gpt4 book ai didi

java - 使用 Spring 3 和 Hibernate 4 在 Open-Session-In-View 中实现注解驱动事务

转载 作者:行者123 更新时间:2023-12-02 07:49:41 24 4
gpt4 key购买 nike

我正在使用 Wicket-1.5.3、Spring-3.1.1 和 Hibernate-4.1.1 开发一个应用程序。

我想实现

  • 在 View 中打开 session 模式
  • 事务将由注释驱动,并且
  • 应用程序应该得到任何 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的依赖注入(inject)实际上发生在其中:

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

我有一个关于这门课的问题。我想知道如果我用 HibernateDaoSupport 扩展 BaseDaoImpl 是否会更好?如果我这样做,那么保存方法的替代版本将是:

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接口(interface):

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

}

我没有教授模型类(class)。主要是我有 User 实现 IUser 并扩展 Base。 IUser 又扩展了 IBase,而 Base 又实现了 IBase。

现在我想知道上面的设计是否正确,是否能满足我的要求。

任何建议都会对我很有帮助。

谢谢。

最佳答案

  1. Spring 3.1 中不再推荐使用 HibernateTemplate。请参阅here

  2. 我无法评估您的服务/dao 层设计,因为您的项目只有一个粗略的背景。但我建议你看看appfuse project ,我相信您会从其源代码中得到很好的提示。

关于java - 使用 Spring 3 和 Hibernate 4 在 Open-Session-In-View 中实现注解驱动事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10371749/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com