Alina Ricciuti (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=61fb92a...
) *updated* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiODkwYjVjYzRk...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16215?atlOrigin=eyJpIjoiODkwYj...
) HHH-16215 (
https://hibernate.atlassian.net/browse/HHH-16215?atlOrigin=eyJpIjoiODkwYj...
) Composite primary key @IdClass attribute mapping is borrowed from the first OneToMany
backref and cannot be set (
https://hibernate.atlassian.net/browse/HHH-16215?atlOrigin=eyJpIjoiODkwYj...
)
Change By: Alina Ricciuti (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=61fb92a...
)
Please find below the issue I have encountered during the migration from hibernate 5 to
hibernante 6.1.7.
My sample project is using Lombok / Spring Data; its datamodel is composed of :
* Buckets having Lines
{noformat}@Getter
@Setter
@Entity
@Table(name = "BUCKET")
@SequenceGenerator(name = "SEQ_BUCKET_ID", allocationSize = 10, sequenceName =
"SEQ_BUCKET_ID")
@IdClass(PkBucket.class)
public class Bucket {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"SEQ_BUCKET_ID")
private Long id;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "BUCKET_ID", referencedColumnName = "id", nullable
= false)
private List<Line> lines = new ArrayList<>();
}{noformat}
* Items having Lines
{noformat}@Getter
@Setter
@Entity
@Table(name = "LINE")
@SequenceGenerator(name = "SEQ_LINE_ID", allocationSize = 10, sequenceName =
"SEQ_LINE_ID")
@IdClass(PkLine.class)
public class Line {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_LINE_ID")
private Long id;
@ManyToOne(targetEntity = Item.class)
@JoinColumn(name = "ITEM_ID", referencedColumnName = "id", nullable =
false)
private Item item;
}{noformat}
* The Line class
{noformat}@Getter
@Setter
@Entity
@Table(name = "ITEM")
@SequenceGenerator(name = "SEQ_ITEM_ID", allocationSize = 10, sequenceName =
"SEQ_ITEM_ID")
@IdClass(PkItem.class)
public class Item {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ITEM_ID")
private Long id;
@OneToMany(mappedBy = "item", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Line> lines = new ArrayList<>();
}{noformat}
* The simplified Pk classes - they are all identical, as PkBucket here below
{noformat}@Getter
@Setter
public class PkBucket implements Serializable {
private Long id;
public PkBucket withId(Long id) {
this.id = id;
return this;
}
}{noformat}
My test is creating and updating some data :
{noformat} @Test
@Transactional
public void buckets_items_lines() {
// create some data
Session session = entityManager.unwrap(Session.class);
session.createNativeQuery("insert into ITEM (id) values
(100)").executeUpdate();
session.createNativeQuery("insert into ITEM (id) values
(101)").executeUpdate();
session.createNativeQuery("insert into BUCKET (id) values
(200)").executeUpdate();
session.createNativeQuery("insert into LINE (id, ITEM_ID, BUCKET_ID) values (300,
100, 200)").executeUpdate();
// move line from item to other item
Item item100 = itemRepository.findById(new PkItem().withId(100L)).get();
final Item item101 = itemRepository.findById(new PkItem().withId(101L)).get();
item100.getLines().forEach(line -> line.setItem(item101));
}{noformat}
The issue below occurs when tying to hydrate Item.lines:
{noformat}Could not set value of type [java.lang.Long] :
`com.example.demo.domain.issue2.PkBucket.id` (setter)
org.hibernate.PropertyAccessException: Could not set value of type [java.lang.Long] :
`com.example.demo.domain.issue2.PkBucket.id` (setter)
at app//org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:81)
at
app//org.hibernate.metamodel.mapping.internal.AbstractEmbeddableMapping.setValues(AbstractEmbeddableMapping.java:103){noformat}
Few remarks:
* As you can see in the stack attached, the Line property id is accessed through PkBucket
id instead of PkLine id.
* If I remove {{nullable = false}} from Bucket lines JoinColums the result is OK
* It I change the mapping to add and use a ManyToOne relationship in Line class to Bucket
entity the result is also OK
* If I use unique Pk class the issue persists : IllegalArgumentException: Can not set
java.lang.Long field
[com.example.demo.domain.issue2.Pk.id|http://com.example.demo.domain.issue2.Pk.id] to
com.example.demo.domain.issue2.Line
* If I force the Line class to extend the expected id class the result is OK but this is
not nice 🙂
{noformat}...
@IdClass(PkLine.class)
public class Line extends PkBucket {
...{noformat}
I have attached the full log; if needed, I can also share my sample project.
(
https://hibernate.atlassian.net/browse/HHH-16215#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16215#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#100216- sha1:64a4cf6 )