HHH-9485 - Duplicate Property with AccessType.PROPERTY and MappedSuperclass
This commit is contained in:
parent
8d2de0beaa
commit
a5cbe326d6
|
@ -1497,8 +1497,17 @@ public final class AnnotationBinder {
|
|||
private static int addProperty(
|
||||
PropertyContainer propertyContainer,
|
||||
XProperty property,
|
||||
List<PropertyData> annElts,
|
||||
List<PropertyData> inFlightPropertyDataList,
|
||||
MetadataBuildingContext context) {
|
||||
// see if inFlightPropertyDataList already contains a PropertyData for this name,
|
||||
// and if so, skip it..
|
||||
for ( PropertyData propertyData : inFlightPropertyDataList ) {
|
||||
if ( propertyData.getPropertyName().equals( property.getName() ) ) {
|
||||
// EARLY EXIT!!!
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
final XClass declaringClass = propertyContainer.getDeclaringClass();
|
||||
final XClass entity = propertyContainer.getEntityAtStake();
|
||||
int idPropertyCounter = 0;
|
||||
|
@ -1515,7 +1524,7 @@ public final class AnnotationBinder {
|
|||
*/
|
||||
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
|
||||
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
|
||||
annElts.add( 0, propertyAnnotatedElement );
|
||||
inFlightPropertyDataList.add( 0, propertyAnnotatedElement );
|
||||
/**
|
||||
* The property must be put in hibernate.properties as it's a system wide property. Fixable?
|
||||
* TODO support true/false/default on the property instead of present / not present
|
||||
|
@ -1573,7 +1582,7 @@ public final class AnnotationBinder {
|
|||
idPropertyCounter++;
|
||||
}
|
||||
else {
|
||||
annElts.add( propertyAnnotatedElement );
|
||||
inFlightPropertyDataList.add( propertyAnnotatedElement );
|
||||
}
|
||||
if ( element.isAnnotationPresent( MapsId.class ) ) {
|
||||
context.getMetadataCollector().addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
|
||||
|
@ -1597,6 +1606,16 @@ public final class AnnotationBinder {
|
|||
boolean inSecondPass,
|
||||
MetadataBuildingContext context,
|
||||
Map<XClass, InheritanceState> inheritanceStatePerClass) throws MappingException {
|
||||
|
||||
if ( entityBinder.isPropertyDefinedInSuperHierarchy( inferredData.getPropertyName() ) ) {
|
||||
LOG.debugf(
|
||||
"Skipping attribute [%s : %s] as it was already processed as part of super hierarchy",
|
||||
inferredData.getClassOrElementName(),
|
||||
inferredData.getPropertyName()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* inSecondPass can only be used to apply right away the second pass of a composite-element
|
||||
* Because it's a value type, there is no bidirectional association, hence second pass
|
||||
|
|
|
@ -80,7 +80,9 @@ import org.hibernate.internal.CoreMessageLogger;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.DependantValue;
|
||||
import org.hibernate.mapping.Join;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.SingleTableSubclass;
|
||||
|
@ -159,6 +161,24 @@ public class EntityBinder {
|
|||
bindHibernateAnnotation( hibAnn );
|
||||
}
|
||||
|
||||
/**
|
||||
* For the most part, this is a simple delegation to {@link PersistentClass#isPropertyDefinedInHierarchy},
|
||||
* after verifying that PersistentClass is indeed set here.
|
||||
*
|
||||
* @param name The name of the property to check
|
||||
*
|
||||
* @return {@code true} if a property by that given name does already exist in the super hierarchy.
|
||||
*/
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
public boolean isPropertyDefinedInSuperHierarchy(String name) {
|
||||
// Yes, yes... persistentClass can be null because EntityBinder can be used
|
||||
// to bind components as well, of course...
|
||||
if ( persistentClass == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return persistentClass.isPropertyDefinedInSuperHierarchy( name );
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableConditionalExpression")
|
||||
private void bindHibernateAnnotation(org.hibernate.annotations.Entity hibAnn) {
|
||||
|
|
|
@ -163,4 +163,51 @@ public class MappedSuperclass {
|
|||
public void setDeclaredIdentifierMapper(Component identifierMapper) {
|
||||
this.identifierMapper = identifierMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this MappedSuperclass defines a property with the given name.
|
||||
*
|
||||
* @param name The property name to check
|
||||
*
|
||||
* @return {@code true} if a property with that name exists; {@code false} if not
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public boolean hasProperty(String name) {
|
||||
final Iterator itr = getDeclaredPropertyIterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final Property property = (Property) itr.next();
|
||||
if ( property.getName().equals( name ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a property with the given name exists in this MappedSuperclass
|
||||
* or in any of its super hierarchy.
|
||||
*
|
||||
* @param name The property name to check
|
||||
*
|
||||
* @return {@code true} if a property with that name exists; {@code false} if not
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "RedundantIfStatement"})
|
||||
public boolean isPropertyDefinedInHierarchy(String name) {
|
||||
if ( hasProperty( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( getSuperMappedSuperclass() != null
|
||||
&& getSuperMappedSuperclass().isPropertyDefinedInHierarchy( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( getSuperPersistentClass() != null
|
||||
&& getSuperPersistentClass().isPropertyDefinedInHierarchy( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.hibernate.engine.OptimisticLockStyle;
|
|||
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
|
||||
import org.hibernate.engine.spi.Mapping;
|
||||
import org.hibernate.internal.FilterConfiguration;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.EmptyIterator;
|
||||
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||
|
@ -498,6 +497,73 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this PersistentClass defines a property with the given name.
|
||||
*
|
||||
* @param name The property name to check
|
||||
*
|
||||
* @return {@code true} if a property with that name exists; {@code false} if not
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public boolean hasProperty(String name) {
|
||||
final Property identifierProperty = getIdentifierProperty();
|
||||
if ( identifierProperty != null && identifierProperty.getName().equals( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Iterator itr = getPropertyClosureIterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final Property property = (Property) itr.next();
|
||||
if ( property.getName().equals( name ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a property with the given name exists in the super hierarchy
|
||||
* of this PersistentClass. Does not check this PersistentClass, just up the
|
||||
* hierarchy
|
||||
*
|
||||
* @param name The property name to check
|
||||
*
|
||||
* @return {@code true} if a property with that name exists; {@code false} if not
|
||||
*/
|
||||
public boolean isPropertyDefinedInSuperHierarchy(String name) {
|
||||
return getSuperclass() != null && getSuperclass().isPropertyDefinedInHierarchy( name );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a property with the given name exists in this PersistentClass
|
||||
* or in any of its super hierarchy. Unlike {@link #isPropertyDefinedInSuperHierarchy},
|
||||
* this method does check this PersistentClass
|
||||
*
|
||||
* @param name The property name to check
|
||||
*
|
||||
* @return {@code true} if a property with that name exists; {@code false} if not
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "RedundantIfStatement"})
|
||||
public boolean isPropertyDefinedInHierarchy(String name) {
|
||||
if ( hasProperty( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( getSuperMappedSuperclass() != null
|
||||
&& getSuperMappedSuperclass().isPropertyDefinedInHierarchy( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( getSuperclass() != null
|
||||
&& getSuperclass().isPropertyDefinedInHierarchy( name ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated prefer {@link #getOptimisticLockStyle}
|
||||
*/
|
||||
|
|
|
@ -43,7 +43,6 @@ public class InheritedAttributeOverridingTest extends BaseUnitTestCase {
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9485" )
|
||||
@FailureExpected( jiraKey = "HHH-9485" )
|
||||
public void testInheritedAttributeOverridingMappedsuperclass() {
|
||||
Metadata metadata = new MetadataSources( standardServiceRegistry )
|
||||
.addAnnotatedClass( A.class )
|
||||
|
@ -55,7 +54,6 @@ public class InheritedAttributeOverridingTest extends BaseUnitTestCase {
|
|||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-9485" )
|
||||
@FailureExpected( jiraKey = "HHH-9485" )
|
||||
public void testInheritedAttributeOverridingEntity() {
|
||||
Metadata metadata = new MetadataSources( standardServiceRegistry )
|
||||
.addAnnotatedClass( C.class )
|
||||
|
|
Loading…
Reference in New Issue