| Hello, It is possible to get a FALSE executing something like this:
emf.getMetamodel().getEmbeddables().contains(Company_.address.getElementType());
emf.getMetamodel().getEmbeddables().contains(Person_.address.getElementType());
where Address is an @Embeddable. The problem is here:
private <Y> Type<Y> getMetaModelType(ValueContext typeContext) {
switch ( typeContext.getValueClassification() ) {
case BASIC: {
return new BasicTypeImpl<Y>(
typeContext.getBindableType(),
Type.PersistenceType.BASIC
);
}
case ENTITY: {
final org.hibernate.type.EntityType type = (EntityType) typeContext.getValue().getType();
return (Type<Y>) context.locateEntityType( type.getAssociatedEntityName() );
}
case EMBEDDABLE: {
final Component component = (Component) typeContext.getValue();
Class javaType;
if ( component.getComponentClassName() == null ) {
javaType = typeContext.getBindableType();
}
else {
javaType = component.getComponentClass();
}
---->HERE final EmbeddableTypeImpl<Y> embeddableType = new EmbeddableTypeImpl<Y>(
javaType,
typeContext.getAttributeMetadata().getOwnerType(),
(ComponentType) typeContext.getValue().getType()
);
context.registerEmbeddedableType( embeddableType );
final Iterator<Property> subProperties = component.getPropertyIterator();
while ( subProperties.hasNext() ) {
final Property property = subProperties.next();
final AttributeImplementor<Y, Object> attribute = buildAttribute( embeddableType, property );
if ( attribute != null ) {
embeddableType.getBuilder().addAttribute( attribute );
}
}
embeddableType.lock();
return embeddableType;
}
default: {
throw new AssertionFailure( "Unknown type : " + typeContext.getValueClassification() );
}
}
}
This is creating a new EmbeddableTypeImpl each time an @Embeddable is used on a different Attribute. The problem is that EmbeddableTypeImpl (and also its class hierarchy) doesn't implement equals() so each instance is compared for equivalence as with ==. I see 2 simple solutions:
- prevent the duplicated instantiation in getMetaModelType() (maybe using a Map<Class<?>, EmbeddableTypeImpl<?>>)
- let EmbeddableTypeImpl (maybe TypeImpl?) implement hashCode() and equals() based on getJavaType() comparison (since it is a natural unique key)
I think the problem is immediate enough to verify just looking at the code snipped, but if you need a Test Case, I'll do it asap. If you decide to accept any of the proposed solutions, I can try to solve it and submit a PR on github. Thank you |