/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * 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.ogm.backendtck.associations.storageconfiguration; import java.lang.annotation.ElementType; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.ogm.backendtck.associations.collection.unidirectional.Cloud; import org.hibernate.ogm.backendtck.associations.collection.unidirectional.SnowFlake; import org.hibernate.ogm.datastore.document.options.AssociationStorageType; import org.hibernate.ogm.utils.GridDialectType; import org.hibernate.ogm.utils.SkipByGridDialect; import org.hibernate.ogm.utils.TestHelper; import org.junit.After; import org.junit.Test; import static org.fest.assertions.Assertions.assertThat; /** * Test for configuring the different association storage modes via annotations. * * @author Gunnar Morling */ @SkipByGridDialect( value = { GridDialectType.HASHMAP, GridDialectType.INFINISPAN, GridDialectType.INFINISPAN_REMOTE, GridDialectType.NEO4J_EMBEDDED, GridDialectType.NEO4J_REMOTE }, comment = "Only the document stores CouchDB and MongoDB support the configuration of specific association storage strategies" ) public class AssociationStorageConfiguredViaAnnotationsTest extends AssociationStorageTestBase { private AnnotatedCloud cloud; private PolarCloud polarCloud; @Test public void associationStorageSetToCollectionOnEntityLevel() throws Exception { setupSessionFactory(); createCloudWithTwoProducedSnowflakes(); assertThat( associationDocumentCount() ).isEqualTo( 0 ); assertThat( inEntityAssociationCount() ).isEqualTo( 1 ); } @Test public void associationStorageSetOnPropertyLevelTakesPrecedenceOverEntityLevel() throws Exception { setupSessionFactory(); createCloudWithTwoProducedAndOneBackupSnowflake(); assertThat( associationDocumentCount() ).isEqualTo( 1 ); assertThat( inEntityAssociationCount() ).isEqualTo( 1 ); } @Test public void associationStorageSetOnPropertyLevelViaApiTakesPrecedenceOverAnnotation() throws Exception { Map<String, Object> settings = new HashMap<String, Object>(); TestHelper.configureOptionsFor( settings, getDocumentDatastoreConfiguration() ) .entity( AnnotatedCloud.class ) .property( "backupSnowFlakes", ElementType.METHOD ) .associationStorage( AssociationStorageType.IN_ENTITY ); sessions = TestHelper.getDefaultTestSessionFactory( settings, AnnotatedCloud.class, Cloud.class, SnowFlake.class ); createCloudWithTwoProducedAndOneBackupSnowflake(); assertThat( associationDocumentCount() ).isEqualTo( 0 ); assertThat( inEntityAssociationCount() ).isEqualTo( 2 ); } @Test public void associationStorageSetOnSubClass() throws Exception { setupSessionFactory(); createPolarCloudWithTwoProducedAndOneBackupSnowflake(); assertThat( associationDocumentCount() ).isEqualTo( 1 ); assertThat( inEntityAssociationCount() ).isEqualTo( 1 ); } private void createCloudWithTwoProducedSnowflakes() { cloud = newCloud() .withLength( 23 ) .withProducedSnowflakes( "Snowflake1", "Snowflake2" ) .createAndSave(); } private void createCloudWithTwoProducedAndOneBackupSnowflake() { cloud = newCloud() .withLength( 23 ) .withProducedSnowflakes( "Snowflake1", "Snowflake2" ) .withBackupSnowflakes( "Snowflake3" ) .createAndSave(); } private void createPolarCloudWithTwoProducedAndOneBackupSnowflake() { polarCloud = newPolarCloud() .withLength( 23 ) .withProducedSnowflakes( "Snowflake1", "Snowflake2" ) .withBackupSnowflakes( "Snowflake3" ) .createAndSave(); } private CloudBuilder<AnnotatedCloud> newCloud() { return new CloudBuilder<AnnotatedCloud>( false ); } private CloudBuilder<PolarCloud> newPolarCloud() { return new CloudBuilder<PolarCloud>( true ); } private class CloudBuilder<T> { private final boolean polar; private int length; private final List<String> producedSnowflakes = new ArrayList<String>(); private final List<String> backupSnowflakes = new ArrayList<String>(); private CloudBuilder(boolean polar) { this.polar = polar; } public CloudBuilder<T> withLength(int length) { this.length = length; return this; } public CloudBuilder<T> withProducedSnowflakes(String... descriptions) { this.producedSnowflakes.addAll( Arrays.asList( descriptions ) ); return this; } public CloudBuilder<T> withBackupSnowflakes(String... descriptions) { this.backupSnowflakes.addAll( Arrays.asList( descriptions ) ); return this; } public T createAndSave() { Session session = sessions.openSession(); Transaction transaction = session.beginTransaction(); Object cloud = null; if ( polar ) { PolarCloud polarCloud = new PolarCloud(); polarCloud.setLength( length ); for ( String description : producedSnowflakes ) { SnowFlake sf = new SnowFlake(); sf.setDescription( description ); session.save( sf ); polarCloud.getProducedSnowFlakes().add( sf ); } for ( String description : backupSnowflakes ) { SnowFlake sf = new SnowFlake(); sf.setDescription( description ); session.save( sf ); polarCloud.getBackupSnowFlakes().add( sf ); } cloud = polarCloud; } else { AnnotatedCloud annotatedCloud = new AnnotatedCloud(); annotatedCloud.setLength( length ); for ( String description : producedSnowflakes ) { SnowFlake sf = new SnowFlake(); sf.setDescription( description ); session.save( sf ); annotatedCloud.getProducedSnowFlakes().add( sf ); } for ( String description : backupSnowflakes ) { SnowFlake sf = new SnowFlake(); sf.setDescription( description ); session.save( sf ); annotatedCloud.getBackupSnowFlakes().add( sf ); } cloud = annotatedCloud; } session.persist( cloud ); transaction.commit(); session.close(); @SuppressWarnings("unchecked") T result = (T) cloud; return result; } } @After public void removeCloudAndSnowflakes() { Session session = sessions.openSession(); Transaction transaction = session.beginTransaction(); if ( cloud != null ) { AnnotatedCloud cloudToDelete = (AnnotatedCloud) session.get( AnnotatedCloud.class, cloud.getId() ); for ( SnowFlake current : cloudToDelete.getProducedSnowFlakes() ) { session.delete( current ); } for ( SnowFlake current : cloudToDelete.getBackupSnowFlakes() ) { session.delete( current ); } session.delete( cloudToDelete ); } if ( polarCloud != null ) { PolarCloud cloudToDelete = (PolarCloud) session.get( PolarCloud.class, polarCloud.getId() ); for ( SnowFlake current : cloudToDelete.getProducedSnowFlakes() ) { session.delete( current ); } for ( SnowFlake current : cloudToDelete.getBackupSnowFlakes() ) { session.delete( current ); } session.delete( cloudToDelete ); } transaction.commit(); session.close(); assertThat( TestHelper.getNumberOfEntities( sessions ) ).isEqualTo( 0 ); assertThat( TestHelper.getNumberOfAssociations( sessions ) ).isEqualTo( 0 ); sessions.close(); } private void setupSessionFactory() { sessions = TestHelper.getDefaultTestSessionFactory( AnnotatedCloud.class, PolarCloud.class, SnowFlake.class ); } }