When I map a @ManyToOne relationship with optional=true, an EntityNotFoundException is thrown. According to the documentation this relationship should not be loaded.
Documentation of "optional": Whether the association is optional. If set to false then a non-null relationship must always exist."
The inverse means that if the parameter is set to true, a null relationship can exist. The thrown EntityNotFoundException is only understandable for me with optional=false. Is this a bug or a problem of understanding? Before switching to Hibernate 5.3.17 this mapping worked like this.
And this is the thrown exception:
_Caused by: javax.persistence.EntityNotFoundException: Unable to find ClassC with id c7bc3ad5-4017-4304-a3ff-e56e571ea6ec
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:163)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:180)
at org.hibernate.proxy.AbstractLazyInitializer.getIdentifier(AbstractLazyInitializer.java:89)
at org.hibernate.proxy.pojo.BasicLazyInitializer.invoke(BasicLazyInitializer.java:65)
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:43)
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
at ClassC$HibernateProxy$8ocrDHSV.getUid(Unknown Source)
at ManagerClassB.dbGetClassBById(ManagerClassB.java:39)_
As far as I can say, this is expected. If your FK column is set, Hibernate assumes the object exists. You can control what should happen with the @NotFound annotation: https://docs.jboss.org/hibernate/orm/5.3/javadocs/index.html?org/hibernate/annotations/NotFound.html
Thanks for your feedback. In my opinion this behaviour should also be achievable with optional=true and without using the Hibernate annotation @NotFound. Or do I interpret the optional parameter completely wrong?
It’s not specified exactly what this means, but let’s play this through. Since optional = true is the default, we’d almost always have to join every target table to check if the object actually exists to decide if we should initialize null or a proxy. This is would hurt performance significantly.
In Hibernate, we tie the nullness of an association to the nullness of the declared join column. So if the join column is not null, we assume the target row exists. To handle cases where the target row is missing, the @NotFound annotation was introduced.
The mapping you are probably looking for is an association to an inheritance entity model. Something like the following: