Область применения DAO в многопользовательском веб-приложении Spring-Hibernate? - PullRequest
3 голосов
/ 15 марта 2011

Я на самом деле видел этот вопрос , но многого от него не получилось, поэтому постараюсь быть более конкретным с моим.
У меня в многопользовательском веб-приложении есть класс 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 имеют только методы. Более того, у меня есть слой service , который охватывает DAO. Таким образом, класс обслуживания может содержать несколько 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 для многопользовательских целей? Я внедряю служебные компоненты в прототип контроллеров для графического интерфейса. Когда я использую эту конфигурацию (с scope = "session"), я получаю сообщение об ошибке, например:

Ошибка создания бина с именем 'modelService': java.lang.IllegalArgumentException setAttribute: несериализуемый атрибут: modelDAO

Я бы сказал, что это выбрасывается из Tomcat StandardSession.setAttribute (). Из этого я могу сделать вывод, что мои DAO должны реализовывать Serializable, и что меня еще больше смущает, так это то, что я видел точно такой же код, который работает без реализации Serializable ...

Если бы кто-то мог объяснить мне, что здесь происходит, и как настроить DAO и службы для этого конкретного случая, я был бы очень признателен ...

1 Ответ

3 голосов
/ 15 марта 2011

Нет необходимости устанавливать область видимости для ваших DAO.

Хотя сеанс Hibernate имеет состояние, при правильно настроенном управлении транзакциями его состояние связано с транзакциями (т. Е. Разные методы DAO, вызываемые внутри одних и тех же транзакций, используют один и тот же сеанс, тогда как один и тот же метод, вызываемый из разных транзакций, использует разные сеансы). 1003 *

Таким образом, ваши DAO фактически не имеют состояния и должны иметь одну область действия (т. Е. Область действия по умолчанию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...