From e5b8eb5f23b8550ab1edba637b8bb9f9242f72dc Mon Sep 17 00:00:00 2001 From: Gail Badner Date: Thu, 8 Dec 2016 12:25:41 -0800 Subject: [PATCH] HHH-11241 : Missing column when executing HQL and criteria query with secondary table (cherry picked from commit b8f9deacc713a6b67f3df1e2473b689f6dfc8247) (cherry picked from commit f490451b6d046d39a04c80079a86e8d20f60d895) --- .../entity/AbstractEntityPersister.java | 58 +++++++++++++++++++ .../entity/SingleTableEntityPersister.java | 14 ++++- .../SubclassesWithSamePropertyNameTest.java | 4 -- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index b3e6c3b167..5327bf1b25 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -268,6 +268,14 @@ public abstract class AbstractEntityPersister private final Map subclassPropertyAliases = new HashMap(); private final Map subclassPropertyColumnNames = new HashMap(); + /** + * Warning: + * When there are duplicated property names in the subclasses + * then propertyMapping will only contain one of those properties. + * To ensure correct results, propertyMapping should only be used + * for the concrete EntityPersister (since the concrete EntityPersister + * cannot have duplicated property names). + */ protected final BasicEntityPropertyMapping propertyMapping; private final boolean useReferenceCacheEntries; @@ -1802,18 +1810,58 @@ public abstract class AbstractEntityPersister return getRootTableKeyColumnNames(); } + /** + * {@inheritDoc} + * + * Warning: + * When there are duplicated property names in the subclasses + * then this method may return the wrong results. + * To ensure correct results, this method should only be used when + * {@literal this} is the concrete EntityPersister (since the + * concrete EntityPersister cannot have duplicated property names). + */ public String[] toColumns(String alias, String propertyName) throws QueryException { return propertyMapping.toColumns( alias, propertyName ); } + /** + * {@inheritDoc} + * + * Warning: + * When there are duplicated property names in the subclasses + * then this method may return the wrong results. + * To ensure correct results, this method should only be used when + * {@literal this} is the concrete EntityPersister (since the + * concrete EntityPersister cannot have duplicated property names). + */ public String[] toColumns(String propertyName) throws QueryException { return propertyMapping.getColumnNames( propertyName ); } + /** + * {@inheritDoc} + * + * Warning: + * When there are duplicated property names in the subclasses + * then this method may return the wrong results. + * To ensure correct results, this method should only be used when + * {@literal this} is the concrete EntityPersister (since the + * concrete EntityPersister cannot have duplicated property names). + */ public Type toType(String propertyName) throws QueryException { return propertyMapping.toType( propertyName ); } + /** + * {@inheritDoc} + * + * Warning: + * When there are duplicated property names in the subclasses + * then this method may return the wrong results. + * To ensure correct results, this method should only be used when + * {@literal this} is the concrete EntityPersister (since the + * concrete EntityPersister cannot have duplicated property names). + */ public String[] getPropertyColumnNames(String propertyName) { return propertyMapping.getColumnNames( propertyName ); } @@ -4499,6 +4547,16 @@ public abstract class AbstractEntityPersister return false; } + /** + * {@inheritDoc} + * + * Warning: + * When there are duplicated property names in the subclasses + * then this method may return the wrong results. + * To ensure correct results, this method should only be used when + * {@literal this} is the concrete EntityPersister (since the + * concrete EntityPersister cannot have duplicated property names). + */ public Type getPropertyType(String propertyName) throws MappingException { return propertyMapping.toType( propertyName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java index b20f2876d4..a9fdbdcfe8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java @@ -712,7 +712,19 @@ public class SingleTableEntityPersister extends AbstractEntityPersister { } private int getSubclassPropertyTableNumber(String propertyName, String entityName) { - Type type = propertyMapping.toType( propertyName ); + // When there are duplicated property names in the subclasses + // then propertyMapping.toType( propertyName ) may return an + // incorrect Type. To ensure correct results, lookup the property type + // using the concrete EntityPersister with the specified entityName + // (since the concrete EntityPersister cannot have duplicated property names). + final EntityPersister concreteEntityPersister; + if ( getEntityName().equals( entityName ) ) { + concreteEntityPersister = this; + } + else { + concreteEntityPersister = getFactory().getMetamodel().entityPersister( entityName ); + } + Type type = concreteEntityPersister.getPropertyType( propertyName ); if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) { return 0; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/join/SubclassesWithSamePropertyNameTest.java b/hibernate-core/src/test/java/org/hibernate/test/join/SubclassesWithSamePropertyNameTest.java index c1cb2c867b..192bf70adc 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/join/SubclassesWithSamePropertyNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/join/SubclassesWithSamePropertyNameTest.java @@ -11,7 +11,6 @@ import org.junit.Test; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.criterion.Restrictions; -import org.hibernate.testing.FailureExpected; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; @@ -59,7 +58,6 @@ public class SubclassesWithSamePropertyNameTest extends BaseCoreFunctionalTestCa @Test @TestForIssue( jiraKey = "HHH-11241" ) - @FailureExpected( jiraKey = "HHH-11241" ) public void testGetSuperclass() { Session s = openSession(); Transaction tx = s.beginTransaction(); @@ -72,7 +70,6 @@ public class SubclassesWithSamePropertyNameTest extends BaseCoreFunctionalTestCa @Test @TestForIssue( jiraKey = "HHH-11241" ) - @FailureExpected( jiraKey = "HHH-11241" ) public void testQuerySuperclass() { Session s = openSession(); Transaction tx = s.beginTransaction(); @@ -87,7 +84,6 @@ public class SubclassesWithSamePropertyNameTest extends BaseCoreFunctionalTestCa @Test @TestForIssue( jiraKey = "HHH-11241" ) - @FailureExpected( jiraKey = "HHH-11241" ) public void testCriteriaSuperclass() { Session s = openSession(); Transaction tx = s.beginTransaction();