Skip to content

Make it easier to use the auto-configured EntityManagerFactoryBuilder with Hibernate-specific properties #15318

@petenattress

Description

@petenattress

This relates to #3654 - I was asked to open a new issue by @wilkinsona.

When I followed the guidance in the Spring Boot documentation on how to define two entity managers, the mappings for my original entity manager stopped working, with exceptions such as this:

Caused by: org.hibernate.MappingException: Unable to find column with logical name: some_id in some_table
	at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:858) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
...

As #3654 describes, this was due to the EntityManagerFactoryBuilder not containing the Spring naming_strategy properties which are populated by the auto-configuration when Boot creates the entity manager itself. This took me a while to get to the bottom of because the documentation does not point this out, in fact it kind of implies that the EntityManagerFactoryBuilder can be used to construct an entity manager in the same way the auto-configuration does.

For my use case, it would be useful if the EntityManagerFactoryBuilder contained the same set of properties created by the auto-configuration, especially to preserve the "clever" behaviour of the ddl-auto option being set differently for integration tests against an embedded database. As is, I am required to replicate this behaviour in my configuration class - I have done this for now by wiring in the properties that I could (this isn't identical to the auto-configuration, but it's close enough for my current needs):

@Bean
public LocalContainerEntityManagerFactoryBean myEntityManagerFactory(EntityManagerFactoryBuilder builder,
                                                                     DataSource dataSource,
                                                                     JpaProperties jpaProperties,
                                                                     HibernateProperties hibernateProperties) {
  HibernateSettings hibernateSettings = new HibernateSettings();

  return builder
      .dataSource(dataSource)
      .properties(hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), hibernateSettings))
      .packages(SomePackage.class)
      .persistenceUnit("someUnit")
      .build();
}

I understand that other use cases may not find the auto-population of properties useful, and that making such a change is probably not backwards compatible. If the change is not possible, I think the documentation should be updated to clarify the behaviour and ideally demonstrate how to work around it like in my example above. Perhaps as a compromise, there could be a nicer way of wiring in the result of the call to hibernateProperties.determineHibernateProperties, which I think is all I need.

Many thanks.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions