0

我知道我的问题很奇怪很难理解

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

我想得到一些建议或帮助。我尝试使用注释transactional,但我不明白在哪种情况下我应该使用implements Serializable. 当然,我知道如果我想使用具有视图范围的 bean,我应该使用客户端保存方法,并且 bean 应该是 implenebts seriailzable。如果我使用其他非原始字段,它也应该是可序列化的。这意味着在接口 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 控制器中,我每次都会遇到这种结构的问题。

我应该对我的应用程序结构进行哪些更改?

4

1 回答 1

1

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

主题服务实现

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

主题HibernateDAO

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

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

您尚未提供 Spring 配置,但要使用 @Transactional,您需要在 Spring 中启用事务代理行为。您可以在 xml 中使用 @EnableTransactionManagement 和使用注释来执行此操作。

于 2012-11-23T16:41:03.417 回答