注意:此贴已被论坛评为新手贴,没有参考价值,我留在这里来记录一下自己的思路而已
坛子里有一篇主题差不多的文章,但是我要说的不是他那个。不知道是我理解错误还是其他什么原因,整整一天时间不断的测试,找资料,总觉得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动态代理。
分享到:
相关推荐
至于`Dao经典泛型.doc`文件,可能是更深入的关于Hibernate泛型DAO的文档,可能包含了如何配置Spring、如何处理复杂查询以及如何优化泛型DAO的更多细节。阅读这份文档将进一步提升你对泛型DAO的理解和应用能力。 ...
在Spring框架中,XML配置文件曾是配置组件和依赖注入的主要方式。例如,它可能会定义一个Hibernate的SessionFactory或Data Source,这样就可以在泛型DAO中使用这些配置来操作数据库。 总之,泛型DAO是Java开发中一...
这些配置文件和代码会详细阐述如何进行S2SH的整合,以及如何使用注解进行配置,如何处理JSON数据,以及如何设计和实现泛型Dao。通过深入学习和实践这些内容,开发者可以更好地理解和掌握企业级Java Web应用的开发...
在Struts2+Hibernate+Spring的集成中,泛型DAO扮演着重要的角色,它使得DAO层对所有实体类的操作变得统一和规范。 首先,让我们详细了解一下Struts2。Struts2是基于拦截器的MVC框架,它提供了强大的动作映射、结果...
下面将详细介绍SSH框架及其分页和泛型DAO的概念。 1. **Struts2**: Struts2是一个基于MVC(Model-View-Controller)设计模式的Web应用框架,用于简化Java Web应用的开发。它提供了动作(Action)类来处理用户请求,...
在Spring框架中,我们可以使用依赖注入将`GenericHibernateDao`实例注入到服务层或者控制器中,通过配置文件或者注解来管理SessionFactory和事务,这样就实现了数据库操作的解耦和控制反转。 总的来说,泛型DAO是...
而`Hibernate泛型DAO`则是为了减少代码重复性,提高代码复用性和可维护性的一种设计模式。本文将深入探讨`Hibernate泛型DAO`的实现及其使用方法。 首先,DAO(Data Access Object)模式是一种设计模式,它的主要...
- `spring和hibernate泛型.doc`:可能详细讲解了如何在Spring中配置Hibernate并使用泛型DAO。 - `有关泛型dao的实现.doc`:可能包含泛型DAO的接口定义、实现以及如何在实际项目中应用的实例。 - `泛型DAO设计.doc`:...
标题中的"SSH泛型DAO+Proxool+DisPlayTag+Jquery easyui"涉及到的是一个Web开发技术的组合,主要包括以下几个部分: 1. SSH(Struts2 + Spring + Hibernate):这是一个流行的Java Web开发框架组合,用于构建企业级...
总的来说,"SSHWithAnnotationDemo"项目展示了如何利用现代Java技术栈的高级特性,包括Struts2、Spring3和Hibernate的注解功能,DAO层的泛型设计以及通用的分页实现,来构建一个高效、可维护的Web应用。这样的实践...
在实际项目中,为了确保SSH2与DAO泛型的无缝集成,还需要考虑事务管理、异常处理、性能优化等问题。 在SSH2中,DAO层的泛型应用还有助于单元测试,因为每个具体的DAO实现都可以独立测试,无需关心底层数据源。同时...
1. `GenericDAO.java`:泛型DAO接口,定义了基本的CRUD方法。 2. `HibernateGenericDAO.java`:实现了`GenericDAO`接口的具体类,使用Hibernate作为底层的数据访问技术。 3. `BaseDAO.java`:可能是一个抽象类,包含...
在Java开发领域,SSH(Struts、Spring、Hibernate)是一个常见的企业级应用框架组合,而Spring...在实际项目中,结合SSH笔记和Spring的其他特性,如AOP(面向切面编程)、事务管理等,我们可以构建出高效的企业级应用。
综上所述,"spring3.1+hibernate4+jpa Dao"的集成是一个高效、灵活的企业级应用开发架构,它结合了Spring的IoC和AOP能力、Hibernate的ORM功能以及JPA的标准接口,通过泛型DAO实现和事务管理,为开发者提供了强大的...
- 事务配置:Spring Data JPA的异常翻译功能仍然可用,同时可以自定义事务配置。 7. **Spring Data JPA的@Query使用** - JPQL(Java Persistence Query Language)和原生SQL查询:用于构建更复杂的查询。 - 排序...
Spring1.x对JDBC和ORM的支持相对较弱,而Spring2.x在这一领域有了显著增强,集成了更多ORM框架,如Hibernate、JPA等,提供了Template和DAO支持,简化了数据库操作。此外,还引入了Transaction API,使得事务管理...
在Spring3和Hibernate4的整合中,泛型常用于创建泛型DAO,如`UserDao<User>`,这样在处理不同类型的实体时,可以重用相同的DAO基础代码,提高了代码的复用性和可维护性。 4. **注解的应用**:Spring3和Hibernate4都...
通过在Spring配置文件中声明bean并注入`SessionFactory`,我们可以将这些泛型BaseDAO实例化并自动管理。 4. `BaseDao.java`和`BaseDaoInter.java`: 这两个文件可能包含了非泛型版本的基础DAO接口和实现,可能是...
Spring注解如`@Autowired`、`@Service`、`@Repository`和`@Controller`使得配置文件大大简化,开发者可以直接在类或方法上添加注解来声明其作用。例如,`@Autowired`用于自动装配依赖,`@Service`和`@Repository`...