That’s exactly what I thought at first. But if I remove the property-ref, or even the whole <set> mapping, the error persists. To make things even worse, if I remove the other<set> mapping, the one in the CostCenter entity itself, the error is gone. Doesn’t make any sense whatsoever. Seriously weird.
But I think I found the bug anyway. Look for it in the constructor of AbstractPluralAttributeSourceImpl:
protected AbstractPluralAttributeSourceImpl(
MappingDocument mappingDocument,
final PluralAttributeInfo pluralAttributeJaxbMapping,
AttributeSourceContainer container) {
super( mappingDocument );
this.pluralAttributeJaxbMapping = pluralAttributeJaxbMapping;
this.container = container;
this.attributeRole = container.getAttributeRoleBase().append( pluralAttributeJaxbMapping.getName() );
this.attributePath = container.getAttributePathBase().append( pluralAttributeJaxbMapping.getName() );
/* This whole thing is new in 5.4 */
Optional<JaxbHbmManyToOneType> jaxbHbmManyToOneTypeOptional = Optional.empty();
if ( pluralAttributeJaxbMapping.isInverse() && pluralAttributeJaxbMapping.getOneToMany() != null ) {
String childClass = pluralAttributeJaxbMapping.getOneToMany().getClazz();
if ( childClass != null ) {
jaxbHbmManyToOneTypeOptional = mappingDocument.getDocumentRoot().getClazz()
.stream()
/* If I'm not mistaken, this checks if the class in question references itself */
.filter( (JaxbHbmRootEntityType entityType) -> childClass.equals( entityType.getName() ) )
/* If it does, we forget about it and look for any (!!!) many-to-one attribute with a property-ref ... */
.flatMap( jaxbHbmRootEntityType -> jaxbHbmRootEntityType.getAttributes().stream() )
.filter(
attribute -> attribute instanceof JaxbHbmManyToOneType &&
( (JaxbHbmManyToOneType) attribute ).getPropertyRef() != null )
.map( JaxbHbmManyToOneType.class::cast )
.findFirst();
}
}
/* ... and use it to fill the keySource, even if (as in my case) it has nothing to do with the original pluralAttributeJaxbMapping at all. This cannot work. */
this.keySource = jaxbHbmManyToOneTypeOptional
.map( jaxbHbmManyToOneType -> new PluralAttributeKeySourceImpl(
sourceMappingDocument(),
jaxbHbmManyToOneType,
container
/* This is the old 5.2 behavior, which does work. */
) ).orElseGet( () -> new PluralAttributeKeySourceImpl(
sourceMappingDocument(),
pluralAttributeJaxbMapping.isInverse() ? /* And what's this? It's not wrong, but still. */
pluralAttributeJaxbMapping.getKey() :
pluralAttributeJaxbMapping.getKey(),
container
) );
I just don’t know what is the right fix here. That will have to be figured out by someone who has an idea about why all this stuff was added in the first place.