2012-04-29 2 views
0

Я разрабатываю приложение с Wicket-1.5.3, Spring-3.1.1 и Hibernate-4.1.1.Выполнение транзакции с аннотацией в Open-Session-In-View с использованием Spring 3 и Hibernate 4

Я хочу осуществить

  • Open-Session-In-View Pattern где
  • сделка будет Driven аннотаций и
  • Заявка должна чистая получить любую LazyInitializationException, также
  • базы данных операции обновления для вложенных моделей должны выполняться правильно.

У меня есть отдельные слои, веб-данные, сервис и т.д.

Сначала я хочу заявить открытый сеанс-за просмотр фильтра определяется в web.xml:

<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? Если я это сделаю, альтернативная версия метода сохранения будет:

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

} 

Я не дал модельные классы. В основном у меня есть User, который реализует IUser и расширяет Base. IUser по очереди расширяет IBase, а также Base реализует IBase.

Теперь мне было интересно, правильно ли выполнено это проектирование и выполнит ли оно мое требование или нет.

Любое предложение будет очень полезно для меня.

Спасибо.

ответ

2
  1. HibernateTemplate больше не рекомендован весной 3.1. См. here

  2. Я не в состоянии оценить ваш дизайн уровня обслуживания/dao, так как существует только грубый контекст вашего проекта. Но я предлагаю вам взглянуть на appfuse project, я уверен, что вы получите хорошие подсказки из исходного кода.

+0

Спасибо за ответ и благодарность за указание, что Hibernatemplate не рекомендуется. Так можно ли использовать getSessionFactory(). GetCurrentSession() для получения сеанса, а затем продолжить? Также это моя полная структура проекта, которую я дал, так как я только начал ее. :) –

+0

Да, безопасно использовать getSessionFactory(). GetCurrentSession(). Поиграй с этим. :-) – Cole

Смежные вопросы