]
Paul Benedict commented on HHH-2599:
------------------------------------
I wonder if the spec is incomplete? The spec says "the state of the given instance
will be re-read from the database" but a collection is not an entity. That's
probably the rub. In my situation, I thought refreshing the parent would grab any new
children. It turns out only to refresh the already loaded children. Doh!
Inconsistent behaviour with Cascade Refresh and lazy loaded
collections
-----------------------------------------------------------------------
Key: HHH-2599
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2599
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.2.3
Environment: 3.2.3, hsqldb/mysql
Reporter: Guy Chua
Attachments: cascadeTest.zip
According to the specs for session.refresh(), the state of the given instance will be
re-read from the database. I have a model 'Company' that has 2 lazy collections,
departments and employees.
Snippet of class Company
--------------------------------------------------------------------
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 1
private Set<Department> departments;
// POINT 1
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 2
private Set<Employee> employees;
// POINT 2
Snippet of class CascadeTestRunner
--------------------------------------------------------------------
public void doRefreshTest() {
session = sessionFactory.openSession();
session.getTransaction().begin();
Company loadedCompany = (Company)session.get(Company.class, companyId);
logger.debug(loadedCompany);
// session.refresh(loadedCompany); // POINT A
session.close();
Set<Department> loadedDepartments = loadedCompany.getDepartments();
logger.debug("TEST for LAZY DEPARTMENTS [START]");
for (Department tmpDepartment : loadedDepartments) {
logger.debug(tmpDepartment); // POINT B
}
logger.debug("TEST for LAZY DEPARTMENTS [END]");
Set<Employee> loadedEmployees = loadedCompany.getEmployees();
logger.debug("TEST for LAZY EMPLOYEES [START]");
for (Employee tmpEmployee : loadedEmployees) {
logger.debug(tmpEmployee); // POINT C
}
logger.debug("TEST for LAZY EMPLOYEES [END]");
}
If I run the above code, Point B will give me LazyInitializationException which is the
expected behavior. But if i uncomment POINT A, the LazyInitializationException happens at
POINT C instead of POINT B. Why should POINT B pass and POINT C fail?
Furthermore, with POINT A still uncommented and when I swap the position of POINT 1 with
POINT 2, the LazyInitializationException happens at POINT B now. I am wondering why the
position of the fields produce the exception at a different location.
What happens when a lazy collection annotated with CascadeType.Refresh is refreshed? I am
getting varied results, sometimes the collection is initialized, sometimes it is not. Is
it supposed to cascade the refresh to lazy elements in the first place?
Hope someone can shed some light on this.
Test Results
------------------
1. LazyInitializationException at POINT B
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 1
private Set<Department> departments;
// POINT 1
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 2
private Set<Employee> employees;
// POINT 2
// session.refresh(loadedCompany); // POINT A
logger.debug(tmpDepartment); // POINT B
logger.debug(tmpEmployee); // POINT C
2. LazyInitializationException at POINT C
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 1
private Set<Department> departments;
// POINT 1
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 2
private Set<Employee> employees;
// POINT 2
session.refresh(loadedCompany); // POINT A
logger.debug(tmpDepartment); // POINT B
logger.debug(tmpEmployee); // POINT C
2. LazyInitializationException at POINT B when positions of POINT 1 and POINT 2 are
swapped
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 2
private Set<Employee> employees;
// POINT 2
@OneToMany (mappedBy="company", cascade={ CascadeType.ALL }) // POINT 1
private Set<Department> departments;
// POINT 1
session.refresh(loadedCompany); // POINT A
logger.debug(tmpDepartment); // POINT B
logger.debug(tmpEmployee); // POINT C
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: