Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring@Transactional和继承_Java_Spring_Transactions_Spring Transactions_Transactional - Fatal编程技术网

Java Spring@Transactional和继承

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) { // ....

我确实有一个基于泛型的DAO类,它是我项目中所有其他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) {
        // ...
    }

}
但是,我需要在每个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);
    }   
}