java - Spring @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 void save(E entity) {
        // ...
    }

    public void delete(E entity) {
        // ...
    }

}

在我的项目中,我使用多个数据源,指向不同的数据库,因此,我有多个 session 和事务管理器:

<bean id="factory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="source1" />
</bean>

<bean id="manager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="factory1" />
</bean>

<bean id="factory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="source2" />
</bean>

<bean id="manager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="factory2" />
</bean>

现在我想创建几个 DAO,在不同的数据库上运行:

@Repository
@Transactional("manager1")
public class Dao1 extends Dao<Entity1> {

    @Overrides
    @Autowired
    @Qualifier("factory1")
    public void setSessionFactory(SessionFactory factory) {
        super.setSessionFactory(factory);
    }

}

@Repository
@Transactional("manager2")
public class Dao1 extends Dao<Entity2> {

    @Overrides
    @Autowired
    @Qualifier("factory2")
    public void setSessionFactory(SessionFactory factory) {
        super.setSessionFactory(factory);
    }

}

但问题是,Dao 中的所有公共(public)方法都没有被子类中的@Transactional 覆盖,因此没有事务管理发生。我能想到的唯一选择是重写父类方法,因此它们在继承类中定义,因此由 @Transactional 处理:

@Repository
@Transactional("manager1")
public class Dao1 extends Dao<Entity1> {

    @Overrides
    @Autowired
    @Qualifier("factory1")
    public void setSessionFactory(SessionFactory factory) {
        super.setSessionFactory(factory);
    }

    @Overrides
    public Entity1 get(int id) {
        return super.get(id);
    }

    @Overrides
    public void save(Entity1 entity) {
        super.save(entity);
    }

    @Overrides
    public void delete(Entity1 entity) {
        super.delete(entity);
    }

}

但之后我需要在每个 DAO 类中执行此操作,代码将在所有地方都相同...

有没有更好的方法来跨所有类共享通用功能并仍然具有声明式事务管理的所有好处?

最佳答案

如果您不介意 super类将是 @Transactional同样,您应该将注释放在 super 上道。如果您介意,我建议创建一个扩展类 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);
    }
}

现在扩展类看起来像这样:

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

这样你只需要这样做super只包装一次。

关于java - Spring @Transactional 和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14153124/

相关文章:

java - 有 JNDI namespace 约定吗?

java - 我无法在 Spring-MVC 中访问 Robots.txt

java - 从 throwable 获取正文详细信息,并断言抛出异常时返回了确切的消息

python - 测试 ndb 实体是否已放入数据存储

java - 纯 Java : How do i know if my thread is sleeping or not?

java - Spring jms - 重命名 DLQ

java - Android 在 TextSwitcher 中滚动文本

java - setter 在 Spring 框架中如何工作?

java - 手动创建的多个数据源的事务管理

PHP PDO SQLite。事务和更新问题