org.hibernate.AssertionFailure: null identifier
I hate Hibernate with a passion!More in general, I tend to hate ORM pretty much, because I feel like I need to adapt my applications and code to what the ORM thinks it should be. However, I have to use some ORMs, most notably Hibernate (I’m not reporting the version because it is awkwardly old).
Anyway, yesterday I start seeing this strange exception on one of applications of mine:
ERROR AssertionFailure <init> - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null identifier
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:61)
at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:688)
Trying to identify the problem
My first try was to enable as much logging as I could:log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type=trace
DEBUG
level. That was enlightning because it revealed me a line like the following:
DEBUG StatefulPersistenceContext initializeNonLazyCollections - initializing non-lazy collections
initialize non-lazy collections
means?
I did a code scan on the entities just to find out I’ve got a collection
@ManyToOne
with a fecthing type of EAGER
, and most notably the value I was trying to fecth was set to null
.
Yatze!
So the workflow was as follows: 1) I did load entity
A
;
2) entity A
has a @OneToOne
relationship with entity B
, so the latter is loaded by “reflection”;
3) entity B
has a @ManyToOne
relationship with entity C
and tries to EAGER
-ly fetch it.
The point 3 is, of course, the problem.
The solution
Having identified the problem, hitting the solution was quite easy: change the@ManyToOne
fetching type from EAGER
to LAZY
. Please note that even setting EAGER
with optional = true
did not work.
Again, I hate Hibernate with a passion!