/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.envers.test.integration.query;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import javax.persistence.EntityManager;
import org.hibernate.envers.RevisionType;
import org.hibernate.envers.enhanced.SequenceIdRevisionEntity;
import org.hibernate.envers.query.AuditEntity;
import org.hibernate.envers.query.criteria.MatchMode;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.entities.StrIntTestEntity;
import org.hibernate.envers.test.entities.ids.EmbId;
import org.hibernate.envers.test.entities.ids.EmbIdTestEntity;
import org.hibernate.envers.test.entities.ids.MulId;
import org.hibernate.envers.test.entities.ids.MulIdTestEntity;
import org.hibernate.envers.test.tools.TestTools;
import org.hibernate.testing.TestForIssue;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Adam Warski (adam at warski dot org)
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
*/
@SuppressWarnings({"unchecked"})
public class SimpleQuery extends BaseEnversJPAFunctionalTestCase {
private Integer id1;
private Integer id2;
private Integer id3;
private MulId mulId1;
private EmbId embId1;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { StrIntTestEntity.class, MulIdTestEntity.class, EmbIdTestEntity.class };
}
@Test
@Priority(10)
public void initData() {
// Revision 1
EntityManager em = getEntityManager();
em.getTransaction().begin();
StrIntTestEntity site1 = new StrIntTestEntity( "a", 10 );
StrIntTestEntity site2 = new StrIntTestEntity( "a", 10 );
StrIntTestEntity site3 = new StrIntTestEntity( "b", 5 );
em.persist( site1 );
em.persist( site2 );
em.persist( site3 );
id1 = site1.getId();
id2 = site2.getId();
id3 = site3.getId();
em.getTransaction().commit();
// Revision 2
em.getTransaction().begin();
mulId1 = new MulId( 1, 2 );
em.persist( new MulIdTestEntity( mulId1.getId1(), mulId1.getId2(), "data" ) );
embId1 = new EmbId( 3, 4 );
em.persist( new EmbIdTestEntity( embId1, "something" ) );
site1 = em.find( StrIntTestEntity.class, id1 );
site2 = em.find( StrIntTestEntity.class, id2 );
site1.setStr1( "aBc" );
site2.setNumber( 20 );
em.getTransaction().commit();
// Revision 3
em.getTransaction().begin();
site3 = em.find( StrIntTestEntity.class, id3 );
site3.setStr1( "a" );
em.getTransaction().commit();
// Revision 4
em.getTransaction().begin();
site1 = em.find( StrIntTestEntity.class, id1 );
em.remove( site1 );
em.getTransaction().commit();
}
@Test
public void testEntitiesIdQuery() {
StrIntTestEntity ver2 = (StrIntTestEntity) getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 2 )
.add( AuditEntity.id().eq( id2 ) )
.getSingleResult();
assert ver2.equals( new StrIntTestEntity( "a", 20, id2 ) );
}
@Test
public void testEntitiesPropertyEqualsQuery() {
List ver1 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 1 )
.add( AuditEntity.property( "str1" ).eq( "a" ) )
.getResultList();
List ver2 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 2 )
.add( AuditEntity.property( "str1" ).eq( "a" ) )
.getResultList();
List ver3 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 3 )
.add( AuditEntity.property( "str1" ).eq( "a" ) )
.getResultList();
assert new HashSet( ver1 ).equals(
TestTools.makeSet(
new StrIntTestEntity( "a", 10, id1 ),
new StrIntTestEntity( "a", 10, id2 )
)
);
assert new HashSet( ver2 ).equals( TestTools.makeSet( new StrIntTestEntity( "a", 20, id2 ) ) );
assert new HashSet( ver3 ).equals(
TestTools.makeSet(
new StrIntTestEntity( "a", 20, id2 ),
new StrIntTestEntity( "a", 5, id3 )
)
);
}
@Test
public void testEntitiesPropertyLeQuery() {
List ver1 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 1 )
.add( AuditEntity.property( "number" ).le( 10 ) )
.getResultList();
List ver2 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 2 )
.add( AuditEntity.property( "number" ).le( 10 ) )
.getResultList();
List ver3 = getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 3 )
.add( AuditEntity.property( "number" ).le( 10 ) )
.getResultList();
assert new HashSet( ver1 ).equals(
TestTools.makeSet(
new StrIntTestEntity( "a", 10, id1 ),
new StrIntTestEntity( "a", 10, id2 ), new StrIntTestEntity( "b", 5, id3 )
)
);
assert new HashSet( ver2 ).equals(
TestTools.makeSet(
new StrIntTestEntity( "aBc", 10, id1 ),
new StrIntTestEntity( "b", 5, id3 )
)
);
assert new HashSet( ver3 ).equals(
TestTools.makeSet(
new StrIntTestEntity( "aBc", 10, id1 ),
new StrIntTestEntity( "a", 5, id3 )
)
);
}
@Test
public void testRevisionsPropertyEqQuery() {
List revs_id1 = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add( AuditEntity.property( "str1" ).le( "a" ) )
.add( AuditEntity.id().eq( id1 ) )
.getResultList();
List revs_id2 = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add( AuditEntity.property( "str1" ).le( "a" ) )
.add( AuditEntity.id().eq( id2 ) )
.getResultList();
List revs_id3 = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add( AuditEntity.property( "str1" ).le( "a" ) )
.add( AuditEntity.id().eq( id3 ) )
.getResultList();
assert Arrays.asList( 1 ).equals( revs_id1 );
assert Arrays.asList( 1, 2 ).equals( revs_id2 );
assert Arrays.asList( 3 ).equals( revs_id3 );
}
@Test
public void testSelectEntitiesQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, true, false )
.add( AuditEntity.id().eq( id1 ) )
.getResultList();
assert result.size() == 2;
assert result.get( 0 ).equals( new StrIntTestEntity( "a", 10, id1 ) );
assert result.get( 1 ).equals( new StrIntTestEntity( "aBc", 10, id1 ) );
}
@Test
public void testSelectEntitiesAndRevisionsQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.add( AuditEntity.id().eq( id1 ) )
.getResultList();
assert result.size() == 3;
assert ((Object[]) result.get( 0 ))[0].equals( new StrIntTestEntity( "a", 10, id1 ) );
assert ((Object[]) result.get( 1 ))[0].equals( new StrIntTestEntity( "aBc", 10, id1 ) );
assert ((Object[]) result.get( 2 ))[0].equals( new StrIntTestEntity( null, null, id1 ) );
assert ((SequenceIdRevisionEntity) ((Object[]) result.get( 0 ))[1]).getId() == 1;
assert ((SequenceIdRevisionEntity) ((Object[]) result.get( 1 ))[1]).getId() == 2;
assert ((SequenceIdRevisionEntity) ((Object[]) result.get( 2 ))[1]).getId() == 4;
assert ((Object[]) result.get( 0 ))[2].equals( RevisionType.ADD );
assert ((Object[]) result.get( 1 ))[2].equals( RevisionType.MOD );
assert ((Object[]) result.get( 2 ))[2].equals( RevisionType.DEL );
}
@Test
public void testSelectRevisionTypeQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionType() )
.add( AuditEntity.id().eq( id1 ) )
.getResultList();
assert result.size() == 3;
assert result.get( 0 ).equals( RevisionType.ADD );
assert result.get( 1 ).equals( RevisionType.MOD );
assert result.get( 2 ).equals( RevisionType.DEL );
}
@Test
public void testEmptyRevisionOfEntityQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.getResultList();
assert result.size() == 7;
}
@Test
public void testEmptyConjunctionRevisionOfEntityQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.add( AuditEntity.conjunction() )
.getResultList();
assert result.size() == 7;
}
@Test
public void testEmptyDisjunctionRevisionOfEntityQuery() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.add( AuditEntity.disjunction() )
.getResultList();
assert result.size() == 0;
}
@Test
public void testEntitiesAddedAtRevision() {
StrIntTestEntity site1 = new StrIntTestEntity( "a", 10, id1 );
StrIntTestEntity site2 = new StrIntTestEntity( "a", 10, id2 );
StrIntTestEntity site3 = new StrIntTestEntity( "b", 5, id3 );
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision(
StrIntTestEntity.class,
StrIntTestEntity.class.getName(),
1
).getResultList();
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(
StrIntTestEntity.class,
1
)
.addProjection( AuditEntity.revisionType() ).add( AuditEntity.id().eq( id1 ) )
.getSingleResult();
Assert.assertTrue( TestTools.checkCollection( result, site1, site2, site3 ) );
Assert.assertEquals( revisionType, RevisionType.ADD );
}
@Test
public void testEntitiesChangedAtRevision() {
StrIntTestEntity site1 = new StrIntTestEntity( "aBc", 10, id1 );
StrIntTestEntity site2 = new StrIntTestEntity( "a", 20, id2 );
List result = getAuditReader().createQuery()
.forEntitiesModifiedAtRevision( StrIntTestEntity.class, 2 )
.getResultList();
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(
StrIntTestEntity.class,
2
)
.addProjection( AuditEntity.revisionType() ).add( AuditEntity.id().eq( id1 ) )
.getSingleResult();
Assert.assertTrue( TestTools.checkCollection( result, site1, site2 ) );
Assert.assertEquals( revisionType, RevisionType.MOD );
}
@Test
public void testEntitiesRemovedAtRevision() {
StrIntTestEntity site1 = new StrIntTestEntity( null, null, id1 );
List result = getAuditReader().createQuery()
.forEntitiesModifiedAtRevision( StrIntTestEntity.class, 4 )
.getResultList();
RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision(
StrIntTestEntity.class,
4
)
.addProjection( AuditEntity.revisionType() ).add( AuditEntity.id().eq( id1 ) )
.getSingleResult();
Assert.assertTrue( TestTools.checkCollection( result, site1 ) );
Assert.assertEquals( revisionType, RevisionType.DEL );
}
@Test
public void testEntityNotModifiedAtRevision() {
List result = getAuditReader().createQuery().forEntitiesModifiedAtRevision( StrIntTestEntity.class, 3 )
.add( AuditEntity.id().eq( id1 ) ).getResultList();
Assert.assertTrue( result.isEmpty() );
}
@Test
public void testNoEntitiesModifiedAtRevision() {
List result = getAuditReader().createQuery()
.forEntitiesModifiedAtRevision( StrIntTestEntity.class, 5 )
.getResultList();
Assert.assertTrue( result.isEmpty() );
}
@Test
@TestForIssue(jiraKey = "HHH-7800")
public void testBetweenInsideDisjunction() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, true, true )
.add(
AuditEntity.disjunction()
.add( AuditEntity.property( "number" ).between( 0, 5 ) )
.add( AuditEntity.property( "number" ).between( 20, 100 ) )
)
.getResultList();
for ( Object o : result ) {
StrIntTestEntity entity = (StrIntTestEntity) o;
int number = entity.getNumber();
Assert.assertTrue( (number >= 0 && number <= 5) || (number >= 20 && number <= 100) );
}
}
@Test
@TestForIssue(jiraKey = "HHH-8495")
public void testIlike() {
StrIntTestEntity site1 = new StrIntTestEntity( "aBc", 10, id1 );
StrIntTestEntity result = (StrIntTestEntity) getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, true, true )
.add( AuditEntity.property( "str1" ).ilike( "abc" ) )
.getSingleResult();
Assert.assertEquals( site1, result );
}
@Test
@TestForIssue(jiraKey = "HHH-8495")
public void testIlikeWithMatchMode() {
StrIntTestEntity site1 = new StrIntTestEntity( "aBc", 10, id1 );
StrIntTestEntity result = (StrIntTestEntity) getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, true, true )
.add( AuditEntity.property( "str1" ).ilike( "BC", MatchMode.ANYWHERE ) )
.getSingleResult();
Assert.assertEquals( site1, result );
}
@Test
@TestForIssue(jiraKey = "HHH-8567")
public void testIdPropertyRestriction() {
StrIntTestEntity ver2 = (StrIntTestEntity) getAuditReader().createQuery()
.forEntitiesAtRevision( StrIntTestEntity.class, 2 )
.add( AuditEntity.property( "id" ).eq( id2 ) )
.getSingleResult();
Assert.assertEquals( new StrIntTestEntity( "a", 20, id2 ), ver2 );
}
@Test
@TestForIssue(jiraKey = "HHH-8567")
public void testMultipleIdPropertyRestriction() {
MulIdTestEntity ver2 = (MulIdTestEntity) getAuditReader().createQuery()
.forEntitiesAtRevision( MulIdTestEntity.class, 2 )
.add( AuditEntity.property( "id1" ).eq( mulId1.getId1() ) )
.add( AuditEntity.property( "id2" ).eq( mulId1.getId2() ) )
.getSingleResult();
Assert.assertEquals( new MulIdTestEntity( mulId1.getId1(), mulId1.getId2(), "data" ), ver2 );
}
@Test
@TestForIssue(jiraKey = "HHH-8567")
public void testEmbeddedIdPropertyRestriction() {
EmbIdTestEntity ver2 = (EmbIdTestEntity) getAuditReader().createQuery()
.forEntitiesAtRevision( EmbIdTestEntity.class, 2 )
.add( AuditEntity.property( "id.x" ).eq( embId1.getX() ) )
.add( AuditEntity.property( "id.y" ).eq( embId1.getY() ) )
.getSingleResult();
Assert.assertEquals( new EmbIdTestEntity( embId1, "something" ), ver2 );
}
}