Join fetch a recursive relationship with EmbeddedId fetches wrong values

Description

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.

Web links

Activity

Show:

Marco Belladelli April 18, 2023 at 9:57 AM

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

Assignee

Reporter

Worked 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