org.hibernate.LazyInitializationException:无法初始化代理 - 再没有会话

时间:2012-11-23 09:16:56

标签: spring hibernate jsf-2

我知道我的问题非常奇怪且难以理解

我创建了一些项目结构。但每次我遇到could not initialize proxy - No session againNot serializable exception

等不同问题时

我想得到一些建议或帮助。我尝试使用注释transactional而我不理解在哪种情况下我应该使用implements Serializable。当然,我知道如果我想使用带有视图范围的bean,我应该使用客户端保存方法,而bean应该是可执行的。如果我使用其他非原始字段,它也应该是可序列化的。这意味着在IDao和ITestSystemService这两个接口中使用inmplenets Serializable没什么不好。

我的通用DAO

public interface IDao<T> extends Serializable{
    List<T> getAll() throws DAOException;
    T get(Long id) throws DAOException;
}

DAO实施

@Repository("subjectDAO")
@Scope("prototype")
public class SubjectHibernateDAO implements ISubjectDAO{

    private static final long serialVersionUID = 1L;

    private static final Logger logger = Logger.getLogger(SubjectHibernateDAO.class);

    @Autowired
    private SessionFactory hibernateSessionFactory;
    //getter and setter

    @SuppressWarnings("unchecked")
    @Override
    public List<Subject> getAll() throws DAOException {
        Session session = hibernateSessionFactory.getCurrentSession();

        Transaction transaction = null;
        List<Subject> subjectList = null;
        try{
            transaction = session.beginTransaction();
            subjectList = session.getNamedQuery(GET_ALL_SUBJECTS_NAME_QUERY).list();
            transaction.commit();
        }  catch (HibernateException e) {
            if (transaction != null)
                transaction.rollback();
            logger.error(SQL_EXCEPTION_IN_QUERY, e);
            throw new DAOException(SQL_EXCEPTION_IN_QUERY, e);
        }
        return subjectList;
    }

// Generic service interface
public interface ITestSystemService<T> extends Serializable{

    List<T> getAll() throws DAOException;
}

//Service realization
@Service("subjectService")
@SessionScoped
public class SubjectServiceImpl implements ISubjectService{

    private static final long serialVersionUID = 1L;

    @Autowired
    @Qualifier("subjectDAO")
    private IDao<Subject> subjectDAO;

    public void setSubjectDAO(IDao<Subject> subjectDAO) {
        this.subjectDAO = subjectDAO;
    }

    @Override
    public List<Subject> getAll() throws DAOException {
        return subjectDAO.getAll();
    }

}

在具有视图范围的我的JSF bean控制器中,我每次都遇到此结构的问题。

我的申请结构应该改变什么?

1 个答案:

答案 0 :(得分:1)

我会对您所写的内容进行以下更改:

<强> SubjectServiceImpl

  • 这可能是单例作用域 - 服务没有状态。
  • 你不需要主题DAO的setter(我会使用构造函数注入并使subjectDAO最终。
  • 创建getAll方法@Transaction(正如您在问题中所提到的那样) - 这将确保Spring将Hibernate会话绑定到执行线程。然后可以使用SessionFactory#getCurrentSession()。

<强> SubjectHibernateDAO

  • 删除与交易有关的代码,例如transaction = session.beginTransaction()。会话的提供将由您的服务方法上的@Transactional注释处理。
  • 删除所有回滚代码
  • 使DAO单例作用域 - 再次没有状态。它应该取决于最终的SessionFactory变量。
  • 通过构造函数注入SessionFactory(字段注入不是很好)。

完成上述所有操作后,您可能会发现问题消失了(从您的问题来看,实际问题并不明显)。您的代码最大的问题是使用SessionFactory#getCurrentSession()混合的手动事务。

您尚未提供Spring配置,但要使用@Transactional,您需要在spring中启用事务代理行为。您可以使用@EnableTransactionManagement在