Tôi đang gặp phải một tình huống lạ khi tôi gặp vấn đề về tải chậm trên một trong các bộ điều khiển của mình. Lưu ý: Tôi đang sử dụng OpenSessionInViewInterceptor và đang chú thích lớp "dịch vụ" của tôi dưới dạng Giao dịch.Spring + Hibernate Lazy Load Error
Tôi có một vài cách khác nhau để tải đối tượng Person, một đối tượng bằng khóa và một bằng SSN. Về đối tượng con người của tôi, tôi có một bộ sưu tập các vai trò mà tôi tải xuống. Khi tôi tải bằng Khóa, tôi có thể truy cập danh sách như mong đợi. Khi tôi tải bằng SSN, tôi không thể truy cập danh sách.
Trong file cấu hình lớp dịch vụ của tôi, tôi đã thêm:
<tx:annotation-driven />
Đây là dịch vụ của tôi lớp mảnh mà tải các người bởi chính & SSN (Tôi biết điều này cần phải được trong một DAO/tái cơ cấu - đây code được thừa hưởng) - Lưu ý không phải phiên bản trong mảnh SSN cho phép tải - cả hai đều trong cùng một lớp:
@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;
}
sự khác biệt duy nhất trong bộ điều khiển của tôi là một tải bởi Key, và một tải bởi SSN. Đây là phần thích hợp của stacktrace:
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)
Ghi chú lẻ, nếu tôi tải người đó bằng khóa ngay sau khi tải bởi SSN, tôi có thể đọc bộ sưu tập mà không có vấn đề.
Edit:
Dưới đây là các bản ghi trước khi stack trace:
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!
Ngoài ra nếu gọi Hibernate.initialize (người) tôi vẫn nhận được ngoại lệ khởi tạo - ngay cả khi tôi làm điều đó trong lớp dịch vụ. – Scott