/*
* 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 java.util.Set;
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.AuditDisjunction;
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.entities.StrIntTestEntity;
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 MaximalizePropertyQuery extends BaseEnversJPAFunctionalTestCase {
Integer id1;
Integer id2;
Integer id3;
Integer id4;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {StrIntTestEntity.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( "b", 15 );
StrIntTestEntity site3 = new StrIntTestEntity( "c", 42 );
StrIntTestEntity site4 = new StrIntTestEntity( "d", 52 );
em.persist( site1 );
em.persist( site2 );
em.persist( site3 );
em.persist( site4 );
id1 = site1.getId();
id2 = site2.getId();
id3 = site3.getId();
id4 = site4.getId();
em.getTransaction().commit();
// Revision 2
em.getTransaction().begin();
site1 = em.find( StrIntTestEntity.class, id1 );
site2 = em.find( StrIntTestEntity.class, id2 );
site1.setStr1( "d" );
site2.setNumber( 20 );
em.getTransaction().commit();
// Revision 3
em.getTransaction().begin();
site1 = em.find( StrIntTestEntity.class, id1 );
site2 = em.find( StrIntTestEntity.class, id2 );
site1.setNumber( 30 );
site2.setStr1( "z" );
em.getTransaction().commit();
// Revision 4
em.getTransaction().begin();
site1 = em.find( StrIntTestEntity.class, id1 );
site2 = em.find( StrIntTestEntity.class, id2 );
site1.setNumber( 5 );
site2.setStr1( "a" );
em.getTransaction().commit();
// Revision 5
em.getTransaction().begin();
site4 = em.find( StrIntTestEntity.class, id4 );
em.remove( site4 );
em.getTransaction().commit();
}
@Test
public void testMaximizeWithIdEq() {
List revs_id1 = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add(
AuditEntity.property( "number" ).maximize()
.add( AuditEntity.id().eq( id2 ) )
)
.getResultList();
assert Arrays.asList( 2, 3, 4 ).equals( revs_id1 );
}
@Test
public void testMinimizeWithPropertyEq() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add(
AuditEntity.property( "number" ).minimize()
.add( AuditEntity.property( "str1" ).eq( "a" ) )
)
.getResultList();
assert Arrays.asList( 1 ).equals( result );
}
@Test
public void testMaximizeRevision() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.addProjection( AuditEntity.revisionNumber() )
.add(
AuditEntity.revisionNumber().maximize()
.add( AuditEntity.property( "number" ).eq( 10 ) )
)
.getResultList();
assert Arrays.asList( 2 ).equals( result );
}
@Test
@TestForIssue(jiraKey = "HHH-7800")
public void testMaximizeInDisjunction() {
List<Integer> idsToQuery = Arrays.asList( id1, id3 );
AuditDisjunction disjunction = AuditEntity.disjunction();
for ( Integer id : idsToQuery ) {
disjunction.add( AuditEntity.revisionNumber().maximize().add( AuditEntity.id().eq( id ) ) );
}
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, true, true )
.add( disjunction )
.getResultList();
Set<Integer> idsSeen = new HashSet<Integer>();
for ( Object o : result ) {
StrIntTestEntity entity = (StrIntTestEntity) o;
Integer id = entity.getId();
Assert.assertTrue( "Entity with ID " + id + " returned but not queried for.", idsToQuery.contains( id ) );
if ( !idsSeen.add( id ) ) {
Assert.fail( "Multiple revisions returned with ID " + id + "; expected only one." );
}
}
}
@Test
@TestForIssue(jiraKey = "HHH-7827")
public void testAllLatestRevisionsOfEntityType() {
List result = getAuditReader().createQuery()
.forRevisionsOfEntity( StrIntTestEntity.class, false, true )
.add( AuditEntity.revisionNumber().maximize().computeAggregationInInstanceContext() )
.addOrder( AuditEntity.property( "id" ).asc() )
.getResultList();
Assert.assertEquals( 4, result.size() );
Object[] result1 = (Object[]) result.get( 0 );
Object[] result2 = (Object[]) result.get( 1 );
Object[] result3 = (Object[]) result.get( 2 );
Object[] result4 = (Object[]) result.get( 3 );
checkRevisionData( result1, 4, RevisionType.MOD, new StrIntTestEntity( "d", 5, id1 ) );
checkRevisionData( result2, 4, RevisionType.MOD, new StrIntTestEntity( "a", 20, id2 ) );
checkRevisionData( result3, 1, RevisionType.ADD, new StrIntTestEntity( "c", 42, id3 ) );
checkRevisionData( result4, 5, RevisionType.DEL, new StrIntTestEntity( null, null, id4 ) );
}
private void checkRevisionData(Object[] result, int revision, RevisionType type, StrIntTestEntity entity) {
Assert.assertEquals( entity, result[0] );
Assert.assertEquals( revision, ((SequenceIdRevisionEntity) result[1]).getId() );
Assert.assertEquals( type, result[2] );
}
}