Troubleshooting Hibernate SessionFactory

My, that’s a snappy title!

I’m still having loads of problems describing the relationships (@OneToMany, @ManyToOne and @OneToOne) between @Entity objects in my Moodle project.

I did a standard install of Moodle to allow it to create the database. I’m now in the process of annotating/modifying the Groovy classes to represent the database. For those unfamiliar with Moodle, it should be noted that the tables created don’t have foreign key constraints. I can only imagine this is done to make the install process work with databases that don’t support the concept.

When I created the @Entity classes I tried to group them into logical packages. This allows me to introduce them gradually by changing the entity-scan.packages entry in application.yml. At the moment only the config package is enable and it works, though it’s only three tables and they have no relationships. As soon as I include a second package I get the session factory error noted in the previous post.

In trying to understand what was failing I enabled trace logging of the org.hibernate.cfg class:

<logger name="org.hibernate.cfg" level="trace"/>

When only the config package is enabled I see this line, which is missing when other packages are enabled.

org.hibernate.cfg.Settings - SessionFactory name : default

When other packages are enabled I see this line in the log:

Binding column: Ejb3JoinColumn{logicalColumnName='null', referencedColumn='null', mappedBy='null'}

Dumb Error Message

I’ve recently been working on a project (in my own time, open source, but we need it at work) to provide a foundation API for Moodle. (Yes, there is an API already, and I’m told it’s pretty good, but it doesn’t quite cover our needs. Plus it’s written in PHP and I don’t do PHP – scratch your own itch!) I’m coding the system in Micronaut because it rocks.

The big, boring piece of this task is mapping the database tables to @Entity classes. I semi-automated as much of this as I could and now I’m working through adding in the relationships.

Once I’d done a few classes I decided I’d test a simple endpoint, nothing beats seeing code working. Instead I got this error:

Internal Server Error: Failed to inject value for parameter [sessionFactory] of class: io.micronaut.transaction.hibernate5.HibernateTransactionManager

Message: No bean of type [org.hibernate.SessionFactory] exists for the given qualifier: @Named('default'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
Path Taken: new HibernateTransactionManager([SessionFactory sessionFactory],DataSource dataSource,Interceptor entityInterceptor)

Annoying! I figured I must have configured something incorrectly. I checked other projects. I enabled trace logging as suggested. I left it for the night and came back to it fresh the following day. I even created a very simple Groovy/JPA reference project so I could compare settings.

I’ve put the entity classes into different packages, just to group them by purpose. So the packages bit of the application.yml file is quite long. I thought perhaps I’d configured it incorrectly, so I commented out all but one line. Aha! I was then able to make calls to the endpoint and get data back.

In conclusion then, it seems that if the model in code doesn’t accurately represent the underlying database then this is the error message that one gets back.