Alina Ricciuti (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=61fb92a...
) *created* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiYzMyYjM0YTFh...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16493?atlOrigin=eyJpIjoiYzMyYj...
) HHH-16493 (
https://hibernate.atlassian.net/browse/HHH-16493?atlOrigin=eyJpIjoiYzMyYj...
) OneToManyCollectionPart doesn't disassemble properly embeddable IdClass (
https://hibernate.atlassian.net/browse/HHH-16493?atlOrigin=eyJpIjoiYzMyYj...
)
Issue Type: Bug Affects Versions: 6.2.0, 6.2.1 Assignee: Unassigned Components:
hibernate-core Created: 19/Apr/2023 06:08 AM Environment: Hibernate: 6.2.0.Final
Postgresql: 11
Spring Data JPA: 3.0.4
Spring Boot: 3.0.5
JDK: Oracle OpenJDK 17.0.2
OS: Windows 11 Priority: Major Reporter: Alina Ricciuti (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=61fb92a...
)
With
https://hibernate.atlassian.net/browse/HHH-16281 the disassembling of OneToMany
collections doesn’t work properly and renders the identifier object as a collection of
objects ( instead of provided identifier type).
Actually the identifier seems to be disassembled twice, first on
NonAggregatedIdentifierMappingImpl.getIdentifier for the Entity object and secondly on
AbstractEmbeddableMapping.dissamble of the identifier object.
As result, an IllegalArgumentException is thrown when setting the identifier values:
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing
field [private java.lang.Long com.example.demo.domain.issue.DoubleId.id] by reflection for
persistent property com.example.demo.domain.issue.DoubleId#id ( #id ) :
[Ljava.lang.Object;@cc46555
{{ at
app//org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:48)}}
{{ at
app//org.hibernate.metamodel.mapping.AttributeMapping.getValue(AttributeMapping.java:59)}}
{{ at
app//org.hibernate.metamodel.mapping.internal.AbstractEmbeddableMapping.breakDownJdbcValues(AbstractEmbeddableMapping.java:594)}}
{{ at
app//org.hibernate.metamodel.mapping.internal.NonAggregatedIdentifierMappingImpl.breakDownJdbcValues(NonAggregatedIdentifierMappingImpl.java:299)}}
{{ at
app//org.hibernate.metamodel.mapping.internal.OneToManyCollectionPart.breakDownJdbcValues(OneToManyCollectionPart.java:98)}}
{{ at app//org.hibernate.metamodel.mapping.ModelPart.decompose(ModelPart.java:194)}}
{{ at
app//org.hibernate.persister.collection.OneToManyPersister.applyDeleteRowRestrictions(OneToManyPersister.java:640)}}
{{ at
app//org.hibernate.persister.collection.mutation.DeleteRowsCoordinatorStandard.deleteRows(DeleteRowsCoordinatorStandard.java:97)}}
{{ at
app//org.hibernate.persister.collection.OneToManyPersister.deleteRows(OneToManyPersister.java:194)}}
{{ at
app//org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:83)}}
...
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field
com.example.demo.domain.issue.DoubleId.id to [Ljava.lang.Object;
...
{{ at java.base/java.lang.reflect.Field.get(Field.java:425)}}
{{ at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:44)}}
{{ ... 115 more}}
My sample project uses Lombok / Spring Data.
* a Content class with inverse OnToMany reference:
@Entity
@Getter
@Setter
public class Content {
@EmbeddedId
private PkComposite id;
private String name;
@OneToMany(cascade = ALL, orphanRemoval = true)
@JoinColumn(name = "ID_CONTENT", referencedColumnName = "ID")
private List<Detail> detailList = new ArrayList<>();
}
* its composite ID class:
@Getter
@Setter
public class PkComposite implements Serializable {
@Column(name = "ID")
private Long id;
public PkComposite withId(Long id) {
this.id = id;
return this;
}
}
* a Detail class using a composite key defined with @IdClass:
@Entity
@Getter
@Setter
@IdClass(DoubleId.class)
public class Detail {
@Id
private Long id;
@Id
private Long id2;
private String name;
}
* its composite key:
@Getter
@Setter
public class DoubleId implements Serializable {
private Long id;
private Long id2;
}
* the test that fails with the exception detailed above:
@Test
@Transactional
public void issue4_disassamble_idclass() {
// create some data
Session session = entityManager.unwrap(Session.class);
session.createNativeQuery("insert into CONTENT (ID, NAME) values (200,
'NAME for CONTENT 320')").executeUpdate();
session.createNativeQuery("insert into DETAIL (ID, ID2, NAME, ID_CONTENT)
values (300, 400, 'NAME for DETAIL 300', 200)").executeUpdate();
// Commit transaction
TestTransaction.flagForCommit();
TestTransaction.end();
TestTransaction.start();
Content content200 = contentRepository.findById(new
PkComposite().withId(200L)).orElse(null);
Assertions.assertNotNull(content200);
Assertions.assertNotNull(content200.getDetailList());
Assertions.assertEquals(1, content200.getDetailList().size());
// content200.getDetailList().clear();
content200.getDetailList().remove(content200.getDetailList().get(0));
Detail newDetail = new Detail();
newDetail.setId(301L);
newDetail.setId2(901L);
newDetail.setName("NAME for DETAIL 301");
content200.getDetailList().add(newDetail);
Content content200Upd = contentRepository.save(content200);
Assertions.assertEquals(1, content200Upd.getDetailList().size());
TestTransaction.flagForCommit();
TestTransaction.end();
TestTransaction.start();
}
I have attached the tests logs. If needed, I can share my sample project.
(
https://hibernate.atlassian.net/browse/HHH-16493#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16493#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100222- sha1:cb3bdf0 )