/* * 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.components.dynamic; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.hibernate.QueryException; import org.hibernate.Session; import org.hibernate.envers.exception.AuditException; import org.hibernate.envers.query.AuditEntity; import org.hibernate.envers.test.BaseEnversFunctionalTestCase; import org.hibernate.envers.test.Priority; import org.hibernate.testing.TestForIssue; import org.junit.Test; import junit.framework.Assert; import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; /** * @author Lukasz Zuchowski (author at zuchos dot com) * More advanced tests for dynamic component. */ @TestForIssue(jiraKey = "HHH-8049") public class AuditedDynamicComponentsAdvancedCasesTest extends BaseEnversFunctionalTestCase { public static final String PROP_BOOLEAN = "propBoolean"; public static final String PROP_INT = "propInt"; public static final String PROP_FLOAT = "propFloat"; public static final String PROP_MANY_TO_ONE = "propManyToOne"; public static final String PROP_ONE_TO_ONE = "propOneToOne"; public static final String INTERNAL_COMPONENT = "internalComponent"; public static final String INTERNAL_LIST = "internalList"; public static final String INTERNAL_MAP = "internalMap"; public static final String INTERNAL_MAP_WITH_MANY_TO_MANY = "internalMapWithEntities"; public static final String INTERNAL_SET = "internalSet"; public static final String INTERNAL_SET_OF_COMPONENTS = "internalSetOfComponents"; public static final String AGE_USER_TYPE = "ageUserType"; public static final String INTERNAL_LIST_OF_USER_TYPES = "internalListOfUserTypes"; @Override protected String[] getMappings() { return new String[] { "mappings/dynamicComponents/mapAdvanced.hbm.xml" }; } private OneToOneEntity getOneToOneEntity() { return new OneToOneEntity( 1L, "OneToOne" ); } private ManyToManyEntity getManyToManyEntity() { return new ManyToManyEntity( 1L, "ManyToMany" ); } private ManyToOneEntity getManyToOneEntity() { return new ManyToOneEntity( 1L, "ManyToOne" ); } private AdvancedEntity getAdvancedEntity(ManyToOneEntity manyToOne, OneToOneEntity oneToOne, ManyToManyEntity manyToManyEntity) { AdvancedEntity advancedEntity = new AdvancedEntity(); advancedEntity.setId( 1L ); advancedEntity.setNote( "Test note" ); advancedEntity.getDynamicConfiguration().put( PROP_BOOLEAN, true ); advancedEntity.getDynamicConfiguration().put( PROP_INT, 19 ); advancedEntity.getDynamicConfiguration().put( PROP_FLOAT, 15.9f ); advancedEntity.getDynamicConfiguration().put( PROP_MANY_TO_ONE, manyToOne ); advancedEntity.getDynamicConfiguration().put( PROP_ONE_TO_ONE, oneToOne ); advancedEntity.getDynamicConfiguration().put( INTERNAL_COMPONENT, new InternalComponent( "Internal value" ) ); List<String> list = new ArrayList<String>(); list.add( "One" ); list.add( "Two" ); list.add( "Three" ); advancedEntity.getDynamicConfiguration().put( INTERNAL_LIST, list ); Map<String, String> map = new HashMap<String, String>(); map.put( "one", "1" ); map.put( "two", "2" ); advancedEntity.getDynamicConfiguration().put( INTERNAL_MAP, map ); Map<String, ManyToManyEntity> mapWithManyToMany = new HashMap<String, ManyToManyEntity>(); mapWithManyToMany.put( "entity1", manyToManyEntity ); advancedEntity.getDynamicConfiguration().put( INTERNAL_MAP_WITH_MANY_TO_MANY, mapWithManyToMany ); Set<String> set = new HashSet<String>(); set.add( "Une" ); set.add( "Due" ); advancedEntity.getDynamicConfiguration().put( INTERNAL_SET, set ); Set<InternalComponent> componentSet = new HashSet<InternalComponent>(); componentSet.add( new InternalComponent( "Ein" ) ); componentSet.add( new InternalComponent( "Zwei" ) ); advancedEntity.getDynamicConfiguration().put( INTERNAL_SET_OF_COMPONENTS, componentSet ); advancedEntity.getDynamicConfiguration().put( AGE_USER_TYPE, new Age( 18 ) ); List<Age> ages = new ArrayList<Age>(); ages.add( new Age( 1 ) ); ages.add( new Age( 2 ) ); ages.add( new Age( 3 ) ); advancedEntity.getDynamicConfiguration().put( INTERNAL_LIST_OF_USER_TYPES, ages ); return advancedEntity; } @Test @Priority(10) //smoke test to make sure that hibernate & envers are working with the entity&mappings public void shouldInitData() { //given ManyToOneEntity manyToOne = getManyToOneEntity(); OneToOneEntity oneToOne = getOneToOneEntity(); ManyToManyEntity manyToManyEntity = getManyToManyEntity(); AdvancedEntity advancedEntity = getAdvancedEntity( manyToOne, oneToOne, manyToManyEntity ); //rev 1 Session session = openSession(); session.getTransaction().begin(); session.save( manyToOne ); session.save( oneToOne ); session.save( manyToManyEntity ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 2 session.getTransaction().begin(); InternalComponent internalComponent = (InternalComponent) advancedEntity.getDynamicConfiguration() .get( INTERNAL_COMPONENT ); internalComponent.setProperty( "new value" ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 3 session.getTransaction().begin(); List<String> internalList = (List) advancedEntity.getDynamicConfiguration().get( INTERNAL_LIST ); internalList.add( "four" ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 4 session.getTransaction().begin(); Map<String, String> map = (Map) advancedEntity.getDynamicConfiguration().get( INTERNAL_MAP ); map.put( "three", "3" ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 5 session.getTransaction().begin(); Map<String, ManyToManyEntity> mapWithManyToMany = (Map) advancedEntity.getDynamicConfiguration() .get( INTERNAL_MAP_WITH_MANY_TO_MANY ); ManyToManyEntity manyToManyEntity2 = new ManyToManyEntity( 2L, "new value" ); mapWithManyToMany.put( "entity2", manyToManyEntity2 ); session.save( manyToManyEntity2 ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 6 session.getTransaction().begin(); mapWithManyToMany = (Map) advancedEntity.getDynamicConfiguration().get( INTERNAL_MAP_WITH_MANY_TO_MANY ); mapWithManyToMany.clear(); session.save( advancedEntity ); session.getTransaction().commit(); //rev 7 session.getTransaction().begin(); Set<InternalComponent> internalComponentSet = (Set) advancedEntity.getDynamicConfiguration() .get( INTERNAL_SET_OF_COMPONENTS ); internalComponentSet.add( new InternalComponent( "drei" ) ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 8 session.getTransaction().begin(); advancedEntity.getDynamicConfiguration().put( AGE_USER_TYPE, new Age( 19 ) ); session.save( advancedEntity ); session.getTransaction().commit(); //rev 9 session.getTransaction().begin(); List<Age> ages = (List<Age>) advancedEntity.getDynamicConfiguration().get( INTERNAL_LIST_OF_USER_TYPES ); ages.add( new Age( 4 ) ); session.save( advancedEntity ); session.getTransaction().commit(); //rev this, should not create revision session.getTransaction().begin(); session.getTransaction().commit(); //sanity check. Loaded entity should be equal to one that we created. AdvancedEntity advancedEntityActual = (AdvancedEntity) session.load( AdvancedEntity.class, 1L ); Assert.assertEquals( advancedEntity, advancedEntityActual ); } @Test public void shouldMakeRevisions() { Session session = openSession(); session.getTransaction().begin(); //given & when shouldInitData ManyToOneEntity manyToOne = getManyToOneEntity(); OneToOneEntity oneToOne = getOneToOneEntity(); ManyToManyEntity manyToManyEntity = getManyToManyEntity(); AdvancedEntity advancedEntity = getAdvancedEntity( manyToOne, oneToOne, manyToManyEntity ); //then v1 AdvancedEntity ver1 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 1 ); Assert.assertEquals( advancedEntity, ver1 ); //then v2 InternalComponent internalComponent = (InternalComponent) advancedEntity.getDynamicConfiguration() .get( INTERNAL_COMPONENT ); internalComponent.setProperty( "new value" ); AdvancedEntity ver2 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 2 ); Assert.assertEquals( advancedEntity, ver2 ); //then v3 List internalList = (List) advancedEntity.getDynamicConfiguration().get( INTERNAL_LIST ); internalList.add( "four" ); AdvancedEntity ver3 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 3 ); Assert.assertEquals( advancedEntity, ver3 ); //then v4 Map<String, String> map = (Map) advancedEntity.getDynamicConfiguration().get( INTERNAL_MAP ); map.put( "three", "3" ); AdvancedEntity ver4 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 4 ); Assert.assertEquals( advancedEntity, ver4 ); //then v5 Map<String, ManyToManyEntity> mapWithManyToMany = (Map) advancedEntity.getDynamicConfiguration() .get( INTERNAL_MAP_WITH_MANY_TO_MANY ); ManyToManyEntity manyToManyEntity2 = new ManyToManyEntity( 2L, "new value" ); mapWithManyToMany.put( "entity2", manyToManyEntity2 ); AdvancedEntity ver5 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 5 ); Assert.assertEquals( advancedEntity, ver5 ); //then v6 mapWithManyToMany = (Map) advancedEntity.getDynamicConfiguration().get( INTERNAL_MAP_WITH_MANY_TO_MANY ); mapWithManyToMany.clear(); AdvancedEntity ver6 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 6 ); Assert.assertEquals( advancedEntity, ver6 ); //then v7 Set<InternalComponent> internalComponentSet = (Set) advancedEntity.getDynamicConfiguration() .get( INTERNAL_SET_OF_COMPONENTS ); internalComponentSet.add( new InternalComponent( "drei" ) ); AdvancedEntity ver7 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 7 ); Assert.assertEquals( advancedEntity, ver7 ); //then v8 advancedEntity.getDynamicConfiguration().put( AGE_USER_TYPE, new Age( 19 ) ); AdvancedEntity ver8 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 8 ); Assert.assertEquals( advancedEntity, ver8 ); //then v9 List<Age> ages = (List<Age>) advancedEntity.getDynamicConfiguration().get( INTERNAL_LIST_OF_USER_TYPES ); ages.add( new Age( 4 ) ); AdvancedEntity ver9 = getAuditReader().find( AdvancedEntity.class, advancedEntity.getId(), 9 ); Assert.assertEquals( advancedEntity, ver9 ); session.getTransaction().commit(); } @Test public void testOfQueryOnDynamicComponent() { //given (and result of shouldInitData() AdvancedEntity entity = getAdvancedEntity( getManyToOneEntity(), getOneToOneEntity(), getManyToManyEntity() ); //when ManyToOneEntity manyToOneEntity = (ManyToOneEntity) entity.getDynamicConfiguration().get( PROP_MANY_TO_ONE ); List resultList = getAuditReader().createQuery() .forEntitiesAtRevision( AdvancedEntity.class, 1 ) .add( AuditEntity.relatedId( "dynamicConfiguration_" + PROP_MANY_TO_ONE ) .eq( manyToOneEntity.getId() ) ) .getResultList(); //then Assert.assertEquals( entity, resultList.get( 0 ) ); //when InternalComponent internalComponent = (InternalComponent) entity.getDynamicConfiguration().get( INTERNAL_COMPONENT ); resultList = getAuditReader().createQuery() .forEntitiesAtRevision( AdvancedEntity.class, 1 ) .add( AuditEntity.property( "dynamicConfiguration_" + INTERNAL_COMPONENT+"_property") .eq( internalComponent.getProperty() ) ) .getResultList(); //then Assert.assertEquals( entity, resultList.get( 0 ) ); //when try { OneToOneEntity oneToOneEntity = (OneToOneEntity) entity.getDynamicConfiguration().get( PROP_ONE_TO_ONE ); getAuditReader().createQuery() .forEntitiesAtRevision( AdvancedEntity.class, 1 ) .add( AuditEntity.property( "dynamicConfiguration_" + PROP_ONE_TO_ONE ).eq( oneToOneEntity ) ) .getResultList(); //then Assert.fail(); } catch ( Exception e ) { assertTyping( IllegalArgumentException.class, e ); } try { getAuditReader().createQuery() .forEntitiesAtRevision( AdvancedEntity.class, 1 ) .add( AuditEntity.property( "dynamicConfiguration_" + INTERNAL_MAP_WITH_MANY_TO_MANY ) .eq( entity.getDynamicConfiguration().get( INTERNAL_MAP_WITH_MANY_TO_MANY ) ) ) .getResultList(); Assert.fail(); } catch ( Exception e ) { assertTyping( AuditException.class, e ); Assert.assertEquals( "This type of relation (org.hibernate.envers.test.integration.components.dynamic.AdvancedEntity.dynamicConfiguration_internalMapWithEntities) isn't supported and can't be used in queries.", e.getMessage() ); } } @Test public void testRevisionsCounts() { Assert.assertEquals( Arrays.asList( 1, 2, 3, 4, 5, 6, 7, 8, 9 ), getAuditReader().getRevisions( AdvancedEntity.class, 1L ) ); } }