假设我们有以下代码:
@Entity
public class User {
@Id
private String name;
@OneToOne(cascade = CascadeType.ALL)
private Address address;
//getters and setters
}
@Entity
public class Address {
@Id
private int id;
private String street;
//getters and setters
}
@Stateless
//@Service
public class UserLogicClass {
@PersistenceContext
//@Autowired
private EntityManager entityManager;
public void logicOnUser(User user) {
if(logicOnAddress(user.getAddress()) {
otherLogicOnUser(user);
}
}
public boolean logicOnAddress(Address address) {
//
entityManager.find(address);//address becomes managed
//
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
//@Transactional(propagation = Propagation.REQUIRES_NEW)
public void otherLogicOnUser
//
entityManager.find(user);/*without annotation, user is not managed and address is managed, but with the transaction annotation is the address still managed?*/
//
}
}
问题依赖于上一种方法的评论;我很好奇在Spring案例和EJB案例中都会发生什么。假设Spring配置了JTA事务,并且从此类调用的任何方法都将启动一个新事务,就像在EJB中一样。
答案 0 :(得分:5)
这更像是JPA的一个问题。除非您将其扩展,否则entityManager不会传播到新事务:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
//@Autowired
private EntityManager entityManager;
引用JPA 2.0规范:
容器管理的持久化上下文可以定义为具有 限定为单个事务或扩展的生命周期 跨越多个事务的生命周期,具体取决于 PersistenceContextType,在其实体管理器时指定 创建。本规范将此类持久性上下文称为 事务范围的持久化上下文和扩展的持久性 上下文。
答案 1 :(得分:4)
注意:由于此机制基于代理,因此只有“外部”方法 通过代理进入的电话将被截获。这意味着 '自调用',即目标对象中调用某些方法的方法 目标对象的其他方法,不会导致实际的事务 在运行时,即使调用的方法标有@Transactional!
在目标对象内调用otherLogicOnUser()。