@JoinColumns doesn't work inside an @Embedded member

Description

If you use multiple joincolumns on a @ManyToOne or @OneToOne field in an @Embedded class, hibernate will fail when building its metamodel with the following exception:

Exception in thread "main" org.hibernate.MappingException: property [_model_MainEntity_embeddedEntity.referencedEntity] not found on entity [model.ReferencedEntity]
at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:379)
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:406)
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:111)
at org.hibernate.cfg.AnnotationConfiguration.processEndOfQueue(AnnotationConfiguration.java:541)
at org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:523)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:380)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1377)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954)
at model.Test.main(Test.java:12)
Caused by: org.hibernate.MappingException: property [_model_MainEntity_embeddedEntity.referencedEntity] not found on entity [model.ReferencedEntity]
at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:425)
at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:376)
... 8 more

A test case is included. Just run model. Test with the hibernate libraries in the classpath.

I get the impression this is because of the dot in the generated property name. Hibernate generates a synthetic property, named after the FQN of the owning entity (with dots replaces by underscores) appended by and underscore and the name of the property. But properties inside of embedded objects are represented with a dot; when Hibernate later tries to retrieve the same property, it incorrectly interprets this dot as a delimiter, and will look for `_model_MainEntity_embeddedEntity` (in the example above) instead; which it will not find.

Environment

Version 3.5.6 and up, no DB

Activity

Show:
Joeri Hendrickx
August 25, 2011, 5:40 PM

The embedded entity looks like this:

@Embeddable
public class EmbeddedEntity implements Serializable {

@ManyToOne
@JoinColumns({
@JoinColumn(name="test", referencedColumnName="testRef"),
@JoinColumn(name="test2", referencedColumnName="test2Ref")
})
private ReferencedEntity referencedEntity;

}

Andreas Joseph Krogh
June 6, 2012, 2:34 PM

Any progress here? I'm getting bitten by this too...


Andreas

Janario Oliveira
July 21, 2012, 9:36 PM

I had the same problem a long time ago

As I saw when we create a relationship many-to-one and use referencedColumnName it creates a mapping property(SyntheticProperty) inside the entity that is the many-to-one.
How described in javadoc SyntheticProperty is a property which does not actually exist in the model.
The name of the property will be the full name of a class replacing dot(.) by underscore(_).
e.g.
br.com.janario.Entity.manyToOne > _br_com_janario_Entity_manyToOne
br.com.janario.Entity.component.manyToOne > _br_com_janario_Entity_component.manyToOne

The problem is when we have it inside a component BinderHelper(:140) replaces the name but the last path to access the property still with a dot and when it tries to read the property by name(PersistentClass.getRecursiveProperty) it splits by dot looking to a component that does not exists.

The solution is quite simple. just replace the last dot by underscore.
Once this property will be only used to this many-to-one

I sent a pull request 355 and put a test case called ReferencedColumnNameTest.testManyToOneInsideComponentReferencedColumn
https://github.com/hibernate/hibernate-orm/pull/355

Andreas Joseph Krogh
August 7, 2012, 9:13 AM

Juhu, thanks for fixing!

Brett Meyer
March 7, 2014, 10:09 PM

Bulk closing tickets resolved in released versions

Assignee

Strong Liu

Reporter

Joeri Hendrickx

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure