Hibernate 6 issues with table name

Recently upgraded to Spring boot 3 and implicitly to hibernate 6.
One issue I am facing is that depending on the annotations on an Entity class, the table name is parsed differently.

For example I have this entity class

@Entity
@Table(name = Folder.TABLE_NAME)
@SecondaryTable(name = RelationView.TABLE_NAME, pkJoinColumns = @PrimaryKeyJoinColumn(name = "NODE"))
@JsonIgnoreProperties(ignoreUnknown = true)
public class Folder extends Entity<Folder, Integer> {

    public static final String TABLE_NAME_NO_QUOTES = "com.proj.db::base.folder";

    public static final String TABLE_NAME = "`" + TABLE_NAME_NO_QUOTES + "`";

    @Id
    @Column(name = "ENTITY_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ENTITY_SEQUENCE")
    @GenericGenerator(name = "ENTITY_SEQUENCE",
            strategy = ...SequenceStyleGenerator")
    private Integer folderId;
...other fields

When I try to start up the application it fails with:

Caused by: java.lang.IllegalStateException: PostInitCallback queue could not be processed...
        - PostInitCallbackEntry - Entity(com.backend.model.Folder) `sqmMultiTableMutationStrategy` interpretation
        - PostInitCallbackEntry - Entity(com.backend.model.Folder) `sqmMultiTableInsertStrategy` interpretation

	at org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess.executePostInitCallbacks(MappingModelCreationProcess.java:144)
	at org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess.execute(MappingModelCreationProcess.java:88)
	at org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess.process(MappingModelCreationProcess.java:40)
	at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.finishInitialization(MappingMetamodelImpl.java:201)
	at org.hibernate.internal.SessionFactoryImpl.initializeMappingModel(SessionFactoryImpl.java:319)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:269)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:431)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1455)
	at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:142)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
	... 54 more
	Suppressed: org.hibernate.HibernateException: Unable to parse object name: "com.proj.db::base.folder"
		at org.hibernate.boot.model.relational.QualifiedNameParser.parse(QualifiedNameParser.java:149)
		at org.hibernate.boot.model.relational.QualifiedNameParser.parse(QualifiedNameParser.java:199)
		at org.hibernate.dialect.temptable.TemporaryTable.<init>(TemporaryTable.java:83)
		at org.hibernate.dialect.temptable.TemporaryTable.createEntityTable(TemporaryTable.java:302)
		at org.hibernate.dialect.H2Dialect.getFallbackSqmInsertStrategy(H2Dialect.java:693)
		at org.hibernate.query.sqm.mutation.internal.SqmMultiTableMutationStrategyProviderStandard.createInsertStrategy(SqmMultiTableMutationStrategyProviderStandard.java:53)
		at org.hibernate.persister.entity.AbstractEntityPersister.interpretSqmMultiTableInsertStrategy(AbstractEntityPersister.java:4807)
		at org.hibernate.persister.entity.AbstractEntityPersister.lambda$prepareMappingModel$17(AbstractEntityPersister.java:4659)
		at org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess$PostInitCallbackEntry.process(MappingModelCreationProcess.java:246)
		at org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess.executePostInitCallbacks(MappingModelCreationProcess.java:106)
		... 64 more

If I remove the @GeneratedValue, @GenericGenerator and anything related to the @SecondaryTable annotation everything works fine.
I also have the physical naming strategy set up in my application.yaml.

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

From what I can tell looking in the hibernate code the issue comes from org.hibernate.dialect.temptable.TemporaryTable constructor, which from version 6.1.4 has changed the way it parses the table name to use QualifiedNameParser which is incompatible with our naming convention (we use a Hana database) and also seems to ignore the physical naming strategy property.

Has anyone encountered anything similar? Am I missing something? Is there a new property that I have missed?

If I remove the @GeneratedValue, @GenericGenerator and anything related to the @SecondaryTable annotation everything works fine.

That’s because by removing these annotations, inserts/updates/deletes for the entity will only touch a single table and hence there is no need for the temporary table strategy.

Using quotes should fix the problem though. If it doesn’t, please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) that reproduces the issue.

Adding quotes is not a solution. Already tried that, as per the example.
Opened an Issue: [HHH-16765] - Hibernate JIRA
PR: Hibernate 6 cannot parse table name by Ciully · Pull Request #276 · hibernate/hibernate-test-case-templates · GitHub

Thank you,
C. Mihai

1 Like