From e40777261e28b22d728b8824eef560304d2ba0cd Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Sun, 10 May 2015 14:53:58 +0100 Subject: [PATCH] OGM-783 Update test related to embeddedable associations Change the test to work with a multi-path game scenario and update the queries for the existing tests. --- .../ogm/backendtck/queries/AnEmbeddable.java | 70 ------ .../queries/EmbeddedCollectionItem.java | 62 ----- .../{AnotherEmbeddable.java => Ending.java} | 30 +-- .../queries/OptionalStoryBranch.java | 73 ++++++ .../QueriesWithEmbeddedCollectionTest.java | 111 +++++---- .../queries/QueriesWithEmbeddedTest.java | 137 ++++------- .../ogm/backendtck/queries/StoryBranch.java | 70 ++++++ .../ogm/backendtck/queries/StoryGame.java | 91 ++++++++ .../ogm/backendtck/queries/WithEmbedded.java | 85 ------- .../embeddable/EmbeddableMappingTest.java | 68 +++--- .../EntityWithObjectIdAndEmbeddable.java | 10 +- .../objectid/ObjectIdWithEmbeddableTest.java | 20 +- .../mapping/ElementCollectionMappingTest.java | 219 +++++++++++------- .../datastore/neo4j/test/mapping/MapTest.java | 107 ++++----- .../neo4j/test/mapping/Neo4jJpaTestCase.java | 28 ++- 15 files changed, 602 insertions(+), 579 deletions(-) delete mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/AnEmbeddable.java delete mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/EmbeddedCollectionItem.java rename core/src/test/java/org/hibernate/ogm/backendtck/queries/{AnotherEmbeddable.java => Ending.java} (55%) create mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/OptionalStoryBranch.java create mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryBranch.java create mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryGame.java delete mode 100644 core/src/test/java/org/hibernate/ogm/backendtck/queries/WithEmbedded.java diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/AnEmbeddable.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/AnEmbeddable.java deleted file mode 100644 index d7303e966c..0000000000 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/AnEmbeddable.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.ogm.backendtck.queries; - -import java.util.List; - -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; - -import org.hibernate.search.annotations.Analyze; -import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.IndexedEmbedded; -import org.hibernate.search.annotations.Store; - -@Embeddable -public class AnEmbeddable { - // Store.YES for filtering in query - // Analyze.NO for projection in query - @Field(store = Store.YES, analyze = Analyze.NO) - private String embeddedString; - - @Embedded - @IndexedEmbedded - private AnotherEmbeddable anotherEmbeddable; - - @ElementCollection - @IndexedEmbedded - private List anotherCollection; - - public AnEmbeddable() { - } - - public AnEmbeddable(String embeddedString) { - this.embeddedString = embeddedString; - } - - public AnEmbeddable(String embeddedString, AnotherEmbeddable anotherEmbeddable) { - this.embeddedString = embeddedString; - this.anotherEmbeddable = anotherEmbeddable; - } - - public String getEmbeddedString() { - return embeddedString; - } - - public void setEmbeddedString(String embeddedString) { - this.embeddedString = embeddedString; - } - - public AnotherEmbeddable getAnotherEmbeddable() { - return anotherEmbeddable; - } - - public void setAnotherEmbeddable(AnotherEmbeddable anotherEmbeddable) { - this.anotherEmbeddable = anotherEmbeddable; - } - - public List getAnotherCollection() { - return anotherCollection; - } - - public void setAnotherCollection(List anotherCollection) { - this.anotherCollection = anotherCollection; - } -} diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/EmbeddedCollectionItem.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/EmbeddedCollectionItem.java deleted file mode 100644 index 2009811849..0000000000 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/EmbeddedCollectionItem.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.ogm.backendtck.queries; - -import javax.persistence.Embeddable; - -import org.hibernate.search.annotations.Analyze; -import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.IndexedEmbedded; -import org.hibernate.search.annotations.Store; - -@Embeddable -public class EmbeddedCollectionItem { - - // Store.YES for filtering in query - // Analyze.NO for projection in query - @Field(store = Store.YES, analyze = Analyze.NO) - private String item; - - @Field(store = Store.YES, analyze = Analyze.NO) - private String anotherItem; - - @IndexedEmbedded - private AnotherEmbeddable embedded; - - public EmbeddedCollectionItem() { - } - - public EmbeddedCollectionItem(String embeddedString, String anotherItem, AnotherEmbeddable anotherEmbeddable) { - this.item = embeddedString; - this.anotherItem = anotherItem; - this.embedded = anotherEmbeddable; - } - - public String getItem() { - return item; - } - - public void setItem(String embeddedString) { - this.item = embeddedString; - } - - public AnotherEmbeddable getEmbedded() { - return embedded; - } - - public void setEmbedded(AnotherEmbeddable anotherEmbeddable) { - this.embedded = anotherEmbeddable; - } - - public String getAnotherItem() { - return anotherItem; - } - - public void setAnotherItem(String anotherItem) { - this.anotherItem = anotherItem; - } -} diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/AnotherEmbeddable.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/Ending.java similarity index 55% rename from core/src/test/java/org/hibernate/ogm/backendtck/queries/AnotherEmbeddable.java rename to core/src/test/java/org/hibernate/ogm/backendtck/queries/Ending.java index c44f2713dc..fde95b28b8 100644 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/AnotherEmbeddable.java +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/Ending.java @@ -13,39 +13,39 @@ import org.hibernate.search.annotations.Store; @Embeddable -public class AnotherEmbeddable { +public class Ending { // Store.YES for filtering in query // Analyze.NO for projection in query @Field(store = Store.YES, analyze = Analyze.NO) - private String embeddedString; + private String text; // Store.YES for filtering in query // Analyze.NO for projection in query @Field(store = Store.YES, analyze = Analyze.NO) - private Integer embeddedInteger; + private Integer score; - public AnotherEmbeddable() { + public Ending() { } - public AnotherEmbeddable(String embeddedString, Integer embeddedInteger) { - this.embeddedString = embeddedString; - this.embeddedInteger = embeddedInteger; + public Ending(String text, Integer score) { + this.text = text; + this.score = score; } - public String getEmbeddedString() { - return embeddedString; + public String getText() { + return text; } - public void setEmbeddedString(String embeddedString) { - this.embeddedString = embeddedString; + public void setText(String text) { + this.text = text; } - public Integer getEmbeddedInteger() { - return embeddedInteger; + public Integer getScore() { + return score; } - public void setEmbeddedInteger(Integer embeddedInteger) { - this.embeddedInteger = embeddedInteger; + public void setScore(Integer score) { + this.score = score; } } diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/OptionalStoryBranch.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/OptionalStoryBranch.java new file mode 100644 index 0000000000..d6d41438e9 --- /dev/null +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/OptionalStoryBranch.java @@ -0,0 +1,73 @@ +/* + * 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 . + */ +package org.hibernate.ogm.backendtck.queries; + +import javax.persistence.Embeddable; + +import org.hibernate.search.annotations.Analyze; +import org.hibernate.search.annotations.Field; +import org.hibernate.search.annotations.IndexedEmbedded; +import org.hibernate.search.annotations.Store; + +@Embeddable +public class OptionalStoryBranch { + + // Store.YES for filtering in query + // Analyze.NO for projection in query + @Field(store = Store.YES, analyze = Analyze.NO) + private String evilText; + + @Field(store = Store.YES, analyze = Analyze.NO) + private String goodText; + + @IndexedEmbedded + private Ending evilEnding; + + @IndexedEmbedded + private Ending goodEnding; + + public OptionalStoryBranch() { + } + + public OptionalStoryBranch(String evilText, String goodText, Ending evilEnding) { + this.evilText = evilText; + this.goodText = goodText; + this.evilEnding = evilEnding; + } + + public String getEvilText() { + return evilText; + } + + public void setEvilText(String embeddedString) { + this.evilText = embeddedString; + } + + public Ending getEvilEnding() { + return evilEnding; + } + + public void setEvilEnding(Ending anotherEmbeddable) { + this.evilEnding = anotherEmbeddable; + } + + public String getGoodText() { + return goodText; + } + + public void setGoodText(String anotherItem) { + this.goodText = anotherItem; + } + + public Ending getGoodEnding() { + return goodEnding; + } + + public void setGoodEnding(Ending goodEnding) { + this.goodEnding = goodEnding; + } +} diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java index bbb32bf4e5..1369d01da5 100644 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedCollectionTest.java @@ -7,6 +7,8 @@ package org.hibernate.ogm.backendtck.queries; import static org.hibernate.ogm.utils.OgmAssertions.assertThat; +import static org.hibernate.ogm.utils.SessionHelper.delete; +import static org.hibernate.ogm.utils.SessionHelper.persist; import java.util.Arrays; import java.util.List; @@ -68,146 +70,139 @@ public void closeSession() { @Test public void testEqualOpeartorWithEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item = 'item[0]'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText = 'search the evil [artifact]'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testInOperatorWithEmbeddedCollection() throws Exception { - List result = session.createQuery( "from WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item IN ( 'item[0]' )" ).list(); + List result = session.createQuery( "from StoryGame story JOIN story.chaoticBranches c WHERE c.evilText IN ( 'search the evil [artifact]' )" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testBetweenOpeartorWithEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item BETWEEN 'aaaaaa' AND 'zzzzzzzzz'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText BETWEEN 'aaaaaa' AND 'zzzzzzzzz'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testLikeOpeartorWithEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item LIKE 'item[1%'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText LIKE 'search the%'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testEqualEmbeddedCollectionWithEmbeddableInCollectionWhereClause() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item = 'item[1]'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText = 'assassinate the leader of the party'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testConjunctionOperatorWithEmbeddedInEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item = 'item[1]' AND c.anotherItem IN ('secondItem[0]')" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText = 'search the evil [artifact]' AND c.goodText IN ('you punish the bandits')" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testBetweenOperatorWithEmbeddedInEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.embedded.embeddedInteger BETWEEN -100 AND 100" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilEnding.score BETWEEN -100 AND 100" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testLikeOperatorWithEmbeddedInEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.embedded.embeddedString LIKE 'string[1%'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilEnding.text LIKE 'you bec%'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testEqualOperatorWithEmbeddedInEmbeddedCollectionForString() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.embedded.embeddedString = 'string[1][0]'" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilEnding.text = 'you become a demon'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testEqualOperatorWithEmbeddedInEmbeddedCollectionForInteger() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.embedded.embeddedInteger = 10" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilEnding.score = 10" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testConjunctionOperatorEqualOperatorWithEmbeddedInEmbeddedCollection() throws Exception { - List result = session.createQuery( "FROM WithEmbedded e JOIN e.anEmbeddedCollection c WHERE c.item = 'item[1]' AND c.embedded.embeddedString IN ('string[1][0]')" ).list(); + List result = session.createQuery( "FROM StoryGame story JOIN story.chaoticBranches c WHERE c.evilText = 'assassinate the leader of the party' AND c.evilEnding.text IN ('you become a demon')" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testQueryReturningEmbeddedObject() { @SuppressWarnings("unchecked") - List list = session.createQuery( "from WithEmbedded we" ).list(); + List list = session.createQuery( "FROM StoryGame story WHERE story.id = 1" ).list(); assertThat( list ) - .onProperty( "anEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "embedded 1" ); + .onProperty( "goodBranch" ) + .onProperty( "storyText" ) + .containsExactly( "you go to the village" ); assertThat( list ) - .onProperty( "anEmbeddable" ) - .onProperty( "anotherEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "string 1" ); + .onProperty( "goodBranch" ) + .onProperty( "ending" ) + .onProperty( "text" ) + .containsExactly( "village ending - everybody is happy" ); assertThat( list ) - .onProperty( "yetAnotherEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "embedded 2" ); + .onProperty( "evilBranch" ) + .onProperty( "storyText" ) + .containsExactly( "you kill the villagers" ); - assertThat( list.get( 0 ).getAnEmbeddedCollection() ) - .onProperty( "item" ) - .containsOnly( "item[0]", "item[1]" ); + assertThat( list.get( 0 ).getChaoticBranches() ) + .onProperty( "evilText" ) + .containsOnly( "search the evil [artifact]", "assassinate the leader of the party" ); - assertThat( list.get( 0 ).getAnEmbeddedCollection() ) - .onProperty( "anotherItem" ) - .containsOnly( "secondItem[0]", null ); + assertThat( list.get( 0 ).getChaoticBranches() ) + .onProperty( "goodText" ) + .containsOnly( "you punish the bandits", null ); - assertThat( list.get( 0 ).getAnotherEmbeddedCollection() ) - .onProperty( "item" ) - .containsOnly( "another[0]", "another[1]" ); + assertThat( list.get( 0 ).getNeutralBranches() ) + .onProperty( "evilText" ) + .containsOnly( "steal the [artifact]", "kill the king" ); - assertThat( list.get( 0 ).getAnotherEmbeddedCollection() ) - .onProperty( "anotherItem" ) + assertThat( list.get( 0 ).getNeutralBranches() ) + .onProperty( "goodText" ) .containsOnly( null, null ); } @BeforeClass public static void insertTestEntities() throws Exception { - WithEmbedded with = new WithEmbedded( 1L, null ); - with.setAnEmbeddable( new AnEmbeddable( "embedded 1", new AnotherEmbeddable( "string 1", 1 ) ) ); - with.setYetAnotherEmbeddable( new AnEmbeddable( "embedded 2" ) ); - with.setAnEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "item[0]", "secondItem[0]", null ), new EmbeddedCollectionItem( "item[1]", null, new AnotherEmbeddable( "string[1][0]", 10 ) ) ) ); - with.setAnotherEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "another[0]", null, null ), new EmbeddedCollectionItem( "another[1]", null, null ) ) ); - - persist( with ); - } + StoryGame story1 = new StoryGame( 1L, null ); + story1.setGoodBranch( new StoryBranch( "you go to the village", new Ending( "village ending - everybody is happy", 1 ) ) ); + story1.setEvilBranch( new StoryBranch( "you kill the villagers" ) ); + story1.setChaoticBranches( Arrays.asList( + new OptionalStoryBranch( "search the evil [artifact]", "you punish the bandits", null ), + new OptionalStoryBranch( "assassinate the leader of the party", null, new Ending( "you become a demon", 10 ) ) ) ); + story1.setNeutralBranches( Arrays.asList( + new OptionalStoryBranch( "steal the [artifact]", null, null ), + new OptionalStoryBranch( "kill the king", null, null ) ) ); - @AfterClass - public static void removeTestEntities() throws Exception { - final Session session = sessions.openSession(); - Transaction transaction = session.beginTransaction(); + StoryGame story2 = new StoryGame( 20L, new StoryBranch( "you go the [cave]", new Ending( "[cave] ending - it's dark", 20 ) ) ); + story2.setEvilBranch( new StoryBranch( "you are now a vampire", null ) ); - session.delete( session.load( WithEmbedded.class, 1L ) ); + StoryGame story3 = new StoryGame( 300L, new StoryBranch( "you go to the [dungeon]", new Ending( "[dungeon] ending - you loot the treasures", 300 ) ) ); + story3.setEvilBranch( new StoryBranch( "evil branch - you become the [dungeon] keeper", null ) ); - transaction.commit(); - session.close(); + persist( sessions, story1, story2, story3); } - private static void persist(Object... entities) { - final Session session = sessions.openSession(); - Transaction transaction = session.beginTransaction(); - for ( Object entity : entities ) { - session.persist( entity ); - } - - transaction.commit(); - session.close(); + @AfterClass + public static void removeTestEntities() throws Exception { + delete( sessions, StoryGame.class, 1L, 20L, 300L ); } @Override protected Class[] getAnnotatedClasses() { - return new Class[] { WithEmbedded.class }; + return new Class[] { StoryGame.class }; } } diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedTest.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedTest.java index 745a48fd43..1e568d41b9 100644 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedTest.java +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/QueriesWithEmbeddedTest.java @@ -7,9 +7,9 @@ package org.hibernate.ogm.backendtck.queries; import static org.hibernate.ogm.utils.OgmAssertions.assertThat; +import static org.hibernate.ogm.utils.SessionHelper.asProjectionResults; +import static org.hibernate.ogm.utils.SessionHelper.persist; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.hibernate.Session; @@ -18,6 +18,7 @@ import org.hibernate.ogm.utils.GridDialectType; import org.hibernate.ogm.utils.OgmTestCase; import org.hibernate.ogm.utils.SkipByGridDialect; +import org.hibernate.ogm.utils.SessionHelper.ProjectionResult; import org.hibernate.ogm.utils.TestSessionFactory; import org.junit.After; import org.junit.Before; @@ -33,7 +34,7 @@ */ @SkipByGridDialect( value = { GridDialectType.CASSANDRA }, - comment = "WithEmbedded list fields - bag semantics unsupported (no primary key)" + comment = "Collection of embeddeds - bag semantics unsupported (no primary key)" ) public class QueriesWithEmbeddedTest extends OgmTestCase { @@ -68,148 +69,92 @@ public void closeSession() { @Test public void testQueryWithEmbeddableInWhereClause() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.anEmbeddable.embeddedString = 'string 1'" ).list(); + List result = session.createQuery( "from StoryGame e where e.goodBranch.storyText = 'you go to the [village]'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testQueryWithInOperator() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.anEmbeddable.embeddedString IN ( 'string 1' )" ).list(); + List result = session.createQuery( "from StoryGame e where e.goodBranch.storyText IN ( 'you go to the [village]' )" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test - public void testQueryWithBetweenOperator() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.anEmbeddable.anotherEmbeddable.embeddedInteger BETWEEN 1 AND 6" ).list(); + public void testQueryWithBetstoryenOperator() throws Exception { + List result = session.createQuery( "from StoryGame e where e.goodBranch.ending.score BETWEEN 1 AND 6" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testQueryWithLikeOperator() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.anEmbeddable.anotherEmbeddable.embeddedString LIKE 'stri%'" ).list(); - assertThat( result ).onProperty( "id" ).containsOnly( 1L ); + List result = session.createQuery( "from StoryGame e where e.goodBranch.ending.text LIKE '[dungeon] end%'" ).list(); + assertThat( result ).onProperty( "id" ).containsOnly( 300L ); } @Test public void testQueryWithNestedEmbeddableInWhereClause() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.anEmbeddable.anotherEmbeddable.embeddedString = 'string 2'" ).list(); + List result = session.createQuery( "from StoryGame e where e.goodBranch.ending.text = '[village] ending - everybody is happy'" ).list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } @Test public void testQueryWithComparisonOnMultipleProperties() throws Exception { - List result = session.createQuery( "from WithEmbedded e where e.yetAnotherEmbeddable.embeddedString = 'string 3' AND e.anEmbeddable.anotherEmbeddable.embeddedString = 'string 2'" ).list(); + List result = session + .createQuery( "from StoryGame e where e.evilBranch.storyText = 'evil branch - you kill everybody' AND e.goodBranch.ending.text = '[village] ending - everybody is happy'" ) + .list(); assertThat( result ).onProperty( "id" ).containsOnly( 1L ); } + @Test + public void testQueryWithEmbeddablePropertyInSelectClauseWithOneResult() throws Exception { + List result = asProjectionResults( session, "select e.id, e.goodBranch.storyText from StoryGame e where e.id = 1" ); + assertThat( result ).containsOnly( new ProjectionResult( 1L, "you go to the [village]" ) ); + } + @Test public void testQueryWithEmbeddablePropertyInSelectClause() throws Exception { - List result = asProjectionResults( "select e.id, e.anEmbeddable.embeddedString from WithEmbedded e" ); - assertThat( result ).containsOnly( new ProjectionResult( 1L, "string 1" ) ); + List result = asProjectionResults( session, "select e.id, e.evilBranch.storyText from StoryGame e" ); + assertThat( result ).containsOnly( new ProjectionResult( 1L, "evil branch - you kill everybody" ), new ProjectionResult( 20L, null ), new ProjectionResult( 300L, "evil branch - you become the [dungeon] keeper" ) ); } @Test public void testQueryReturningEmbeddedObject() { - List list = session.createQuery( "from WithEmbedded we" ).list(); + List list = session.createQuery( "FROM StoryGame story WHERE story.id = 1" ).list(); assertThat( list ) - .onProperty( "anEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "string 1" ); + .onProperty( "goodBranch" ) + .onProperty( "storyText" ) + .containsExactly( "you go to the [village]" ); assertThat( list ) - .onProperty( "anEmbeddable" ) - .onProperty( "anotherEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "string 2" ); + .onProperty( "goodBranch" ) + .onProperty( "ending" ) + .onProperty( "text" ) + .containsExactly( "[village] ending - everybody is happy" ); assertThat( list ) - .onProperty( "yetAnotherEmbeddable" ) - .onProperty( "embeddedString" ) - .containsExactly( "string 3" ); + .onProperty( "evilBranch" ) + .onProperty( "storyText" ) + .containsExactly( "evil branch - you kill everybody" ); } @BeforeClass public static void insertTestEntities() throws Exception { - WithEmbedded with = new WithEmbedded( 1L, new AnEmbeddable( "string 1", new AnotherEmbeddable( "string 2", 2 ) ) ); - with.setYetAnotherEmbeddable( new AnEmbeddable( "string 3", null ) ); - persist( with ); - } - - private static void persist(Object... entities) { - final Session session = sessions.openSession(); - Transaction transaction = session.beginTransaction(); + StoryGame story1 = new StoryGame( 1L, new StoryBranch( "you go to the [village]", new Ending( "[village] ending - everybody is happy", 1 ) ) ); + story1.setEvilBranch( new StoryBranch( "evil branch - you kill everybody", null ) ); - for ( Object entity : entities ) { - session.persist( entity ); - } - - transaction.commit(); - session.close(); - } + StoryGame story2 = new StoryGame( 20L, new StoryBranch( "you go the cave", new Ending( "cave ending - it's dark", 20 ) ) ); + story2.setEvilBranch( new StoryBranch( null, null ) ); - private List asProjectionResults(String projectionQuery) { - List results = session.createQuery( projectionQuery ).list(); - List projectionResults = new ArrayList(); + StoryGame story3 = new StoryGame( 300L, new StoryBranch( "you go to the [dungeon]", new Ending( "[dungeon] ending - you loot the treasures", 300 ) ) ); + story3.setEvilBranch( new StoryBranch( "evil branch - you become the [dungeon] keeper", null ) ); - for ( Object result : results ) { - if ( !( result instanceof Object[] ) ) { - throw new IllegalArgumentException( "No projection result: " + result ); - } - projectionResults.add( ProjectionResult.forArray( (Object[]) result ) ); - } - - return projectionResults; - } + persist( sessions, story1, story2, story3 ); - private static class ProjectionResult { - - private Object[] elements; - - public ProjectionResult(Object... elements) { - this.elements = elements; - } - - public static ProjectionResult forArray(Object[] element) { - ProjectionResult result = new ProjectionResult(); - result.elements = element; - return result; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode( elements ); - return result; - } - - @Override - public boolean equals(Object obj) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - ProjectionResult other = (ProjectionResult) obj; - if ( !Arrays.equals( elements, other.elements ) ) { - return false; - } - return true; - } - - @Override - public String toString() { - return Arrays.deepToString( elements ); - } } @Override protected Class[] getAnnotatedClasses() { - return new Class[] { WithEmbedded.class }; + return new Class[] { StoryGame.class }; } } diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryBranch.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryBranch.java new file mode 100644 index 0000000000..994e08e5ec --- /dev/null +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryBranch.java @@ -0,0 +1,70 @@ +/* + * 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 . + */ +package org.hibernate.ogm.backendtck.queries; + +import java.util.List; + +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; + +import org.hibernate.search.annotations.Analyze; +import org.hibernate.search.annotations.Field; +import org.hibernate.search.annotations.IndexedEmbedded; +import org.hibernate.search.annotations.Store; + +@Embeddable +public class StoryBranch { + // Store.YES for filtering in query + // Analyze.NO for projection in query + @Field(store = Store.YES, analyze = Analyze.NO) + private String storyText; + + @Embedded + @IndexedEmbedded + private Ending ending; + + @ElementCollection + @IndexedEmbedded + private List additionalEndings; + + public StoryBranch() { + } + + public StoryBranch(String embeddedString) { + this.storyText = embeddedString; + } + + public StoryBranch(String storyText, Ending endBranch) { + this.storyText = storyText; + this.ending = endBranch; + } + + public String getStoryText() { + return storyText; + } + + public void setStoryText(String storyText) { + this.storyText = storyText; + } + + public Ending getEnding() { + return ending; + } + + public void setEnding(Ending anotherEmbeddable) { + this.ending = anotherEmbeddable; + } + + public List getAdditionalEndings() { + return additionalEndings; + } + + public void setAdditionalEndings(List anotherCollection) { + this.additionalEndings = anotherCollection; + } +} diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryGame.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryGame.java new file mode 100644 index 0000000000..d67c1da37c --- /dev/null +++ b/core/src/test/java/org/hibernate/ogm/backendtck/queries/StoryGame.java @@ -0,0 +1,91 @@ +/* + * 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 . + */ +package org.hibernate.ogm.backendtck.queries; + +import java.util.List; + +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.search.annotations.Indexed; +import org.hibernate.search.annotations.IndexedEmbedded; + +/** + * Simulate a multi-path story game. + * It can be used to test embeddable elements and collections. + * + * @author Davide D'Alto + */ +@Indexed +@Entity +public class StoryGame { + + @Id + private Long id; + + @Embedded + @IndexedEmbedded + private StoryBranch goodBranch; + + @Embedded + @IndexedEmbedded + private StoryBranch evilBranch; + + @ElementCollection + @IndexedEmbedded + private List chaoticBranches; + + @ElementCollection + @IndexedEmbedded + private List neutralBranches; + + public StoryGame() { + } + + public StoryGame(Long id, StoryBranch goodBranch) { + this.id = id; + this.goodBranch = goodBranch; + } + + public Long getId() { + return id; + } + + public void setGoodBranch(StoryBranch goodBranch) { + this.goodBranch = goodBranch; + } + + public StoryBranch getGoodBranch() { + return goodBranch; + } + + public StoryBranch getEvilBranch() { + return evilBranch; + } + + public void setEvilBranch(StoryBranch evilBranch) { + this.evilBranch = evilBranch; + } + + public List getChaoticBranches() { + return chaoticBranches; + } + + public void setChaoticBranches(List chaoticBranchhes) { + this.chaoticBranches = chaoticBranchhes; + } + + public List getNeutralBranches() { + return neutralBranches; + } + + public void setNeutralBranches(List neutralBranches) { + this.neutralBranches = neutralBranches; + } +} diff --git a/core/src/test/java/org/hibernate/ogm/backendtck/queries/WithEmbedded.java b/core/src/test/java/org/hibernate/ogm/backendtck/queries/WithEmbedded.java deleted file mode 100644 index e711040fdb..0000000000 --- a/core/src/test/java/org/hibernate/ogm/backendtck/queries/WithEmbedded.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.ogm.backendtck.queries; - -import java.util.List; - -import javax.persistence.ElementCollection; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.Id; - -import org.hibernate.search.annotations.Indexed; -import org.hibernate.search.annotations.IndexedEmbedded; - -@Indexed -@Entity -public class WithEmbedded { - - @Id - private Long id; - - @Embedded - @IndexedEmbedded - private AnEmbeddable anEmbeddable; - - @Embedded - @IndexedEmbedded - private AnEmbeddable yetAnotherEmbeddable; - - @ElementCollection - @IndexedEmbedded - private List anEmbeddedCollection; - - @ElementCollection - @IndexedEmbedded - private List anotherEmbeddedCollection; - - public WithEmbedded() { - } - - public WithEmbedded(Long id, AnEmbeddable anEmbeddable) { - this.id = id; - this.anEmbeddable = anEmbeddable; - } - - public Long getId() { - return id; - } - - public void setAnEmbeddable(AnEmbeddable anEmbeddable) { - this.anEmbeddable = anEmbeddable; - } - - public AnEmbeddable getAnEmbeddable() { - return anEmbeddable; - } - - public AnEmbeddable getYetAnotherEmbeddable() { - return yetAnotherEmbeddable; - } - - public void setYetAnotherEmbeddable(AnEmbeddable yetAnotherEmbeddable) { - this.yetAnotherEmbeddable = yetAnotherEmbeddable; - } - - public List getAnEmbeddedCollection() { - return anEmbeddedCollection; - } - - public void setAnEmbeddedCollection(List anEmbeddedCollection) { - this.anEmbeddedCollection = anEmbeddedCollection; - } - - public List getAnotherEmbeddedCollection() { - return anotherEmbeddedCollection; - } - - public void setAnotherEmbeddedCollection(List anotherEmbeddedCollection) { - this.anotherEmbeddedCollection = anotherEmbeddedCollection; - } -} diff --git a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/embeddable/EmbeddableMappingTest.java b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/embeddable/EmbeddableMappingTest.java index 40c6173698..84bfed1fc4 100644 --- a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/embeddable/EmbeddableMappingTest.java +++ b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/embeddable/EmbeddableMappingTest.java @@ -15,10 +15,10 @@ import org.hibernate.ogm.backendtck.embeddable.Account; import org.hibernate.ogm.backendtck.embeddable.Address; import org.hibernate.ogm.backendtck.embeddable.AddressType; -import org.hibernate.ogm.backendtck.queries.AnEmbeddable; -import org.hibernate.ogm.backendtck.queries.AnotherEmbeddable; -import org.hibernate.ogm.backendtck.queries.EmbeddedCollectionItem; -import org.hibernate.ogm.backendtck.queries.WithEmbedded; +import org.hibernate.ogm.backendtck.queries.StoryBranch; +import org.hibernate.ogm.backendtck.queries.Ending; +import org.hibernate.ogm.backendtck.queries.OptionalStoryBranch; +import org.hibernate.ogm.backendtck.queries.StoryGame; import org.hibernate.ogm.utils.OgmTestCase; import org.junit.Test; @@ -205,13 +205,17 @@ public void testEmbeddableCollection() throws Exception { // Given, When // If the value is not big enough, it gets converted as integer Long id = Long.MAX_VALUE; - WithEmbedded with = new WithEmbedded( id, null ); - with.setAnEmbeddable( new AnEmbeddable( "embedded 1", new AnotherEmbeddable( "string 1", 1 ) ) ); - with.setYetAnotherEmbeddable( new AnEmbeddable( "embedded 2" ) ); - with.setAnEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "item[0]", "secondItem[0]", null ), new EmbeddedCollectionItem( "item[1]", null, new AnotherEmbeddable( "string[1][0]", 10 ) ) ) ); - with.setAnotherEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "another[0]", null, null ), new EmbeddedCollectionItem( "another[1]", null, null ) ) ); - - session.persist( with ); + StoryGame story = new StoryGame( id, null ); + story.setGoodBranch( new StoryBranch( "you go to the village", new Ending( "village ending - everybody is happy", 1 ) ) ); + story.setEvilBranch( new StoryBranch( "you kill the villagers" ) ); + story.setChaoticBranches( Arrays.asList( + new OptionalStoryBranch( "search the evil [artifact]", "you punish the bandits", null ), + new OptionalStoryBranch( "assassinate the leader of the party", null, new Ending( "you become a demon", 10 ) ) ) ); + story.setNeutralBranches( Arrays.asList( + new OptionalStoryBranch( "steal the [artifact]", null, null ), + new OptionalStoryBranch( "kill the king", null, null ) ) ); + + session.persist( story ); transaction.commit(); session.clear(); transaction = session.beginTransaction(); @@ -219,43 +223,43 @@ public void testEmbeddableCollection() throws Exception { // Then assertDbObject( session.getSessionFactory(), // collection - WithEmbedded.class.getSimpleName(), + StoryGame.class.getSimpleName(), // query "{ '_id' : " + id + " }", // expected "{" + "'_id' : " + id + "," + - "'anEmbeddable' : {" + - "'anotherEmbeddable' : {" + - "'embeddedInteger' : 1," + - "'embeddedString' : 'string 1'" + + "'goodBranch' : {" + + "'ending' : {" + + "'score' : 1," + + "'text' : 'village ending - everybody is happy'" + "}," + - "'embeddedString' : 'embedded 1'" + + "'storyText' : 'you go to the village'" + "}," + - "'yetAnotherEmbeddable' : {" + - "'embeddedString' : 'embedded 2'" + + "'evilBranch' : {" + + "'storyText' : 'you kill the villagers'" + "}," + - "'anEmbeddedCollection' : [" + + "'chaoticBranches' : [" + "{" + - "'item' : 'item[1]'," + - "'embedded' : {" + - "'embeddedString' : 'string[1][0]'," + - "'embeddedInteger' : 10," + - "}," + + "'evilText' : 'assassinate the leader of the party'," + + "'evilEnding': {" + + "'text' : 'you become a demon'," + + "'score' : 10," + + "}" + "}," + "{" + - "'item' : 'item[0]'," + - "'anotherItem' : 'secondItem[0]'" + + "'evilText' : 'search the evil [artifact]'," + + "'goodText' : 'you punish the bandits'" + "}" + "]," + - "'anotherEmbeddedCollection' : [" + - "{ 'item' : 'another[1]' }," + - "{ 'item' : 'another[0]' }" + + "'neutralBranches' : [" + + "{ 'evilText' : 'steal the [artifact]' }," + + "{ 'evilText' : 'kill the king' }" + "]" + "}" ); - session.delete( with ); + session.delete( story ); transaction.commit(); session.clear(); session.close(); @@ -263,6 +267,6 @@ public void testEmbeddableCollection() throws Exception { @Override protected Class[] getAnnotatedClasses() { - return new Class[] { Account.class, WithEmbedded.class }; + return new Class[] { Account.class, StoryGame.class }; } } diff --git a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/EntityWithObjectIdAndEmbeddable.java b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/EntityWithObjectIdAndEmbeddable.java index 452f74c072..add8d1cf9c 100644 --- a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/EntityWithObjectIdAndEmbeddable.java +++ b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/EntityWithObjectIdAndEmbeddable.java @@ -13,7 +13,7 @@ import javax.persistence.Id; import org.bson.types.ObjectId; -import org.hibernate.ogm.backendtck.queries.AnEmbeddable; +import org.hibernate.ogm.backendtck.queries.StoryBranch; /** * @author Davide D'Alto @@ -26,12 +26,12 @@ public class EntityWithObjectIdAndEmbeddable { private ObjectId id; @Embedded - private AnEmbeddable anEmbeddable; + private StoryBranch anEmbeddable; public EntityWithObjectIdAndEmbeddable() { } - public EntityWithObjectIdAndEmbeddable(AnEmbeddable anEmbeddable) { + public EntityWithObjectIdAndEmbeddable(StoryBranch anEmbeddable) { this.anEmbeddable = anEmbeddable; } @@ -43,11 +43,11 @@ public void setId(ObjectId id) { this.id = id; } - public AnEmbeddable getAnEmbeddable() { + public StoryBranch getAnEmbeddable() { return anEmbeddable; } - public void setAnEmbeddable(AnEmbeddable details) { + public void setAnEmbeddable(StoryBranch details) { this.anEmbeddable = details; } } diff --git a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/ObjectIdWithEmbeddableTest.java b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/ObjectIdWithEmbeddableTest.java index fadfb1395b..66ce27a48f 100644 --- a/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/ObjectIdWithEmbeddableTest.java +++ b/mongodb/src/test/java/org/hibernate/ogm/datastore/mongodb/test/id/objectid/ObjectIdWithEmbeddableTest.java @@ -12,8 +12,8 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.ogm.OgmSession; -import org.hibernate.ogm.backendtck.queries.AnEmbeddable; -import org.hibernate.ogm.backendtck.queries.AnotherEmbeddable; +import org.hibernate.ogm.backendtck.queries.StoryBranch; +import org.hibernate.ogm.backendtck.queries.Ending; import org.hibernate.ogm.utils.OgmTestCase; import org.hibernate.ogm.utils.TestForIssue; import org.junit.Test; @@ -33,7 +33,7 @@ public void canUseObjectIdAssignedUponInsertWithEmbeddable() { // given EntityWithObjectIdAndEmbeddable entity = new EntityWithObjectIdAndEmbeddable(); - AnEmbeddable anEmbeddable = new AnEmbeddable( "a very nice string", null ); + StoryBranch anEmbeddable = new StoryBranch( "a very nice string", null ); entity.setAnEmbeddable( anEmbeddable ); // when @@ -47,8 +47,8 @@ public void canUseObjectIdAssignedUponInsertWithEmbeddable() { // then assertThat( loaded.getId() ).isEqualTo( entity.getId() ); - assertThat( loaded.getAnEmbeddable().getEmbeddedString() ).isEqualTo( entity.getAnEmbeddable().getEmbeddedString() ); - assertThat( loaded.getAnEmbeddable().getAnotherEmbeddable() ).isEqualTo( entity.getAnEmbeddable().getAnotherEmbeddable() ); + assertThat( loaded.getAnEmbeddable().getStoryText() ).isEqualTo( entity.getAnEmbeddable().getStoryText() ); + assertThat( loaded.getAnEmbeddable().getEnding() ).isEqualTo( entity.getAnEmbeddable().getEnding() ); tx.commit(); session.close(); @@ -62,8 +62,8 @@ public void canUseObjectIdAssignedUponInsertWithNestedEmbeddable() { // given EntityWithObjectIdAndEmbeddable entity = new EntityWithObjectIdAndEmbeddable(); - AnotherEmbeddable anotherEmbeddable = new AnotherEmbeddable( "Another nice string ... nested", 5 ); - AnEmbeddable anEmbeddable = new AnEmbeddable( "a very nice string", anotherEmbeddable ); + Ending anotherEmbeddable = new Ending( "Another nice string ... nested", 5 ); + StoryBranch anEmbeddable = new StoryBranch( "a very nice string", anotherEmbeddable ); entity.setAnEmbeddable( anEmbeddable ); // when @@ -77,9 +77,9 @@ public void canUseObjectIdAssignedUponInsertWithNestedEmbeddable() { // then assertThat( loaded.getId() ).isEqualTo( entity.getId() ); - assertThat( loaded.getAnEmbeddable().getEmbeddedString() ).isEqualTo( entity.getAnEmbeddable().getEmbeddedString() ); - assertThat( loaded.getAnEmbeddable().getAnotherEmbeddable().getEmbeddedString() ).isEqualTo( - entity.getAnEmbeddable().getAnotherEmbeddable().getEmbeddedString() ); + assertThat( loaded.getAnEmbeddable().getStoryText() ).isEqualTo( entity.getAnEmbeddable().getStoryText() ); + assertThat( loaded.getAnEmbeddable().getEnding().getText() ).isEqualTo( + entity.getAnEmbeddable().getEnding().getText() ); tx.commit(); session.close(); diff --git a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/ElementCollectionMappingTest.java b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/ElementCollectionMappingTest.java index 883ee62404..92b234ba7f 100644 --- a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/ElementCollectionMappingTest.java +++ b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/ElementCollectionMappingTest.java @@ -6,18 +6,25 @@ */ package org.hibernate.ogm.datastore.neo4j.test.mapping; +import static org.hibernate.ogm.datastore.neo4j.dialect.impl.NodeLabel.EMBEDDED; +import static org.hibernate.ogm.datastore.neo4j.dialect.impl.NodeLabel.ENTITY; +import static org.hibernate.ogm.datastore.neo4j.test.dsl.GraphAssertions.node; + +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import java.util.List; import javax.persistence.EntityManager; -import org.hibernate.ogm.backendtck.queries.AnEmbeddable; -import org.hibernate.ogm.backendtck.queries.AnotherEmbeddable; -import org.hibernate.ogm.backendtck.queries.EmbeddedCollectionItem; -import org.hibernate.ogm.backendtck.queries.WithEmbedded; +import org.hibernate.ogm.backendtck.queries.Ending; +import org.hibernate.ogm.backendtck.queries.OptionalStoryBranch; +import org.hibernate.ogm.backendtck.queries.StoryBranch; +import org.hibernate.ogm.backendtck.queries.StoryGame; +import org.hibernate.ogm.datastore.neo4j.test.dsl.NodeForGraphAssertions; +import org.hibernate.ogm.datastore.neo4j.test.dsl.RelationshipsChainForGraphAssertions; import org.junit.Before; import org.junit.Test; +import org.neo4j.cypher.javacompat.ExecutionEngine; /** * Tests the mapping of embeddable collections in Neo4j @@ -31,96 +38,138 @@ public void prepareDB() throws Exception { final EntityManager em = getFactory().createEntityManager(); em.getTransaction().begin(); - WithEmbedded with = new WithEmbedded( 1L, null ); - with.setAnEmbeddable( new AnEmbeddable( "embedded 1", new AnotherEmbeddable( "string 1", 1 ) ) ); - with.setYetAnotherEmbeddable( new AnEmbeddable( "embedded 2" ) ); - with.setAnEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "item[0]", "secondItem[0]", null ), new EmbeddedCollectionItem( "item[1]", null, new AnotherEmbeddable( "string[1][0]", 10 ) ) ) ); - with.setAnotherEmbeddedCollection( Arrays.asList( new EmbeddedCollectionItem( "another[0]", null, null ), new EmbeddedCollectionItem( "another[1]", null, null ) ) ); - - em.persist( with ); - em.getTransaction().commit(); - em.close(); - } - - @Test - public void testEmbeddedCollectionNodesMapping() throws Exception { - assertNumberOfNodes( 8 ); - assertRelationships( 7 ); - - String withEmbeddedNode = "(w:WithEmbedded:ENTITY { id: {w}.id })"; - String anEmbeddableNode = "(e:EMBEDDED {embeddedString: {e}.embeddedString})"; - String anotherEmbeddableNode = "(ae:EMBEDDED {embeddedString: {ae}.embeddedString, embeddedInteger: {ae}.embeddedInteger})"; - String yetAnotherEmbeddableNode = "(yae:EMBEDDED {embeddedString: {yae}.embeddedString})"; - - String anEmbeddedCollectionNode1 = "(ec1:EMBEDDED {embeddedString: {ec1}.embeddedString, embeddedInteger: {ec1}.embeddedInteger, item: {ec1}.item})"; - String anEmbeddedCollectionNode2 = "(ec2:EMBEDDED {item: {ec2}.item, anotherItem: {ec2}.anotherItem})"; - - String anotherEmbeddedCollectionNode1 = "(aec1:EMBEDDED {item: {aec1}.item})"; - String anotherEmbeddedCollectionNode2 = "(aec2:EMBEDDED {item: {aec2}.item})"; - - Map withEmbeddedNodeProperties = new HashMap(); - withEmbeddedNodeProperties.put( "id", 1L ); - - Map anEmbeddableNodeProperties = new HashMap(); - anEmbeddableNodeProperties.put( "embeddedString", "embedded 1" ); + List goodBranchAdditionalEndings = new ArrayList(); + goodBranchAdditionalEndings.add( new Ending( "Bonus ending - you save the world", 100 ) ); + goodBranchAdditionalEndings.add( new Ending( "Bonus ending - you kill the demon", 80 ) ); - Map anotherEmbeddableNodeProperties = new HashMap(); - anotherEmbeddableNodeProperties.put( "embeddedString", "string 1" ); - anotherEmbeddableNodeProperties.put( "embeddedInteger", 1 ); + StoryBranch goodBranch = new StoryBranch( "you go to the village", new Ending( "village ending - everybody is happy", 1 ) ); + goodBranch.setAdditionalEndings( goodBranchAdditionalEndings ); - Map yetAnotherEmbeddableNodeProperties = new HashMap(); - yetAnotherEmbeddableNodeProperties.put( "embeddedString", "embedded 2" ); + StoryBranch evilBranch = new StoryBranch( "you kill the villagers" ); - Map anEmbeddedCollectionNodeProperties1 = new HashMap(); - anEmbeddedCollectionNodeProperties1.put( "embeddedString", "string[1][0]" ); - anEmbeddedCollectionNodeProperties1.put( "embeddedInteger", 10 ); - anEmbeddedCollectionNodeProperties1.put( "item", "item[1]" ); + StoryGame story = new StoryGame( 1L, null ); + story.setGoodBranch( goodBranch ); + story.setEvilBranch( evilBranch ); - Map anEmbeddedCollectionNodeProperties2 = new HashMap(); - anEmbeddedCollectionNodeProperties2.put( "item", "item[0]" ); - anEmbeddedCollectionNodeProperties2.put( "anotherItem", "secondItem[0]" ); + story.setChaoticBranches( Arrays.asList( + new OptionalStoryBranch( "search the evil [artifact]", "you punish the bandits", null ), + new OptionalStoryBranch( "assassinate the leader of the party", null, new Ending( "you become a demon", 10 ) ) ) ); - Map anotherEmbeddedCollectionNodeProperties1 = new HashMap(); - anotherEmbeddedCollectionNodeProperties1.put( "item", "another[0]" ); + story.setNeutralBranches( Arrays.asList( + new OptionalStoryBranch( "steal the [artifact]", null, null ), + new OptionalStoryBranch( "kill the king", null, null ) ) ); - Map anotherEmbeddedCollectionNodeProperties2 = new HashMap(); - anotherEmbeddedCollectionNodeProperties2.put( "item", "another[1]" ); - - Map params = new HashMap(); - params.put( "w", withEmbeddedNodeProperties ); - params.put( "e", anEmbeddableNodeProperties ); - params.put( "ae", anotherEmbeddableNodeProperties ); - params.put( "yae", yetAnotherEmbeddableNodeProperties ); - - params.put( "ec1", anEmbeddedCollectionNodeProperties1 ); - params.put( "ec2", anEmbeddedCollectionNodeProperties2 ); - - params.put( "aec1", anotherEmbeddedCollectionNodeProperties1 ); - params.put( "aec2", anotherEmbeddedCollectionNodeProperties2 ); - - assertExpectedMapping( "w", withEmbeddedNode, params ); - assertExpectedMapping( "e", anEmbeddableNode, params ); - assertExpectedMapping( "ae", anotherEmbeddableNode, params ); - assertExpectedMapping( "yae", yetAnotherEmbeddableNode, params ); - - assertExpectedMapping( "ec1", anEmbeddedCollectionNode1, params ); - assertExpectedMapping( "ec2", anEmbeddedCollectionNode2, params ); - - assertExpectedMapping( "aec1", anotherEmbeddedCollectionNode1, params ); - assertExpectedMapping( "aec2", anotherEmbeddedCollectionNode2, params ); - - assertExpectedMapping( "r", withEmbeddedNode + " - [r:anEmbeddable] -> " + anEmbeddableNode + " - [:anotherEmbeddable] -> " + anotherEmbeddableNode, params ); - assertExpectedMapping( "r", withEmbeddedNode + " - [r:yetAnotherEmbeddable] -> " + yetAnotherEmbeddableNode, params ); + em.persist( story ); + em.getTransaction().commit(); + em.close(); + } - assertExpectedMapping( "r", withEmbeddedNode + " - [r:anEmbeddedCollection] -> " + anEmbeddedCollectionNode1, params ); - assertExpectedMapping( "r", withEmbeddedNode + " - [r:anEmbeddedCollection] -> " + anEmbeddedCollectionNode2, params ); + @Test + public void testEmbeddedCollectionNodesMapping() throws Exception { - assertExpectedMapping( "r", withEmbeddedNode + " - [r:anotherEmbeddedCollection] -> " + anotherEmbeddedCollectionNode1, params ); - assertExpectedMapping( "r", withEmbeddedNode + " - [r:anotherEmbeddedCollection] -> " + anotherEmbeddedCollectionNode2, params ); + NodeForGraphAssertions storyGameNode = node( "story", StoryGame.class.getSimpleName(), ENTITY.name() ) + .property( "id", 1L ); + + NodeForGraphAssertions goodBranchNode = node( "good", EMBEDDED.name() ) + .property( "storyText", "you go to the village" ); + + NodeForGraphAssertions goodBranchEndingNode = node( "goodEnd", EMBEDDED.name() ) + .property( "text", "village ending - everybody is happy" ) + .property( "score", 1 ); + + NodeForGraphAssertions goodBranchAdditionalEndingNode1 = node( "goodEndAdd1", EMBEDDED.name() ) + .property( "text", "Bonus ending - you save the world" ) + .property( "score", 100 ); + + NodeForGraphAssertions goodBranchAdditionalEndingNode2 = node( "goodEndAdd2", EMBEDDED.name() ) + .property( "text", "Bonus ending - you kill the demon" ) + .property( "score", 80 ); + + NodeForGraphAssertions evilBranchNode = node( "evil", EMBEDDED.name() ) + .property( "storyText", "you kill the villagers" ); + + NodeForGraphAssertions chaoticBranchNode1 = node( "chaos1", "StoryGame_chaoticBranches", EMBEDDED.name() ) + .property( "evilText", "assassinate the leader of the party" ); + + NodeForGraphAssertions chaoticBranchNode1EvilEnding = node( "chaos1End", EMBEDDED.name() ) + .property( "text", "you become a demon" ) + .property( "score", 10 ); + + NodeForGraphAssertions chaoticBranchNode2 = node( "chaos2", "StoryGame_chaoticBranches", EMBEDDED.name() ) + .property( "evilText", "search the evil [artifact]" ) + .property( "goodText", "you punish the bandits" ); + + NodeForGraphAssertions neutralBranchNode1 = node( "neutral1", "StoryGame_neutralBranches", EMBEDDED.name() ) + .property( "evilText", "steal the [artifact]" ); + + NodeForGraphAssertions neutralBranchNode2 = node( "neutral1", "StoryGame_neutralBranches", EMBEDDED.name() ) + .property( "evilText", "kill the king" ); + + RelationshipsChainForGraphAssertions relationship1 = + storyGameNode + .relationshipTo( goodBranchNode, "goodBranch" ) + .relationshipTo( goodBranchEndingNode, "ending" ); + + RelationshipsChainForGraphAssertions relationship2 = + goodBranchNode + .relationshipTo( goodBranchAdditionalEndingNode1, "additionalEndings" ); + + RelationshipsChainForGraphAssertions relationship3 = + goodBranchNode + .relationshipTo( goodBranchAdditionalEndingNode2, "additionalEndings" ); + + RelationshipsChainForGraphAssertions relationship4 = + storyGameNode + .relationshipTo( evilBranchNode, "evilBranch" ); + + RelationshipsChainForGraphAssertions relationship5 = + storyGameNode + .relationshipTo( chaoticBranchNode1, "chaoticBranches" ) + .relationshipTo( chaoticBranchNode1EvilEnding, "evilEnding" ); + + RelationshipsChainForGraphAssertions relationship6 = + storyGameNode + .relationshipTo( chaoticBranchNode2, "chaoticBranches" ); + + RelationshipsChainForGraphAssertions relationship7 = + storyGameNode + .relationshipTo( neutralBranchNode1, "neutralBranches" ); + + RelationshipsChainForGraphAssertions relationship8 = + storyGameNode + .relationshipTo( neutralBranchNode2, "neutralBranches" ); + + getTransactionManager().begin(); + ExecutionEngine executionEngine = createExecutionEngine(); + + assertThatOnlyTheseNodesExist( executionEngine + , storyGameNode + , goodBranchNode + , goodBranchEndingNode + , goodBranchAdditionalEndingNode1 + , goodBranchAdditionalEndingNode2 + , evilBranchNode + , chaoticBranchNode1 + , chaoticBranchNode1EvilEnding + , chaoticBranchNode2 + , neutralBranchNode1 + , neutralBranchNode2); + + assertThatOnlyTheseRelationshipsExist( executionEngine + , relationship1 + , relationship2 + , relationship3 + , relationship4 + , relationship5 + , relationship6 + , relationship7 + , relationship8 + ); + getTransactionManager().commit(); } @Override public Class[] getEntities() { - return new Class[] { WithEmbedded.class }; + return new Class[] { StoryGame.class }; } } diff --git a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/MapTest.java b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/MapTest.java index f3892fd635..25d6d2757d 100644 --- a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/MapTest.java +++ b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/MapTest.java @@ -5,16 +5,19 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.ogm.datastore.neo4j.test.mapping; - -import java.util.HashMap; -import java.util.Map; +import static org.hibernate.ogm.datastore.neo4j.dialect.impl.NodeLabel.EMBEDDED; +import static org.hibernate.ogm.datastore.neo4j.dialect.impl.NodeLabel.ENTITY; +import static org.hibernate.ogm.datastore.neo4j.test.dsl.GraphAssertions.node; import javax.persistence.EntityManager; import org.hibernate.ogm.backendtck.associations.collection.types.Address; import org.hibernate.ogm.backendtck.associations.collection.types.User; +import org.hibernate.ogm.datastore.neo4j.test.dsl.NodeForGraphAssertions; +import org.hibernate.ogm.datastore.neo4j.test.dsl.RelationshipsChainForGraphAssertions; import org.junit.Before; import org.junit.Test; +import org.neo4j.cypher.javacompat.ExecutionEngine; /** * @author Davide D'Alto @@ -53,62 +56,48 @@ public void prepareDb() throws Exception { @Test public void testMapping() throws Exception { - String userNode = "(u:User:ENTITY { id: {u}.id })"; - String addressNode = "(a:Address:ENTITY {id: {a}.id, city: {a}.city})"; - String nickNameNode = "(n:Nicks:EMBEDDED {nicknames: {n}.nicknames})"; - - // Expected nodes - assertExpectedMapping( "u", userNode, params( user ) ); - assertExpectedMapping( "a", addressNode, params( home ) ); - assertExpectedMapping( "a", addressNode, params( work ) ); - assertExpectedMapping( "n", nickNameNode, params( "idrA" ) ); - assertExpectedMapping( "n", nickNameNode, params( "day[9]" ) ); - assertNumberOfNodes( 5 ); - - assertExpectedMapping( "r", userNode + " - [r:nicknames] - " + nickNameNode, params( "idrA" ) ); - assertExpectedMapping( "r", userNode + " - [r:nicknames] - " + nickNameNode, params( "day[9]" ) ); - assertExpectedMapping( "r", userNode + " - [r:addresses{addressType: {r}.addressType}] - " + addressNode, params( home, "home" ) ); - assertExpectedMapping( "r", userNode + " - [r:addresses{addressType: {r}.addressType}] - " + addressNode, params( work, "work" ) ); - assertRelationships( 4 ); - } - - private Map params(Address address, String key) { - Map relationshipProperties = new HashMap(); - relationshipProperties.put( "addressType", key ); - - Map params = params( user ); - params.putAll( params( address ) ); - params.put( "r", relationshipProperties ); - return params; - } - - private Map params(User user) { - Map userProperties = new HashMap(); - userProperties.put( "id", user.getId() ); - - Map params = new HashMap(); - params.put( "u", userProperties ); - return params; - } - - private Map params(Address address) { - Map properties = new HashMap(); - properties.put( "id", address.getId() ); - properties.put( "city", address.getCity() ); - - Map params = new HashMap(); - params.put( "a", properties ); - return params; - } - - private Map params(String nick) { - Map properties = new HashMap(); - properties.put( "nicknames", nick ); - - Map params = new HashMap(); - params.put( "n", properties ); - params.putAll( params( user ) ); - return params; + NodeForGraphAssertions userNode = node( "user", User.class.getSimpleName(), ENTITY.name() ) + .property( "id", user.getId() ); + + NodeForGraphAssertions homeNode = node( "home", Address.class.getSimpleName(), ENTITY.name() ) + .property( "id", home.getId() ) + .property( "city", home.getCity() ); + + NodeForGraphAssertions workNode = node( "work", Address.class.getSimpleName(), ENTITY.name() ) + .property( "id", work.getId() ) + .property( "city", work.getCity() ); + + NodeForGraphAssertions nickNode1 = node( "nick1", "Nicks", EMBEDDED.name() ) + .property( "nicknames", "idrA" ); + + NodeForGraphAssertions nickNode2 = node( "nick2", "Nicks", EMBEDDED.name() ) + .property( "nicknames", "day[9]" ); + + getTransactionManager().begin(); + ExecutionEngine executionEngine = createExecutionEngine(); + + assertThatNodesExistOnly( executionEngine + , userNode + , homeNode + , workNode + , nickNode1 + , nickNode2 + ); + + //FIXME: Add properties to relationships + RelationshipsChainForGraphAssertions relationship1 = userNode.relationshipTo( nickNode1, "nicknames" ); + RelationshipsChainForGraphAssertions relationship2 = userNode.relationshipTo( nickNode2, "nicknames" ); + RelationshipsChainForGraphAssertions relationship3 = userNode.relationshipTo( homeNode, "addresses" ).property( "addressType", "home" ); + RelationshipsChainForGraphAssertions relationship4 = userNode.relationshipTo( workNode, "addresses" ).property( "addressType", "work" ); + + assertThatRelationshipsExistOnly( executionEngine + , relationship1 + , relationship2 + , relationship3 + , relationship4 + ); + + getTransactionManager().commit(); } @Override diff --git a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/Neo4jJpaTestCase.java b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/Neo4jJpaTestCase.java index 1a6d31a3a3..bcfc2827f1 100644 --- a/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/Neo4jJpaTestCase.java +++ b/neo4j/src/test/java/org/hibernate/ogm/datastore/neo4j/test/mapping/Neo4jJpaTestCase.java @@ -7,6 +7,8 @@ package org.hibernate.ogm.datastore.neo4j.test.mapping; import static org.fest.assertions.Assertions.assertThat; +import static org.hibernate.ogm.datastore.neo4j.test.dsl.GraphAssertions.assertThatExists; +import static org.hibernate.ogm.datastore.neo4j.test.dsl.GraphAssertions.assertThatExists; import java.util.ArrayList; import java.util.Iterator; @@ -18,6 +20,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.ogm.datastore.neo4j.impl.Neo4jDatastoreProvider; +import org.hibernate.ogm.datastore.neo4j.test.dsl.NodeForGraphAssertions; +import org.hibernate.ogm.datastore.neo4j.test.dsl.RelationshipsChainForGraphAssertions; import org.hibernate.ogm.datastore.spi.DatastoreProvider; import org.hibernate.ogm.jpa.impl.OgmEntityManagerFactory; import org.hibernate.ogm.utils.jpa.JpaTestCase; @@ -90,11 +94,16 @@ protected void assertExpectedMapping(String alias, String cypher, Map parameters) throws Exception { + ExecutionEngine engine = createExecutionEngine(); + ExecutionResult result = engine.execute( query, parameters ); + return result; + } + + protected ExecutionEngine createExecutionEngine() { SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) ( (OgmEntityManagerFactory) getFactory() ).getSessionFactory(); Neo4jDatastoreProvider provider = (Neo4jDatastoreProvider) sessionFactory.getServiceRegistry().getService( DatastoreProvider.class ); ExecutionEngine engine = new ExecutionEngine( provider.getDataBase() ); - ExecutionResult result = engine.execute( query, parameters ); - return result; + return engine; } private Long executeQuery(String queryString) throws Exception { @@ -114,4 +123,19 @@ private Long executeQuery(String queryString) throws Exception { return uniqueResult; } + protected void assertThatNodesExistOnly(ExecutionEngine executionEngine, NodeForGraphAssertions... nodes) throws Exception { + for ( NodeForGraphAssertions node : nodes ) { + assertThatExists( executionEngine, node ); + } + assertNumberOfNodes( nodes.length ); + } + + protected void assertThatRelationshipsExistOnly(ExecutionEngine executionEngine, RelationshipsChainForGraphAssertions... relationships) throws Exception { + int expectedNumberOfRelationships = 0; + for ( RelationshipsChainForGraphAssertions relationship : relationships ) { + assertThatExists( executionEngine, relationship ); + expectedNumberOfRelationships += relationship.getSize(); + } + assertRelationships( expectedNumberOfRelationships ); + } }