Join fetch a recursive relationship with EmbeddedId fetches wrong values
Description
is fixed by
Activity
Show:
Marco Belladelli April 18, 2023 at 9:57 AM
@Staffan Hörke I just updated the PR including this issue and your test case, after clearing it up a bit.
Stay tuned for updates on the fix.
Staffan Hörke April 18, 2023 at 9:52 AM
That’s great! Let me know if you are interested in the test case.
Marco Belladelli April 18, 2023 at 7:33 AM
This issue is very similar to https://hibernate.atlassian.net/browse/HHH-16363, after a quick test I confirmed that my PR for that issue also fixes the provided reproducer for this.
Fixed
Details
Details
Assignee
Marco Belladelli
Marco BelladelliReporter
Staffan Hörke
Staffan HörkeWorked in
Components
Fix versions
Affects versions
Priority
Created April 14, 2023 at 2:33 PM
Updated April 28, 2023 at 9:36 AM
Resolved April 26, 2023 at 11:56 AM
Given an entity with an embedded id and a recursive parent/child relationship, when querying a child instance with a join fetch to the parent, the child instance is populated with values that belongs to the parent instance.
Domain model
@Entity(name = "OrganizationWithEmbeddedId") public static class OrganizationWithEmbeddedId { @EmbeddedId private OrganizationId id; private String name; @ManyToOne private OrganizationWithEmbeddedId parent; @OneToMany(mappedBy = "parent") private Set<OrganizationWithEmbeddedId> children; public OrganizationWithEmbeddedId() { } public OrganizationWithEmbeddedId(OrganizationId id, String name) { this.id = id; this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public OrganizationWithEmbeddedId getParent() { return parent; } public void setParent(OrganizationWithEmbeddedId parent) { this.parent = parent; } public Set<OrganizationWithEmbeddedId> getChildren() { return children; } public void addChild(OrganizationWithEmbeddedId child) { if (children == null) { children = new HashSet<>(); } children.add(child); child.setParent(this); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OrganizationWithEmbeddedId that = (OrganizationWithEmbeddedId) o; return Objects.equals(id, that.id); } @Override public int hashCode() { return Objects.hash(id); } } @Embeddable public static class OrganizationId implements java.io.Serializable { private static final long serialVersionUID = 1L; @Column(name = "id") private long value; OrganizationId() { super(); } OrganizationId(long value) { this.value = value; } @Override public String toString() { return Long.toString(value); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OrganizationId that = (OrganizationId) o; return value == that.value; } @Override public int hashCode() { return Objects.hash(value); } }
Query
SELECT child FROM OrganizationWithEmbeddedId child JOIN FETCH child.parent WHERE child.id = :id
Result
The name property of the child instance is wrong. It has the value from the parent instance.