开发者

DAO scope in spring-hibernate multi-user web-app?

I actually saw this question, but couldn't get much from it, so I'll try to be more specific with mine.

I have BaseDAO class in my multi-user web-app that looks like this:

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开发者_StackOverflow 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);
}
}

It's basically wrapper around HibernateTemplate. All my other DAOs inherit this class and implement appropriate interfaces, which hold some additional methods (like getBySomeAttribute()). So basically these DAOs have only methods. Further more, I have service layer that wraps DAOs. That is, a service class can hold multiple DAOs, and method calls from service layer are intercepted with spring-AOP for auto commit/rollback (transaction demaracation). For example:

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();
    }
}

Config is as follows:

<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>

So, I'm wondering how should I scope DAO/Service beans for multi-user purposes? I am injecting service beans into prototype controllesrs for GUI. When I use this configuration (with scope="session"), I get error like:

Error creating bean with name 'modelService': java.lang.IllegalArgumentException setAttribute: Non-serializable attribute: modelDAO

I'd say that this is thrown from Tomcat's StandardSession.setAttribute(). From this I could conclude that my DAOs should implement Serializable, and what confuses me even more is that I saw exact same code that works without implementing Serializable...

If someone could enlighten me what is going on here, and how to scope DAOs and Services for this particular case, I'd be very grateful...


There is no need to make your DAOs session-scoped.

Though Hibernate session has a state, under properly configured transaction management its state is bound to transactions (i.e. different DAO methods called inside the same transactions share the same session, whereas the same method called from different transactions use different sessions).

So, your DAOs are effectively stateless, and should be singleton-scoped (i.e. default scope).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜