Fix for HHH-15759 broke our code
Description
Activity
Show:
Thomas Maurer April 11, 2024 at 10:10 AM
Hello Hibernate team
We had exactly the same problem when we migrated from Hibernate 5.6.7.Final to Hibernate 6.4.4.Final. I created a test case https://github.com/thomas-a-maurer/hibernate-test-case-templates/blob/main/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java that reproduces the error. It occurs when @CollectionTable is used cascaded across multiple entities and when the first collection is a set and not a list. In our opinion, sets should still be usable.
Automation for Jira August 3, 2023 at 5:01 AM
This issue is being closed by automation because a test case was requested, but not provided.
Andrea Boriero May 30, 2023 at 3:41 PM
Hi @Armen Chouldjian ,
please provide a test case so I can investigate the issue and work an a solution.
Thanks
Hello Hibernate Team,
My team and I have tried updating one of our main software projects from Hibernate 6.1.6 to 6.2.3 and we are unable to perform this upgrade due to an issue.
I have dug around enough, and have figured out the particular commit which is causing the issue.
The following code (hibernate-core/src/main/java/org/hibernate/mapping/Set.java:createPrimaryKey) needs to be looked at again and re-evaluated. I can provide a test-case in time, but as of right now, I do not have the test-case for you.
Here is a link to the particular commit which prevents us from upgrading to 6.2.3:
https://github.com/hibernate/hibernate-orm/commit/9341df0b8b5c1eee2a54efd9c2404d511490c836
Old (working) code from 6.1.6 tag:
void createPrimaryKey() { if ( !isOneToMany() ) { PrimaryKey pk = new PrimaryKey( getCollectionTable() ); pk.addColumns( getKey() );
New (broken) code from 6.2.3 tag:
void createPrimaryKey() { if ( !isOneToMany() ) { final Table collectionTable = getCollectionTable(); PrimaryKey pk = collectionTable.getPrimaryKey(); if ( pk == null ) { pk = new PrimaryKey( getCollectionTable() ); } pk.addColumns( getKey() );
It looks like dreab8 (Andrea Boriero) was trying to solve this particular Jira ID: https://hibernate.atlassian.net/browse/HHH-15759
Now I am not sure what the final fix should be, as reverting this commit may cause the original issue to break as well, however I am certain that current state the code is in is not the correct solution, as it causes major breakage in our (very) large project.
I would suggest playing around with a debugger to understand what is going on here.
Here’s my annotation:
@ElementCollection(fetch=FetchType.EAGER) @CollectionTable(name="interlocking",joinColumns=@JoinColumn(name="ctl_interlocking")) @Column(name="idn") private Set<Integer> ctlInterlockingInterlockingIdns = new HashSet<Integer>();
Here is the original exception I got:
Exception in thread "main" org.hibernate.MappingException: Foreign key (FKntc3fe3p6srhxyr5cbmvtcq40:contact_rail_at_location [interlocking])) must have same number of columns as the referenced primary key (interlocking [idn,ctl_interlocking]) at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:138) at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:119) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:2010) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1974) at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1818) at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:328) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1380) at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1451) at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:55) at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80) at g.b.c.p.JpaManager.<init>(JpaManager.java:122) at g.b.i.r.c.SvgLoad.<init>(SvgLoad.java:47) at g.b.i.r.c.SvgLoad.main(SvgLoad.java:65)
In our particular situation, we believe “idn” in this case should not be part of the referenced primary key (interlocking [idn,ctl_interlocking]). That is the mistake that is breaking the code.