0

Wicket-1.5.3、Spring-3.1.1、Hibernate-4.1.1を使用してアプリケーションを開発しています。

実装したい

  • Open-Session-In-Viewパターン
  • トランザクションはアノテーションドリブンになり、
  • アプリケーションは、LazyInitializationExceptionをネットで取得する必要があります。
  • ネストされたモデルのデータベース更新操作は正しく実行する必要があります。

私は別々のレイヤー、ウェブ、データ、サービスなどを持っています。

最初に、web.xmlで定義されているopen-session-in-viewフィルターについて説明します。

<filter>
    <filter-name>openSessionInView</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/app/*</url-pattern>
</filter-mapping>

applicationContext.xmlには、次の構成があります。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/ems" />
    <property name="username" value="root" />
    <property name="password" value="admin" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>
    <property name="mappingDirectoryLocations" value="/WEB-INF/resources/mappings" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />   

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager" ref="transactionManager" />
    <property name="transactionAttributeSource">
        <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
    </property>
</bean>

<bean id="managerTemplate" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="interceptorNames">
        <list>
            <value>transactionInterceptor</value>
        </list>
    </property>
</bean>

<bean id="userDao" class="app.dev.ems.data.dao.impl.UserDaoImpl">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="userManager" parent="managerTemplate">
    <property name="target">
        <bean class="app.dev.ems.manager.impl.UserManagerImpl">
            <property name="userDao" ref="userDao" />
        </bean>
    </property>
</bean> 

* .hbm.xmlで定義されているデータモデルクラスは、プロキシベースです。

<class name="app.dev.ems.data.model.impl.User" table="USER" proxy="app.dev.ems.data.model.IUser">
    <id name="id" column="ID">
        <generator class="native"/>         
    </id>
    <property name="name" column="NAME" not-null="true" />
</class>

ここで、applicationConextで定義されたクラスについて説明します。

userDao:実際にはUserDaoImplです:

public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao {

    public UserDaoImpl() {
        super(User.class);
    }   
}

BaseDaoImplは、sessionFactoryの依存性注入が実際に行われる抽象クラスです。

public abstract class BaseDaoImpl<T extends Base> implements IBaseDao<T> {

    private Class<T> entityClass;
    private SessionFactory sessionFactory;

    public BaseDaoImpl(Class<T> entityClass) {
        super();
        this.entityClass = entityClass;
    }   

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @SuppressWarnings("unchecked")
    public List<T> getAll() {
        return getSessionFactory().getCurrentSession().createCriteria(entityClass).list();
    }

    public Integer save(T entity) {
        return (Integer) getSessionFactory().getCurrentSession().save(entity);
    }
}

ここで、このクラスについて質問があります。BaseDaoImplをHibernateDaoSupportで拡張した方がよいかどうか疑問に思いました。そうすると、saveメソッドの代替バージョンは次のようになります。

public Integer save(final T entity) {
    return getHibernateTemplate().execute(new HibernateCallback<Integer>() {

        @Override
        public Integer doInHibernate(Session session) throws HibernateException, SQLException {
            return (Integer) session.save(entity);
        }
    });
}

どちらがいいですか?

次に、インターフェイスIBaseDao:

public interface IBaseDao<T extends Base> extends ISupportSave<T, Integer> {

    List<T> getAll();
}

そしてISupportSave:

public interface ISupportSave<T extends Base, U extends Number> {

    U save(T entity);
}

UserDaoImplはIUserDaoを実装します。これは次のとおりです。

public interface IUserDao extends IBaseDao<User> {

}

次はサービスレイヤーで、userManagerについて説明している他のクラスの中で、トランザクションです。

@Transactional
public class UserManagerImpl extends BaseManagerImpl<User> implements IUserManager {

    @SuppressWarnings("unused")
    private IUserDao userDao;

    public void setUserDao(IUserDao userDao) {
        super.setEntityDao(userDao);
        this.userDao = userDao;
    }   
}

BaseManagerImplは、UserManagerImplによって拡張される抽象クラスです。

@Transactional
public abstract class BaseManagerImpl<T extends Base> implements IBaseManager<T> {

    private IBaseDao<T> entityDao;

    public void setEntityDao(IBaseDao<T> entityDao) {
        this.entityDao = entityDao;
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Integer save(T entity) {
        return entityDao.save(entity);
    }
}

以下はIBaseManagerです。

public interface IBaseManager<T extends Base> {

    Integer save(T entity);
}

そして、IUserManagerは次のとおりです。

public interface IUserManager extends IBaseManager<User> {

}

私はモデルクラスを与えませんでした。主に、IUserを実装してBaseを拡張するUserがあります。IUserはIBaseを拡張し、BaseはIBaseを実装します。

今、私は上記の設計が正しいかどうか、そしてそれが私の要件を満たすかどうか疑問に思いました。

どんな提案も私に非常に役立ちます。

ありがとう。

4

1 に答える 1

2
  1. Spring 3.1 では、HibernateTemplate は推奨されなくなりました。こちらをご覧ください

  2. プロジェクトの大まかなコンテキストしかないため、サービス/dao レイヤーの設計を評価するのに適した立場にありません。しかし、appfuse projectをご覧になることをお勧めします。そのソース コードから良いヒントが得られると確信しています。

于 2012-04-29T14:13:45.870 に答える