内部类中的Hibernate会话

eug*_*ied 6 java spring annotations hibernate inner-classes

我在使用spring session factory在hibernate上获取anonymus内部类的会话时遇到问题.这是代码:

public class DomainDaoImpl extends BasicDaoImpl<Domain> implements Iterable<Collection<Domain>> {

...

@Override
public Iterator<Collection<Domain>> iterator() {
    return (new Iterator<Collection<Domain>>() {
        private int counter = 0;
        public static final int LIMIT = 100;

        ...

        @Override
        @Transactional(readOnly = true)
        public Collection<Domain> next() {
            final Criteria criteria = getCurrentSession().createCriteria(Domain.class);
            final LinkedHashSet<Domain> result = new LinkedHashSet<Domain>();

            List resultList = null;
            while (!(resultList = criteria.list()).isEmpty()) {
                criteria.setFirstResult((counter++ * LIMIT) + 1);
                criteria.setMaxResults(LIMIT);
                result.addAll(resultList);
            }
            return result;
        }

        ...
    });
Run Code Online (Sandbox Code Playgroud)

问题是org.hibernate.HibernateException:找不到当前线程的会话, 这通常发生在DAO方法不在事务中时.那么如何让它与内部类一起工作呢?

Jig*_*ekh 1

我认为@Transactional(readOnly = true)在内部类级别定义,Spring将无法检测和应用事务方面。所以它肯定不会起作用。

但我认为如果你写下面的东西可能不能100%确定(我怀疑一旦你调用迭代器方法事务就关闭了)

@Override
@Transactional(readOnly = true)
public Iterator<Collection<Domain>> iterator() {
...
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是让调用者负责事务或编写包装方法,然后将事务应用于该方法iterator()getAllDomain()

有效的解决方案(评论中提到)

可能你可以在 getCurrentSession() 中做一些修补,例如 sessionFactory 中的 getCurrentSession() 如果不可用,则使用 openSession(),当然,如果新会话打开,你必须手动关闭它。