[JIRA] (HHH-16031) @ManyToMany with @JoinTable(inverseColumn = ...) and SortedSet may results in data loss
by Yoann Rodière (JIRA)
Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNDMyNTdlMDYz... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16031?atlOrigin=eyJpIjoiNDMyNT... ) HHH-16031 ( https://hibernate.atlassian.net/browse/HHH-16031?atlOrigin=eyJpIjoiNDMyNT... ) @ManyToMany with @JoinTable(inverseColumn = ...) and SortedSet may results in data loss ( https://hibernate.atlassian.net/browse/HHH-16031?atlOrigin=eyJpIjoiNDMyNT... )
Issue Type: Bug Affects Versions: 6.2.0.CR1 Assignee: Unassigned Components: hibernate-core Created: 12/Jan/2023 04:59 AM Priority: Major Reporter: Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
Affects ORM 6.2, but not 5.6, and (I think) not 6.1 either.
With the following model, attempting to remove one entity from the associations may result in the whole association being cleared.
@Entity(name = "containing" )
public static class ContainingEntity {
@Id
private Integer id;
@ManyToMany
@JoinTable(inverseJoinColumns = @JoinColumn(name = "inverse" ))
@SortNatural
private SortedSet<ContainedEntity> contained = new TreeSet<>();
public Integer getId() {
return id;
}
public void setId( Integer id) {
this.id = id;
}
public SortedSet<ContainedEntity> getContained() {
return contained;
}
public void setContained(SortedSet<ContainedEntity> contained) {
this.contained = contained;
}
}
@Entity(name = "contained" )
public static class ContainedEntity implements Comparable<ContainedEntity> {
@Id
private Integer id;
@ManyToMany(mappedBy = "contained" )
private List<ContainingEntity> containing = new ArrayList<>();
@Override
public int compareTo(ContainedEntity o) {
return getId() - o.getId();
}
public Integer getId() {
return id;
}
public void setId( Integer id) {
this.id = id;
}
public List<ContainingEntity> getContaining() {
return containing;
}
}
The problem appears to be in the SQL generated to clear the association, which completely ignores one side of the association:
13:52:57,376 DEBUG SQL:128 -
delete
from
containing_contained
where
containing_id=?
Whereas, when @JoinTable(inverseColumn) is not used, we get:
13:57:51,481 DEBUG SQL:128 -
delete
from
containing_contained
where
containing_id=?
and contained_id=?
Removing @JoinTable(inverseColumn = ...) , or moving from SortedSet to List , makes the problem disappear.
I will submit a reproducer in the comments.
( https://hibernate.atlassian.net/browse/HHH-16031#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16031#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=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100214- sha1:b03f6a4 )
1 year, 11 months