我确实有一个基于泛型的 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/