From 27ac1dbbe4d30694bbe0c7bd468c46bf97b39c7e Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Fri, 20 Feb 2015 17:32:06 -0800 Subject: [PATCH] HHH-9457 : EntityGraph with order by using Oracle10gDialect (cherry picked from commit 9337f731853b5b62c8db843a197260091ac0fe90) --- .../hibernate/dialect/Oracle10gDialect.java | 5 ++ .../hibernate/jpa/test/graphs/Company.java | 4 + .../hibernate/jpa/test/graphs/Location.java | 4 + .../queryhint/QueryHintEntityGraphTest.java | 74 ++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java index 850db1df17..cc51a69314 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java @@ -48,6 +48,11 @@ public class Oracle10gDialect extends Oracle9iDialect { return new ANSIJoinFragment(); } + @Override + public String getCrossJoinSeparator() { + return " cross join "; + } + @Override public String getWriteLockString(int timeout) { if ( timeout == LockOptions.SKIP_LOCKED ) { diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Company.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Company.java index 3ab98c0c9b..426792877f 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Company.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Company.java @@ -51,4 +51,8 @@ public class Company { @ElementCollection(fetch = FetchType.EAGER) public Set phoneNumbers = new HashSet(); + + public Location getLocation() { + return location; + } } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Location.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Location.java index 4543e605b2..4726ef150c 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Location.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/Location.java @@ -35,4 +35,8 @@ public class Location { public String address; public int zip; + + public int getZip() { + return zip; + } } diff --git a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/queryhint/QueryHintEntityGraphTest.java b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/queryhint/QueryHintEntityGraphTest.java index 3dfd4df1ec..43f5356ac0 100644 --- a/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/queryhint/QueryHintEntityGraphTest.java +++ b/hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/graphs/queryhint/QueryHintEntityGraphTest.java @@ -20,10 +20,13 @@ */ package org.hibernate.jpa.test.graphs.queryhint; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.util.Iterator; +import java.util.List; import javax.persistence.EntityGraph; import javax.persistence.EntityManager; @@ -64,7 +67,7 @@ public class QueryHintEntityGraphTest extends BaseEntityManagerFunctionalTestCas Query query = entityManager.createQuery( "from " + Company.class.getName() ); query.setHint( QueryHints.HINT_LOADGRAPH, entityGraph ); Company company = (Company) query.getSingleResult(); - + entityManager.getTransaction().commit(); entityManager.close(); @@ -94,6 +97,7 @@ public class QueryHintEntityGraphTest extends BaseEntityManagerFunctionalTestCas assertTrue( Hibernate.isInitialized( company.employees ) ); assertTrue( Hibernate.isInitialized( company.location ) ); + assertEquals( 12345, company.location.zip ); assertTrue( Hibernate.isInitialized( company.markets ) ); // With "loadgraph", non-specified attributes use the fetch modes defined in the mappings. So, here, // @ElementCollection(fetch = FetchType.EAGER) should cause the follow-on selects to happen. @@ -117,6 +121,74 @@ public class QueryHintEntityGraphTest extends BaseEntityManagerFunctionalTestCas assertTrue(foundManager); } + @Test + @TestForIssue( jiraKey = "HHH-9457") + public void testLoadGraphOrderByWithImplicitJoin() { + EntityManager entityManager = getOrCreateEntityManager(); + entityManager.getTransaction().begin(); + + // create a new Company at a different location in a different zip code + Location location = new Location(); + location.address = "123 somewhere"; + location.zip = 11234; + entityManager.persist( location ); + Company companyNew = new Company(); + companyNew.location = location; + entityManager.persist( companyNew ); + + entityManager.getTransaction().commit(); + entityManager.close(); + + entityManager = getOrCreateEntityManager(); + entityManager.getTransaction().begin(); + + EntityGraph entityGraph = entityManager.createEntityGraph( Company.class ); + //entityGraph.addAttributeNodes( "location" ); + entityGraph.addAttributeNodes( "markets" ); + Query query = entityManager.createQuery( "from " + Company.class.getName() + " c order by c.location.zip, c.id" ); + query.setHint( QueryHints.HINT_LOADGRAPH, entityGraph ); + List results = query.getResultList(); + + // we expect 3 results: + // - 1st will be the Company with location.zip == 11234 with an empty markets collection + // - 2nd and 3rd should be the Company with location.zip == 12345 + // (2nd and 3rd are duplicated because that entity has 2 elements in markets collection + assertEquals( 3, results.size() ); + + Company companyResult = (Company) results.get( 0 ); + assertFalse( Hibernate.isInitialized( companyResult.employees ) ); + assertFalse( Hibernate.isInitialized( companyResult.location ) ); + // initialize and check zip + // TODO: must have getters to access lazy entity after being initialized (why?) + //assertEquals( 11234, companyResult.location.zip ); + assertEquals( 11234, companyResult.getLocation().getZip() ); + assertTrue( Hibernate.isInitialized( companyResult.markets ) ); + assertEquals( 0, companyResult.markets.size() ); + // With "loadgraph", non-specified attributes use the fetch modes defined in the mappings. So, here, + // @ElementCollection(fetch = FetchType.EAGER) should cause the follow-on selects to happen. + assertTrue( Hibernate.isInitialized( companyResult.phoneNumbers ) ); + assertEquals( 0, companyResult.phoneNumbers.size() ); + + companyResult = (Company) results.get( 1 ); + assertFalse( Hibernate.isInitialized( companyResult.employees ) ); + assertFalse( Hibernate.isInitialized( companyResult.location ) ); + // initialize and check zip + // TODO: must have getters to access lazy entity after being initialized (why?) + //assertEquals( 12345, companyResult.location.zip ); + assertEquals( 12345, companyResult.getLocation().getZip() ); + assertTrue( Hibernate.isInitialized( companyResult.markets ) ); + assertEquals( 2, companyResult.markets.size() ); + // With "loadgraph", non-specified attributes use the fetch modes defined in the mappings. So, here, + // @ElementCollection(fetch = FetchType.EAGER) should cause the follow-on selects to happen. + assertTrue( Hibernate.isInitialized( companyResult.phoneNumbers ) ); + assertEquals( 2, companyResult.phoneNumbers.size() ); + + assertSame( companyResult, results.get( 2 ) ); + + entityManager.getTransaction().commit(); + entityManager.close(); + } + @Test @TestForIssue( jiraKey = "HHH-9448") @FailureExpected( jiraKey = "HHH-9448")