Java Spring@Transactional和继承
我确实有一个基于泛型的DAO类,它是我项目中所有其他DAO类的基础,并包含常见功能:Java Spring@Transactional和继承,java,spring,transactions,spring-transactions,transactional,Java,Spring,Transactions,Spring Transactions,Transactional,我确实有一个基于泛型的DAO类,它是我项目中所有其他DAO类的基础,并包含常见功能: public class Dao<E> { private SessionFactory factory; public void setSessionFactory(SessionFactory factory) { this.factory = factory; } public E get(int id) { // ....
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
// ....
}
public void save(E entity) {
// ...
}
public void delete(E entity) {
// ...
}
}
但是,我需要在每个DAO类中都这样做,代码在任何地方都是一样的
有没有更好的方法可以在所有类之间共享通用功能,并且仍然拥有声明式事务管理的所有好处?您应该使用like,而不是在所有地方添加
@Transactional
注释-
在服务层上使用事务是一种很好的做法。您是否尝试过将@transaction放在父DAO类的方法上
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
@Transactional(readOnly = true)
public E get(int id) {
// ....
}
@Transactional
public void save(E entity) {
// ...
}
@Transactional
public void delete(E entity) {
// ...
}
}
公共类Dao{
私营工厂;
公共无效设置会话工厂(会话工厂){
这个工厂=工厂;
}
@事务(只读=真)
公共E-get(int-id){
// ....
}
@交易的
公共作废保存(E实体){
// ...
}
@交易的
公共作废删除(E实体){
// ...
}
}
这样,当您在DAO1上调用save时,它将从子类(将指定要使用哪个TX管理器)中选择class-level@Transactional,然后从父级的save方法中选择method-level@Transactional。如果您不介意的话,super类也将是
@Transactional
,您应该将注释放在super
DAO上。如果您不介意,我建议创建一个扩展类TransactionalDao
,它将扩展主DAO并成为@Transactional
,所有应该是@Transactional
的DAO也将扩展它:
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
// ....
}
public void save(E entity) {
// ...
}
public void delete(E entity) {
// ...
}
}
@Transactional
public class TransactionalDao<E> extends Dao<E>{
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
return super.get(id);
}
public void save(E entity) {
super.save(entity);
}
public void delete(E entity) {
super.delete(entity);
}
}
公共类Dao{
私营工厂;
公共无效设置会话工厂(会话工厂){
这个工厂=工厂;
}
公共E-get(int-id){
// ....
}
公共作废保存(E实体){
// ...
}
公共作废删除(E实体){
// ...
}
}
@交易的
公共类TransactionalDao扩展了Dao{
私营工厂;
公共无效设置会话工厂(会话工厂){
这个工厂=工厂;
}
公共E-get(int-id){
返回super.get(id);
}
公共作废保存(E实体){
超级保存(实体);
}
公共作废删除(E实体){
超级。删除(实体);
}
}
现在扩展类将如下所示:
@Repository
@Transactional("manager1") // You'd probably still want the @Transactional for new methods
public class Dao1 extends TransactionalDao<Entity1> {
@Overrides
@Autowired
@Qualifier("factory1")
public void setSessionFactory(SessionFactory factory) {
super.setSessionFactory(factory);
}
}
@存储库
@Transactional(“manager1”)//对于新方法,您可能仍然需要@Transactional
公共类Dao1扩展了TransactionalDao{
@覆盖
@自动连线
@限定词(“工厂1”)
公共无效设置会话工厂(会话工厂){
超级工厂(工厂);
}
}
这样,您只需完成一次
super
包装工作。您知道@Transactional可以应用于方法。那么Dao方法可以被附加吗?此外,与Dao层相比,事务更好地属于服务层。AFAIK,如果您对类进行注释,则每个方法,包括继承的方法,都是事务性的。也就是说,事务划分无论如何不应该在DAO级别。@Subin:如果我没有弄错的话-如果我开始注释DAO
的方法-他们仍然要求我指定要使用哪个事务管理器-在那个地方不清楚,因为没有默认的事务管理器。。。事务管理器是继承的特定于类的,只有这样才清楚,特定DAO需要它们中的哪一个…事务管理器属于DAO层。springdatajpa()将事务性存储放在它的所有存储库中。这里人们指的是谁启动事务,事务由事务的“传播”属性控制。服务层应该将其设置为REQUIRED(如果onen不存在,将创建一个新事务),然后DAO应该使用PROPAGATION_emdatory(如果事务不存在,将抛出一个异常-应该由服务层启动).Transacional应该在服务层而不是存储库层,原因是Dao无法知道它参与了什么业务逻辑。相同的方法dao.insertEntity1可能在单个事务上运行,或者作为多实体插入的一部分运行,dao无法确定这一点。当前的实现几乎肯定不是您想要的,事务性的是基于AOP的事务管理。您正在链接到过时的文档。
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
@Transactional(readOnly = true)
public E get(int id) {
// ....
}
@Transactional
public void save(E entity) {
// ...
}
@Transactional
public void delete(E entity) {
// ...
}
}
public class Dao<E> {
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
// ....
}
public void save(E entity) {
// ...
}
public void delete(E entity) {
// ...
}
}
@Transactional
public class TransactionalDao<E> extends Dao<E>{
private SessionFactory factory;
public void setSessionFactory(SessionFactory factory) {
this.factory = factory;
}
public E get(int id) {
return super.get(id);
}
public void save(E entity) {
super.save(entity);
}
public void delete(E entity) {
super.delete(entity);
}
}
@Repository
@Transactional("manager1") // You'd probably still want the @Transactional for new methods
public class Dao1 extends TransactionalDao<Entity1> {
@Overrides
@Autowired
@Qualifier("factory1")
public void setSessionFactory(SessionFactory factory) {
super.setSessionFactory(factory);
}
}