]
Julien Kronegg commented on HHH-1523:
-------------------------------------
BTW, you get the same error when doing the following HQL query twice and access to the
resulting list with a closed entity manager on Hibernate 3.3.1:
{code}
SELECT emp.department FROM Employee emp
{code}
Note that the generated SQL has an INNER JOIN as in the original issue description where
the HQL has a JOIN FETCH:
{code}
Hibernate: select employee0_.EMP_ID as EMP1_0_, department1_.DEPARTMENT_ID as
DEPARTMENT1_1_, employee0_.EMP_NAME as EMP2_1_0_, employee0_.DEPARTMENT_ID as
DEPARTMENT3_1_0_, department1_.NAME as NAME0_1_ from CACHE_ISSUE_EMP employee0_ inner join
CACHE_ISSUE_DEP department1_ on employee0_.DEPARTMENT_ID=department1_.DEPARTMENT_ID
{code}
The full pseudo-code is:
{code}
// step 1
EntityManager em = ... // build an EM from the EMF
Query q = em.createQuery("SELECT emp.department FROM Employee emp");
... // enable query cache for q
List<Department> list = q.getResultList();
em.close();
list.iterator().next().getId(); // no LIE raised here (expected result)
// step 2
EntityManager em = ... // build an EM from the EMF
Query q = em.createQuery("SELECT emp.department FROM Employee emp");
... // enable query cache for q
List<Department> list = q.getResultList();
em.close();
list.iterator().next().getId(); // LIE raised here!!! (unexpected result)
{code}
Steve: you may consider that behavior as a feature, but you should admit that it is not
very practical to ask yourself the question whether or not the generated SQL contains an
INNER JOIN. And if so, you should take care of the query cache result...
Rebuild fetches from query-cache hits
-------------------------------------
Key: HHH-1523
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1523
Project: Hibernate Core
Issue Type: New Feature
Components: caching (L2), core, query-criteria, query-hql, query-sql
Affects Versions: 3.0.5, 3.1
Reporter: Vikas Sasidharan
Attachments: cache_issue.log, QueryCacheIssue.zip
I have two domain objects - Employee and Department - and there is a 1:N relationship
from Department to Employee. When I join fetch an Employee with its Department, without
query cache enabled, it works fine. If I enable query cache for this same query, it bombs
with a LazyInitializationException.
Notes:
1) We get this error only if query cache is enabled.
2) We observed the same behaviour on both oscache and ehcache
3) Calling Hibernate.initialize() explicitly after firing the HQL seems to work. The
initialization does not fire an extra query though (it seems to pick it from the cache).
4) Setting "lazy=false" on the "many-to-one" mapping also works.
However, it wouldn't be acceptable.
Hibernate version: 3.0.5
Mapping documents:
Employee.hbm.xml
<hibernate-mapping>
<class name="tavant.platform.test.domain.Employee"
table="CACHE_ISSUE_EMP" lazy="true"
dynamic-update="true" dynamic-insert="true">
<cache usage="read-write" />
<id name="id" column="EMP_ID"
type="java.lang.Long"
access="field" unsaved-value="null">
<generator class="increment" />
</id>
<property name="name" type="string"
update="true"
insert="true" column="EMP_NAME"/>
<many-to-one name="department"
class="tavant.platform.test.domain.Department"
cascade="none" outer-join="auto" update="true"
insert="true" column="DEPARTMENT_ID"/>
</class>
</hibernate-mapping>
Department.hbm.xml
<hibernate-mapping>
<class name="tavant.platform.test.domain.Department"
table="CACHE_ISSUE_DEP"
lazy="true" dynamic-update="true"
dynamic-insert="true">
<cache usage="read-write" />
<id name="id" column="DEPARTMENT_ID"
type="java.lang.Long" access="field">
<generator class="increment"/>
</id>
<property name="name" type="java.lang.String"
update="false" insert="true" column="NAME"/>
<bag name="employees" lazy="true"
inverse="true" cascade="save-update"
access="field">
<cache usage="read-write"/>
<key column="DEPARTMENT_ID"/>
<one-to-many class="tavant.platform.test.domain.Employee"/>
</bag>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
public Employee getEmployeeWithDepartment(String empName) {
Session session = null;
try {
session = sessionFactory.openSession();
Employee emp = (Employee) session.createQuery(
"from Employee e join fetch e.department where e.name =
:name")
.setString("name", empName)
.setCacheable(true)
.uniqueResult();
// If I uncomment the next line, this works (even without
// firing an extra query)!
// Hibernate.initialize(emp.getDepartment());
return emp;
} finally {
if (session != null) {
session.close();
}
}
}
// First load employee and populate cahces
Employee emp = test.getEmployeeWithDepartment(EMPLOYEE_NAME);
System.out.println("Employee : " + emp + ", Employee.Department :
"
+ emp.getDepartment());
// Now try to make use of the cache
emp = test.getEmployeeWithDepartment(EMPLOYEE_NAME);
System.out.println("Employee : " + emp + ", Employee.Department :
"
+ emp.getDepartment());
Full stack trace of any exception that occurs:
org.hibernate.LazyInitializationException: could not initialize proxy - the owning
Session was closed
at
org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:53)
at
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
at
tavant.platform.test.domain.Department$$EnhancerByCGLIB$$67b26899.toString(<generated>)
at java.lang.String.valueOf(String.java:2131)
at java.lang.StringBuffer.append(StringBuffer.java:370)
at
tavant.platform.test.client.TestPrefetchRelationWithQueryCacheEnabled.main(TestPrefetchRelationWithQueryCacheEnabled.java:116)
Name and version of the database you are using:
We have noticed this on Oracle and HSQL
The generated SQL (show_sql=true):
#First read, goes fine
Hibernate: select employee0_.EMP_ID as EMP1_0_, department1_.DEPARTMENT_ID as
DEPARTMENT1_1_, employee0_.EMP_NAME as EMP2_1_0_, employee0_.DEPARTMENT_ID as
DEPARTMENT3_1_0_, department1_.NAME as NAME0_1_ from CACHE_ISSUE_EMP employee0_ inner join
CACHE_ISSUE_DEP department1_ on employee0_.DEPARTMENT_ID=department1_.DEPARTMENT_ID where
(employee0_.EMP_NAME=? )
#Prints the Employee and Department fine
Employee : [Id : 1, name : testEmployee], Employee.Department : [Id : 1, name :
testDepartment]
#Second read bombs!
org.hibernate.LazyInitializationException: could not initialize proxy - the owning
Session was closed
at
org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:53)
at
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:84)
at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:134)
[..]
Please have a look at the post [
http://forum.hibernate.org/viewtopic.php?t=955839] for
more details and follow ups.
Kindly help. I am attaching an Eclipse Project containing the TestCase. The main file is
TestPrefetchRelationWithQueryCacheEnabled.
Thanks,
Vikas
--
This message is automatically generated by JIRA.
For more information on JIRA, see: