我遇到了一個奇怪的情況,在我的一個控制器上發生延遲加載問題。 注意:我正在使用OpenSessionInViewInterceptor,並將我的「服務」層註釋爲Transactional。Spring + Hibernate懶惰加載錯誤
我有幾種不同的方法來加載一個Person對象,一個是它的密鑰,另一個是它的SSN。在我的人物對象上,我收集了一些我懶洋洋地加載的角色。當我通過鍵加載時,我可以按照預期訪問列表。當我通過SSN加載時,我無法訪問列表。
在我的服務層配置文件我已經加入:
<tx:annotation-driven />
這裏是通過加載重點& SSN的人(我知道這需要在DAO /重組一個我的服務層片 - 這被繼承代碼) - 注意既不版本的SSN件允許裝載 - 無論是在同一個類:
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public Person loadPersonByKey(final Person.Key personKey) {
Assert.notNull(personKey);
return (Person) getHibernateTemplate().get(Person.class, personKey);
}
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public Person findPersonBySsn(final SocialSecurityNumber ssn) {
@SuppressWarnings("unchecked")
//List<Person> results = getHibernateTemplate().findByNamedParam("from core.model.entities.Person as person where ssn = :ssn", "ssn", ssn);
Criteria crit = getSession().createCriteria(Person.class);
crit.add(Restrictions.eq("ssn", ssn));
List<Person> results = crit.list();
int size = results.size();
Person returnPerson = ((size != 0) ? (Person) results.get(0) : null);
return returnPerson;
}
唯一的區別在我的控制器是一個關鍵負載和一個負載的SSN。這裏是堆棧跟蹤的相關部分:
SEVERE: Servlet.service() for servlet springmvc threw exception
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: core.model.entities.Person.memberships, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.readElementByIndex(AbstractPersistentCollection.java:176)
at org.hibernate.collection.PersistentMap.get(PersistentMap.java:169)
at core.model.entities.Person.getMemberships(Person.java:870)
at core.springmvc.controllers.find.FindController.defaultAction(FindController.java:164)
奇注意,如果我用SSN加載後立即加載關鍵的人,我能讀集合沒有問題。
編輯:
以下是前堆棧跟蹤日誌:
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils CV#905cde28-e60c-4331 P#75004 - Resetting read-only flag of JDBC Connection [Transaction-aware proxy for target Connection [jdbc:oracle:thin:@(description=(address_list=(address=(host=127.0.0.1)(protocol=tcp)(port=11523))(load_balance=yes)(failover=yes))), UserName=USER_NAME, Oracle JDBC driver]]
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.impl.SessionImpl CV#905cde28-e60c-4331 P#75004 - disconnecting session
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.jdbc.ConnectionManager CV#905cde28-e60c-4331 P#75004 - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils CV#905cde28-e60c-4331 P#75004 - Returning JDBC Connection to DataSource
2011-08-02 13:29:32,415 [http-8080-1] DEBUG org.hibernate.jdbc.ConnectionManager CV#905cde28-e60c-4331 P#75004 - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
此外,如果調用Hibernate.initialize(person),我仍然會得到初始化異常 - 即使我在服務層中這樣做。 – Scott