[JIRA] (HHH-16447) Lazy load of collection fails after EntityManager.refresh
by Rob Scala (JIRA)
Rob Scala ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiMzViNzliNzBm... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiMzViNz... ) HHH-16447 ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiMzViNz... ) Lazy load of collection fails after EntityManager.refresh ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiMzViNz... )
Change By: Rob Scala ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
I have a schema that includes two polymorphic entity classes using the join strategy.
When I call EntityManager.refresh on one of the subclasses a lazy collection in its superclass fails to work. Specifically, when I try to get a record from that collection, I get this exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.hibernate.bugs.Company.people: could not initialize proxy - no Session
The failure happens whether or not I include CascadeType.REFRESH on the collection.
Here is a picture of the schema:
!Hibernate_refresh_lazy.png|width=721,height=331!
Here is the essential source code:
{noformat}@Entity
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name="CompanyType", discriminatorType= DiscriminatorType.INTEGER)
public abstract class ComputerSystem {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
@ManyToOne
@JoinColumn(name = "OWNER_ID", foreignKey = @ForeignKey())
protected Company owner = null;
public void setOwner(Company owner) {
this.owner = owner;
}
}
@Entity
@DiscriminatorValue("2")
public class ManufacturerComputerSystem extends ComputerSystem {
}
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name="CompanyType", discriminatorType= DiscriminatorType.INTEGER)
public abstract class Company {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
protected long id;
@OneToMany(mappedBy="company", orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private List<Person> people = new ArrayList<>();
public List<Person> getPeople() {
return people;
}
public void addPerson(Person person) {
people.add(person);
person.setCompany(this);
}
}
@Entity
@DiscriminatorValue("1")
public class ManufacturerCompany extends Company {
@OneToOne(orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name = "COMPUTERSYSTEM_ID", foreignKey = @ForeignKey())
private ManufacturerComputerSystem computerSystem;
public void setComputerSystem(ManufacturerComputerSystem computerSystem) {
this.computerSystem = computerSystem;
computerSystem.setOwner(this);
}
}
@Entity
public class Person {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
private String firstName;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID", foreignKey = @ForeignKey())
private Company company;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setCompany(Company company) {
this.company = company;
}
}
public class JPAUnitTestCase {
@Before
public void init() {
// Details omitted for brevity
}
@Test
public void refresh_test() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
ManufacturerCompany manufacturerCompany = entityManager.find(ManufacturerCompany.class, 1L);
entityManager.refresh(manufacturerCompany);
List<Person> people = manufacturerCompany.getPeople();
Person person1 = people.get(0); // <-- This is where it fails.
String newFirstName = "name1".equals(person1.getFirstName()) ? "name2" : "name1";
entityManager.getTransaction().begin();
person1.setFirstName(newFirstName);
entityManager.getTransaction().commit();
assertEquals("Get latest name", newFirstName, person1.getFirstName());
}
}{noformat}
Here is a project that reproduces the problem (it is also attached) :
[https://github.com/robscala/Hibernate_lazy_load_collection_fails|https://...]
( https://hibernate.atlassian.net/browse/HHH-16447#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16447#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#100221- sha1:8f8083a )
3 years
[JIRA] (HHH-16447) Lazy load of collection fails after EntityManager.refresh
by Rob Scala (JIRA)
Rob Scala ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiZTM0YzBmN2Qw... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiZTM0Yz... ) HHH-16447 ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiZTM0Yz... ) Lazy load of collection fails after EntityManager.refresh ( https://hibernate.atlassian.net/browse/HHH-16447?atlOrigin=eyJpIjoiZTM0Yz... )
Issue Type: Bug Affects Versions: 6.2.0.CR4 Assignee: Unassigned Attachments: Hibernate_refresh_lazy.png Components: hibernate-core Created: 06/Apr/2023 13:09 PM Environment: H2 database 2.1.214
Hibernate 6.2.0.CR4 Priority: Major Reporter: Rob Scala ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
I have a schema that includes two polymorphic entity classes using the join strategy.
When I call EntityManager.refresh on one of the subclasses a lazy collection in its superclass fails to work. Specifically, when I try to get a record from that collection, I get this exception:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.hibernate.bugs.Company.people: could not initialize proxy - no Session
The failure happens whether or not I include CascadeType.REFRESH on the collection.
Here is a picture of the schema:
Here is the essential source code:
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name="CompanyType", discriminatorType= DiscriminatorType.INTEGER)
public abstract class ComputerSystem {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
@ManyToOne
@JoinColumn(name = "OWNER_ID", foreignKey = @ForeignKey())
protected Company owner = null;
public void setOwner(Company owner) {
this.owner = owner;
}
}
@Entity
@DiscriminatorValue("2")
public class ManufacturerComputerSystem extends ComputerSystem {
}
@Entity
@Inheritance(strategy= InheritanceType.JOINED)
@DiscriminatorColumn(name="CompanyType", discriminatorType= DiscriminatorType.INTEGER)
public abstract class Company {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
protected long id;
@OneToMany(mappedBy="company", orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
private List<Person> people = new ArrayList<>();
public List<Person> getPeople() {
return people;
}
public void addPerson(Person person) {
people.add(person);
person.setCompany(this);
}
}
@Entity
@DiscriminatorValue("1")
public class ManufacturerCompany extends Company {
@OneToOne(orphanRemoval=true, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name = "COMPUTERSYSTEM_ID", foreignKey = @ForeignKey())
private ManufacturerComputerSystem computerSystem;
public void setComputerSystem(ManufacturerComputerSystem computerSystem) {
this.computerSystem = computerSystem;
computerSystem.setOwner(this);
}
}
@Entity
public class Person {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
private String firstName;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "COMPANY_ID", foreignKey = @ForeignKey())
private Company company;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setCompany(Company company) {
this.company = company;
}
}
public class JPAUnitTestCase {
@Before
public void init() {
// Details omitted for brevity
}
@Test
public void refresh_test() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
ManufacturerCompany manufacturerCompany = entityManager.find(ManufacturerCompany.class, 1L);
entityManager.refresh(manufacturerCompany);
List<Person> people = manufacturerCompany.getPeople();
Person person1 = people.get(0); // <-- This is where it fails.
String newFirstName = "name1".equals(person1.getFirstName()) ? "name2" : "name1";
entityManager.getTransaction().begin();
person1.setFirstName(newFirstName);
entityManager.getTransaction().commit();
assertEquals("Get latest name", newFirstName, person1.getFirstName());
}
}
Here is a project that reproduces the problem:
https://github.com/robscala/Hibernate_lazy_load_collection_fails
( https://hibernate.atlassian.net/browse/HHH-16447#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16447#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#100221- sha1:8f8083a )
3 years