`
vulcan
  • 浏览: 3775 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

泛型DAO和Spring的事务配置问题

阅读更多
注意:此贴已被论坛评为新手贴,没有参考价值,我留在这里来记录一下自己的思路而已
坛子里有一篇主题差不多的文章,但是我要说的不是他那个。不知道是我理解错误还是其他什么原因,整整一天时间不断的测试,找资料,总觉得Spring对于范型接口的事务配置有问题。
public interface GenericDAO<T, ID extends Serializable> {
	/**
	 * A common method for load a instance with Id specified
	 * @param id
	 * @return
	 */
	public T findById(ID id);
	/**
	 * Get a entity by the ID
	 * @param id
	 * @param lock
	 * @return
	 */
    public T findById(ID id, boolean lock);

    /**
     * Get all the entities
     * @return
     */
    public List<T> findAll();
    /**
     * Get all the entities page by page
     * @param index
     * @param offset
     * @return
     */
    public List<T> findAllByPage(int index, int offset);
    /**
     * Get a list of entities by example
     * @param exampleInstance
     * @return
     */
    public List<T> findByExample(T exampleInstance);
    /**
     * Make the entity persistent
     * @param entity
     * @return
     */
    public boolean save(T entity);
    /**
     * Delete an entity
     * @param entity
     * @return
     */
    public boolean delete(T entity);
    /**
     * Update an entity
     * @param entity
     * @return
     */
    public boolean update(T entity);
    
}

上面是范型接口的定义
有一个GenericHibernateDAO实现了上面的接口,提供了类型安全的基本的CRUD操作
现在有一个具体的DAO操作,比如User
那么可以这样来做
public interface UserDAO extends GenericDAO<User, Integer>
//other method signature


public class UserDAOImpl extends GenericHibernateDAO<User, Integer> implements UserDAO
//implementation for other method except basic CRUD operations

现在UserDAOImpl即使不写一行代码,那么也具备了基本的CURD能力,工程是使用了webwork框架,并且使用了Spring的
OpenSessionInViewFilter,那么对于update,save之类得方法,必须要配置事务管理,才可以正常工作。
那么我写下下面的Spring配置
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
  <tx:attributes>
   <tx:method name="save*" propagation="REQUIRED" />
   <tx:method name="update*" propagation="REQUIRED"/>
   <tx:method name="delete*" propagation="REQUIRED"/>
   <tx:method name="find*" read-only="true"/>
   <tx:method name="get*" read-only="true" />
   <tx:method name="*"/>

  </tx:attributes>
</tx:advice>

<aop:config>
  <aop:pointcut id="daoOperation" expression="execution(* x.y.z.dao.UserDAO.*(..))"/>
  <aop:advisor advice-ref="txAdvice" pointcut-ref="daoOperation"/>
</aop:config>

奇怪的问题出现了,通过GenericDAO继承过来的方法签名对于事务管理都无效。
报错信息为:
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
而额外的新增的方法居然是正常工作的,我原来怀疑是不是不支持接口继承啊,于是专门做了一下测试,把UserDAO额外的方法签名全部放到UserService接口中,那么类型结构就成了这个样子:
UserService extends GenericDAO<User, Integer>
//method signature here

UserDAO extends UserService
这样居然测试之后的结果居然是除GenericDAO额外的方法签名都是可以正常受事务管理器管理的,那就证明对于父接口的aop不成问题;那么结论是什么呢?难道是范型接口中的方法支持有问题?

请哪位兄弟解答一下,或者哪位兄弟有类似疑问的也请回帖。我是百思不得其解了。
--------------
2.1日更新:
今天又测试了一下,发现自己的猜想是片面的,只是一种特殊情况下的错误理解;其实对于范型的接口继承,Spring是没有问题的,却发现了一个更奇怪的问题:必须要在DepartmentDAOImpl中重载接口中的方法,Spring的声明式事务才会有效果。或者父接口不能为范型。
也就是说,要么这样重载:
public boolean save(User user) {
    return super.save(user);
}

要么就完全的实现另外一个接口,这样其实也就保证了具体业务的类中实际有方法实现,而不是从范型父类中继承的方法。
需要说明的是,对于这个问题,很多人的设计是不会出的,因为他们会进行更高层次的抽象,也就是说这个范型DAO之上还有一个业务层,这里通常是一些*Service或者*Manager方法,而通常的事务配置应该在业务层上配置.这样的我试过,是完全正常的,不过这无非也就是避免了在范型接口的方法上配置事务.不过无疑这样的设计是很好的,也应该使用,比如新增一个用户,先要查看该用户是否之前存在,然后才是真正的写入到数据库的操作,这两个DAO操作组成了addUser这一个"业务逻辑".可是,我的设计中,却偏不愿意这么干,我不想为了一些简单的操作,再多建2n个类和接口.而按照DAO层之上再加业务逻辑层的设计方法,却是对于一个需要持久化的实体会有4n个类或者是接口.我换了一种策略,我不再想着在DAO上做事务配置的文章,而是在webwork的action的增加需要事务的方法,在Spring配置中对这些具有固定前缀的方法配置事务,这样和webwork中把表单参数集中到Action的方法有点类似,想当初我烦Struts就是因为没一个表单,不管多简单,都要一个ActionForm,要么就从request对象里面取.对于我的这个小软件系统,很多操作并不复杂,基本就是一个Action一个DAO操作,涉及到多个DAO连用的也就那么几个Action,我大可以在Action中来写这些.并且由于webwork是采用Spring作为ObjectFactory的,所以Action本来就在Spring的object池中了,那么也就省去了,再到Spring配置文件中配置n个server或者Manager的类.而且说到数据库迁移和测试的能力,在DAO层上的抽象,对于我的项目,我觉得也足够了。
也许不是Spring达不到我的要求,但是好看完Spring的文档之后,也试验了好久,还是找不到原因,就是找不到针对DAO的范型接口中定义的方法做声明式事务的方法.有时间要好好看看Spring的源码,看看它AOP这一块到底到底是怎么搞的,来解除我的疑惑.
---------------------
2008年3月18日更新:
问题解决:原因,没有给范型接口配置声明式事务。
看了SpringSide2.0的源码,才知道如果DAO继承自范型接口,那么还要给范型DAO配置声明式事务,而不是像我之前设想的那样,继承自范型接口的操作将会在给子类配置时自动被配置了。不过需要注意的是进行声明式事务配置时,需要指定proxy-target-class="true"来使用Cglib来进行代码增强,而不能使用默认的java动态代理。
分享到:
评论

相关推荐

    Hibernate泛型DAO(结合spring模板支持)

    至于`Dao经典泛型.doc`文件,可能是更深入的关于Hibernate泛型DAO的文档,可能包含了如何配置Spring、如何处理复杂查询以及如何优化泛型DAO的更多细节。阅读这份文档将进一步提升你对泛型DAO的理解和应用能力。 ...

    泛型dao

    在Spring框架中,XML配置文件曾是配置组件和依赖注入的主要方式。例如,它可能会定义一个Hibernate的SessionFactory或Data Source,这样就可以在泛型DAO中使用这些配置来操作数据库。 总之,泛型DAO是Java开发中一...

    S2SH整合例子 注解配置 JSON 泛型Dao

    这些配置文件和代码会详细阐述如何进行S2SH的整合,以及如何使用注解进行配置,如何处理JSON数据,以及如何设计和实现泛型Dao。通过深入学习和实践这些内容,开发者可以更好地理解和掌握企业级Java Web应用的开发...

    Struts2+hibernate+spring整合泛型DAO

    在Struts2+Hibernate+Spring的集成中,泛型DAO扮演着重要的角色,它使得DAO层对所有实体类的操作变得统一和规范。 首先,让我们详细了解一下Struts2。Struts2是基于拦截器的MVC框架,它提供了强大的动作映射、结果...

    SSH 泛型DAO分页

    下面将详细介绍SSH框架及其分页和泛型DAO的概念。 1. **Struts2**: Struts2是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,用于简化Java Web应用的开发。它提供了动作(Action)类来处理用户请求,...

    Hibernate泛型DAO及使用方法.doc

    在Spring框架中,我们可以使用依赖注入将`GenericHibernateDao`实例注入到服务层或者控制器中,通过配置文件或者注解来管理SessionFactory和事务,这样就实现了数据库操作的解耦和控制反转。 总的来说,泛型DAO是...

    Hibernate泛型DAO及使用方法

    而`Hibernate泛型DAO`则是为了减少代码重复性,提高代码复用性和可维护性的一种设计模式。本文将深入探讨`Hibernate泛型DAO`的实现及其使用方法。 首先,DAO(Data Access Object)模式是一种设计模式,它的主要...

    DAO模式设计

    - `spring和hibernate泛型.doc`:可能详细讲解了如何在Spring中配置Hibernate并使用泛型DAO。 - `有关泛型dao的实现.doc`:可能包含泛型DAO的接口定义、实现以及如何在实际项目中应用的实例。 - `泛型DAO设计.doc`:...

    SSH泛型DAO+Proxool+DisPlayTag+Jquery easyui

    标题中的"SSH泛型DAO+Proxool+DisPlayTag+Jquery easyui"涉及到的是一个Web开发技术的组合,主要包括以下几个部分: 1. SSH(Struts2 + Spring + Hibernate):这是一个流行的Java Web开发框架组合,用于构建企业级...

    Struts2 Spring3 Hibernate 注解功能 DAO 泛型 通用分页

    总的来说,"SSHWithAnnotationDemo"项目展示了如何利用现代Java技术栈的高级特性,包括Struts2、Spring3和Hibernate的注解功能,DAO层的泛型设计以及通用的分页实现,来构建一个高效、可维护的Web应用。这样的实践...

    ssh2 + dao泛型

    在实际项目中,为了确保SSH2与DAO泛型的无缝集成,还需要考虑事务管理、异常处理、性能优化等问题。 在SSH2中,DAO层的泛型应用还有助于单元测试,因为每个具体的DAO实现都可以独立测试,无需关心底层数据源。同时...

    ssh通用基于泛型的dao

    1. `GenericDAO.java`:泛型DAO接口,定义了基本的CRUD方法。 2. `HibernateGenericDAO.java`:实现了`GenericDAO`接口的具体类,使用Hibernate作为底层的数据访问技术。 3. `BaseDAO.java`:可能是一个抽象类,包含...

    SSH笔记-泛型依赖注入

    在Java开发领域,SSH(Struts、Spring、Hibernate)是一个常见的企业级应用框架组合,而Spring...在实际项目中,结合SSH笔记和Spring的其他特性,如AOP(面向切面编程)、事务管理等,我们可以构建出高效的企业级应用。

    spring3.1+hibernate4+Jpa Dao

    综上所述,"spring3.1+hibernate4+jpa Dao"的集成是一个高效、灵活的企业级应用开发架构,它结合了Spring的IoC和AOP能力、Hibernate的ORM功能以及JPA的标准接口,通过泛型DAO实现和事务管理,为开发者提供了强大的...

    Persistence with Spring

    - 事务配置:Spring Data JPA的异常翻译功能仍然可用,同时可以自定义事务配置。 7. **Spring Data JPA的@Query使用** - JPQL(Java Persistence Query Language)和原生SQL查询:用于构建更复杂的查询。 - 排序...

    Spring1.x 和Spring2.x 版本上使用有什么区别

    Spring1.x对JDBC和ORM的支持相对较弱,而Spring2.x在这一领域有了显著增强,集成了更多ORM框架,如Hibernate、JPA等,提供了Template和DAO支持,简化了数据库操作。此外,还引入了Transaction API,使得事务管理...

    spring3和hibernate4WEB工程

    在Spring3和Hibernate4的整合中,泛型常用于创建泛型DAO,如`UserDao&lt;User&gt;`,这样在处理不同类型的实体时,可以重用相同的DAO基础代码,提高了代码的复用性和可维护性。 4. **注解的应用**:Spring3和Hibernate4都...

    hibernate basedao(泛型版本)

    通过在Spring配置文件中声明bean并注入`SessionFactory`,我们可以将这些泛型BaseDAO实例化并自动管理。 4. `BaseDao.java`和`BaseDaoInter.java`: 这两个文件可能包含了非泛型版本的基础DAO接口和实现,可能是...

    基于注解整合spring与hibernate

    Spring注解如`@Autowired`、`@Service`、`@Repository`和`@Controller`使得配置文件大大简化,开发者可以直接在类或方法上添加注解来声明其作用。例如,`@Autowired`用于自动装配依赖,`@Service`和`@Repository`...

Global site tag (gtag.js) - Google Analytics