HHH-12375 Fix for eager loading same named properties with conflicting types
This commit is contained in:
parent
f030e7f39f
commit
7dd640a65e
|
@ -152,9 +152,9 @@ public abstract class AbstractPropertyMapping implements PropertyMapping {
|
|||
String[] formulaTemplates,
|
||||
Mapping factory) {
|
||||
Type existingType = typesByPropertyPath.get( path );
|
||||
if ( existingType != null ) {
|
||||
if ( existingType != null || typesByPropertyPath.containsKey( path ) ) {
|
||||
// If types match or the new type is not an association type, there is nothing for us to do
|
||||
if ( type == existingType || !( type instanceof AssociationType ) ) {
|
||||
if ( type == existingType || existingType == null || !( type instanceof AssociationType ) ) {
|
||||
logDuplicateRegistration(
|
||||
path,
|
||||
existingType,
|
||||
|
@ -173,12 +173,12 @@ public abstract class AbstractPropertyMapping implements PropertyMapping {
|
|||
return;
|
||||
}
|
||||
|
||||
Type newType;
|
||||
Type newType = null;
|
||||
MetadataImplementor metadata = (MetadataImplementor) factory;
|
||||
|
||||
if ( type instanceof AnyType ) {
|
||||
// TODO: not sure how to handle any types
|
||||
throw new UnsupportedOperationException( "Not yet implemented!" );
|
||||
// TODO: not sure how to handle any types. For now we just return and let the first type dictate what type the property has...
|
||||
return;
|
||||
}
|
||||
else if ( type instanceof CollectionType ) {
|
||||
Collection thisCollection = metadata.getCollectionBinding( ( (CollectionType) existingType ).getRole() );
|
||||
|
@ -193,7 +193,7 @@ public abstract class AbstractPropertyMapping implements PropertyMapping {
|
|||
return;
|
||||
}
|
||||
|
||||
// When we discover incompatible types, we register "null" as property type to signal that the property is not resolvable on the parent type
|
||||
// When we discover incompatible types, we use "null" as property type to signal that the property is not resolvable on the parent type
|
||||
newType = null;
|
||||
if ( LOG.isTraceEnabled() ) {
|
||||
LOG.tracev(
|
||||
|
@ -220,9 +220,6 @@ public abstract class AbstractPropertyMapping implements PropertyMapping {
|
|||
|
||||
newType = getCommonType( metadata, entityType1, entityType2 );
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException( "Unexpected association type: " + type );
|
||||
}
|
||||
|
||||
typesByPropertyPath.put( path, newType );
|
||||
// Set everything to empty to signal action has to be taken!
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|||
import org.hibernate.loader.PropertyPath;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
import org.hibernate.persister.entity.AbstractEntityPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -90,8 +91,9 @@ public class MetamodelGraphWalker {
|
|||
private void visitEntityDefinition(EntityDefinition entityDefinition) {
|
||||
strategy.startingEntity( entityDefinition );
|
||||
|
||||
AbstractEntityPersister persister = (AbstractEntityPersister) entityDefinition.getEntityPersister();
|
||||
visitIdentifierDefinition( entityDefinition.getEntityKeyDefinition() );
|
||||
visitAttributes( entityDefinition );
|
||||
visitAttributes( entityDefinition, persister);
|
||||
|
||||
strategy.finishingEntity( entityDefinition );
|
||||
}
|
||||
|
@ -122,17 +124,17 @@ public class MetamodelGraphWalker {
|
|||
strategy.finishingEntityIdentifier( identifierDefinition );
|
||||
}
|
||||
|
||||
private void visitAttributes(AttributeSource attributeSource) {
|
||||
private void visitAttributes(AttributeSource attributeSource, AbstractEntityPersister sourcePersister) {
|
||||
final Iterable<AttributeDefinition> attributeDefinitions = attributeSource.getAttributes();
|
||||
if ( attributeDefinitions == null ) {
|
||||
return;
|
||||
}
|
||||
for ( AttributeDefinition attributeDefinition : attributeDefinitions ) {
|
||||
visitAttributeDefinition( attributeDefinition );
|
||||
visitAttributeDefinition( attributeDefinition, sourcePersister);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitAttributeDefinition(AttributeDefinition attributeDefinition) {
|
||||
private void visitAttributeDefinition(AttributeDefinition attributeDefinition, AbstractEntityPersister sourcePersister) {
|
||||
final PropertyPath subPath = currentPropertyPath.append( attributeDefinition.getName() );
|
||||
log.debug( "Visiting attribute path : " + subPath.getFullPath() );
|
||||
|
||||
|
@ -147,6 +149,14 @@ public class MetamodelGraphWalker {
|
|||
// EARLY EXIT!!!
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sourcePersister != null ) {
|
||||
String[] columns = sourcePersister.toColumns(attributeDefinition.getName());
|
||||
// Empty columns means that the attribute is not resolvable on this persister
|
||||
if ( columns.length == 0 ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +206,7 @@ public class MetamodelGraphWalker {
|
|||
private void visitCompositeDefinition(CompositionDefinition compositionDefinition) {
|
||||
strategy.startingComposite( compositionDefinition );
|
||||
|
||||
visitAttributes( compositionDefinition );
|
||||
visitAttributes( compositionDefinition, null );
|
||||
|
||||
strategy.finishingComposite( compositionDefinition );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.test.inheritance.discriminator;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Test cases for joined inheritance with eager fetching.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class JoinedInheritanceEagerTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class[] {
|
||||
BaseEntity.class,
|
||||
EntityA.class,
|
||||
EntityB.class,
|
||||
EntityC.class,
|
||||
EntityD.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-12375" )
|
||||
public void joinUnrelatedCollectionOnBaseType() {
|
||||
final Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
|
||||
try {
|
||||
s.createQuery("from BaseEntity b join b.attributes").list();
|
||||
Assert.fail("Expected a resolution exception for property 'attributes'!");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Assert.assertTrue(ex.getMessage().contains("could not resolve property: attributes "));
|
||||
} finally {
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "BaseEntity")
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public static class BaseEntity {
|
||||
@Id
|
||||
private long id;
|
||||
}
|
||||
|
||||
@Entity(name = "EntityA")
|
||||
public static class EntityA extends BaseEntity {
|
||||
@OneToMany(fetch = FetchType.LAZY)
|
||||
private Set<EntityC> attributes;
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
private EntityC relation;
|
||||
}
|
||||
|
||||
@Entity(name = "EntityB")
|
||||
public static class EntityB extends BaseEntity {
|
||||
@OneToMany(fetch = FetchType.LAZY)
|
||||
private Set<EntityD> attributes;
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
private EntityD relation;
|
||||
}
|
||||
|
||||
@Entity(name = "EntityC")
|
||||
public static class EntityC {
|
||||
@Id
|
||||
private long id;
|
||||
}
|
||||
|
||||
@Entity(name = "EntityD")
|
||||
public static class EntityD {
|
||||
@Id
|
||||
private long id;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue