Solved: Hibernate not autoscanning entity classes
I recently had to update an old Java (.war) JPA/Hibernate project (from Hibernate 5.4 to 7.2, among other things), and ran into org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'Foo' issues at runtime. (My classes were annotated with @Entity and named correctly.) Relatedly, when I tried to set jakarta.persistence.schema-generation.database.action to CREATE or similar (e.g., for testing in a new environment), it wouldn’t generate my tables.
This used to work, and while I discovered that explicitly adding <class>org.example.Foo.Bar</class>-type entries to my persistence.xml worked around the issue, that was dissatisfying, since everything indicated this should “just work” (as it had before), and I’d rather avoid adding additional touch-points that inevitably will be missed when some new @Entity class is added in the future.
Several proposed solutions didn’t work for me, complicated by the (apparently unusual?) situation that my project builds a .war file with all of my code compiled into .class files nested under WEB-INF/classes instead of a .jar file that could be succinctly referenced in a <jar-file> element of persistence.xml.
Along the way, I found many guides explaining that the Persistence / EntityManager provider should automatically scan / include @Entity classes found under a PersistenceUnit‘s “root”, without explaining what that was. I eventually turned to the JPA 3.2 specification ยง8.2 to learn that, in my case, the root was “the WEB-INF/classes directory of a WAR file”. (My .war contains all of my classes as, e.g., WEB-INF/classes/org/example/Foo/Bar.class files.)
Long story short, the suggestion found several places of adding <property name="hibernate.archive.autodetection" value="class" /> to persistence.xml was close, but, at least in my scenario, missed an important piece. (Many had actually unnecessarily suggested "class, hbm" as a value; while the additional ‘, hbm‘ shouldn’t break things, none of the people had expressed that their hbm.xml files were being ignored, so it seems like ignorant advice.) Due to poor formatting of the Hibernate documentation, I didn’t see a critical addendum:
When
https://docs.hibernate.org/orm/7.2/userguide/html_single/#settings-hibernate.archive.autodetection.classdiscovery is enabled, the modulehibernate-scan-jandexmust be added as a dependency, or some other implementation of the serviceScannerFactorymust be made available.
Sure enough, once I added hibernate-scan-jandex as a dependency to my pom.xml (and re-enabled a previously failed attempt at adding <property name="hibernate.archive.autodetection" value="class" /> to persistence.xml), everything started to work again!
Thanks to dreamreal from the Libera.chat #java IRC channel for asking good questions and willingness to help.
Tags: error, Java, solved