Rob Scala (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *created* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiY2YwY2MyZjIw...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-17049?atlOrigin=eyJpIjoiY2YwY2...
) HHH-17049 (
https://hibernate.atlassian.net/browse/HHH-17049?atlOrigin=eyJpIjoiY2YwY2...
) Extra records created for entities created in constructor (
https://hibernate.atlassian.net/browse/HHH-17049?atlOrigin=eyJpIjoiY2YwY2...
)
Issue Type: Bug Affects Versions: 6.3.0.CR1 Assignee: Unassigned Components:
hibernate-core Created: 08/Aug/2023 13:00 PM Environment: Hibernate 6.3.0.CR1
H2 database
bytecode enhancement on Priority: Major Reporter: Rob Scala (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
I have two cases where entities created in a constructor of another entity are persisted
in the next transaction, even after the entity is replaced upon loading from the database.
For example:
@Entity
public class Person {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
@OneToOne(orphanRemoval = true , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private ContactInfo contactInfo = new ContactInfo();
private String firstName;
...
}
In some conditions, when I load a Person object (entityManager.find), then set its
firstName and commit the transaction, the firstName is changed, but an extra ContactInfo
record is unexpectedly created. I expect the ContactInfo instance that was created in the
constructor to be discarded when the Person entity is loaded with a ContactInfo record
from the database. The database ends up with unreferenced records.
This only happens for me when using bytecode enhancement. I have two test cases that
reproduce this behavior.
One involves a bi-directional OneToOne relationship. Here is the repo:
git(a)github.com :robscala/extra_inserts_OneToOne_bi_test.git
@Entity public class Person {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
private String firstName;
@OneToOne(orphanRemoval= true , cascade={CascadeType.PERSIST, CascadeType.REMOVE},
fetch=FetchType.LAZY)
private LoginAccount loginAccount = new LoginAccount();
}
@Entity public class LoginAccount {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
private String name;
@OneToOne(orphanRemoval= true , cascade= CascadeType.ALL, fetch= FetchType.LAZY)
private AccountPreferences accountPreferences = new AccountPreferences();
@OneToOne(mappedBy = "loginAccount" )
private Person owner;
}
@Entity public class AccountPreferences {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private boolean open = false ;
}
In this case, after loading a Person and performing a transaction, an extra record in the
AccountPreferences table is created.
The other case involves a polymorphic class, Company. Here is the repo:
git(a)github.com :robscala/extra_inserts_polymorphic_test.git
@Entity
public class Person {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
private String firstName;
@OneToOne(orphanRemoval = true , cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private ContactInfo contactInfo = new ContactInfo();
@ManyToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
private Company company;
}
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name= "CompanyType" , discriminatorType=
DiscriminatorType.INTEGER)
public abstract class Company {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
protected long id;
@OneToOne(orphanRemoval= true , cascade=CascadeType.PERSIST, fetch=FetchType.LAZY)
private ContactInfo contactInfo = new ContactInfo();
}
@Entity
@DiscriminatorValue( "9" )
public class CustomerCompany extends Company {
private String zipCode;
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,
CascadeType.REMOVE})
private CustomerCompany parent;
}
In this case, after loading a Person and performing a transaction, an extra record in the
ContactInfo table is created.
(
https://hibernate.atlassian.net/browse/HHH-17049#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-17049#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#100233- sha1:7fb7fe8 )