【问题标题】:DAO scope in spring-hibernate multi-user web-app?春季休眠多用户网络应用程序中的DAO范围?
【发布时间】:2011-03-15 13:50:02
【问题描述】:

我实际上看到了this question,但无法从中得到太多,所以我会尝试更具体地介绍我的。
我的多用户网络应用中有 BaseDAO 类,如下所示:

public abstract class BaseDAO<GenType>
{
private HibernateOperations hibernateTemplate;

protected BaseDAO() {}
protected HibernateOperations getHibernateTemplate() {
    return hibernateTemplate;
}
public void setHibernateTemplate(HibernateOperations hibernateTemplate) {
    this.hibernateTemplate = hibernateTemplate;
}
protected void initialize(final Object proxy) throws DataAccessException {
    hibernateTemplate.initialize(proxy);
}
public GenType merge(GenType entity) throws DataAccessException {
    return (GenType)hibernateTemplate.merge(entity);
}
protected void persist(GenType entity) throws DataAccessException {
    hibernateTemplate.persist(entity);
}
public void refresh(GenType entity) throws DataAccessException {
    hibernateTemplate.refresh(entity);
}
public void save(GenType entity) throws DataAccessException {
    hibernateTemplate.save(entity);
}
public void saveOrUpdate(GenType entity) throws DataAccessException {
    hibernateTemplate.saveOrUpdate(entity);
}
public void update(GenType entity) throws DataAccessException {
    hibernateTemplate.update(entity);
}
public void delete(GenType entity) throws DataAccessException {
    hibernateTemplate.delete(entity);
}
protected void deleteAll(Collection<GenType> entities) throws DataAccessException {
    hibernateTemplate.deleteAll(entities);
}
protected GenType get(Class<GenType> entityClass, Serializable id) throws DataAccessException {
    return (GenType)hibernateTemplate.get(entityClass, id);
}
}

它基本上是 HibernateTemplate 的包装。我所有的其他 DAO 都继承了这个类并实现了适当的接口,这些接口包含一些额外的方法(如 getBySomeAttribute())。所以基本上这些 DAO 有 only 方法。此外,我还有包装 DAO 的 service 层。也就是说,一个服务类可以容纳多个DAO,来自服务层的方法调用被spring-AOP拦截,用于自动提交/回滚(事务分界)。例如:

public class ModelDAO extends BaseDAO<Model> implements IModelDAO
{
    @Override
    public Model getNew() {
        return new Model();
    }

    @Override
    public List<Model> getBySomeAttr() {
        DetachedCriteria criteria;
        // define some criteria
        return getHibernateTemplate().findByCriteria(criteria);
    }
}

...

public class ModelService
{
    private ModelDAO modelDAO;
    private ElementDAO elementDAO;
    // GET/SET for model and user DAO

    public void doSomethingWithModel() {

        modelDAO.doSomething();
        elementDAO.doSomethingElse();
    }
}

配置如下:

<bean id="hibernateTemplate2" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory2" />
    <property name="maxResults" value="3000" />
</bean>

<!-- DAO -->
<bean id="baseDAO" abstract="true" 
    class="org.irvas.backend.dao_implement.BaseDAO" scope="session">
    <property name="hibernateTemplate" ref="hibernateTemplate2" />
</bean>
<bean id="modelDAO" 
    class="org.irvas.backend.dao_implement.ModelDAOImplement" 
    parent="baseDAO" scope="session">
</bean>
<bean id="elementDAO" 
    class="org.irvas.backend.dao_implement.ElementDAOImplement" 
    parent="baseDAO" scope="session">
</bean>

<!-- Service -->
<bean id="modelService" 
    class="org.irvas.backend.service_implement.ModelServiceImplement" scope="session">
    <property name="modelDAO" ref="modelDAO" />
    <property name="elementDAO" ref="elementDAO" />
</bean>
<bean id="elementService" 
    class="org.irvas.backend.service_implement.ElementServiceImplement" scope="session">
    <property name="elementDAO" ref="elementDAO" />
</bean>

所以,我想知道我应该如何将 DAO/Service bean 范围限定为多用户用途?我将服务 bean 注入到 GUI 的 prototype 控制器中。 当我使用此配置时(使用 scope="session"),我收到如下错误:

创建名为“modelService”的 bean 时出错:java.lang.IllegalArgumentException setAttribute:不可序列化的属性:modelDAO

我会说这是从 Tomcat 的 StandardSession.setAttribute() 抛出的。由此我可以得出结论,我的 DAO 应该实现 Serializable,而更让我困惑的是,我看到了完全相同的代码,在没有实现 Serializable 的情况下也能工作......

如果有人能告诉我这里发生了什么,以及如何针对这种特殊情况确定 DAO 和服务的范围,我将不胜感激......

【问题讨论】:

    标签: hibernate spring


    【解决方案1】:

    无需将您的 DAO 设置为会话范围。

    虽然 Hibernate 会话有一个状态,但在正确配置的事务管理下,它的状态绑定到事务(即在相同事务中调用的不同 DAO 方法共享相同的会话,而从不同事务调用的相同方法使用不同的会话)。

    因此,您的 DAO 实际上是无状态的,并且应该是单例范围的(即默认范围)。

    【讨论】:

    • 嗯,我也是这么想的,但我需要一些确认。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多