Java 新事务是否分离所有以前的实体?
假设我们有以下代码:Java 新事务是否分离所有以前的实体?,java,spring,jpa,transactions,ejb,Java,Spring,Jpa,Transactions,Ejb,假设我们有以下代码: @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 s
@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中一样。这更像是JPA的问题。除非扩展entityManager,否则不会将其传播到新事务:
@PersistenceContext(type = PersistenceContextType.EXTENDED)
//@Autowired
private EntityManager entityManager;
引用JPA 2.0规范:
容器管理的持久性上下文可以定义为
限定为单个事务或扩展事务的生存期
跨多个事务的生存期,具体取决于
PersistenceContextType,当其实体管理器为
创建。本规范引用了以下持久性上下文:
事务作用域持久性上下文和扩展持久性
分别是上下文
注意:由于该机制基于代理,因此仅使用“外部”方法
通过代理传入的呼叫将被拦截。这意味着
“自调用”,即目标对象内调用某些
目标对象的其他方法不会导致实际事务
在运行时,即使调用的方法标记为@Transactional
在目标对象内部调用otherLogicOnUser()
阅读更多信息:因此,除非将类型设置为extended,否则在该方法中,将创建一个新的实体管理器,其中没有任何托管实体?是的,完全正确。在
otherLogicOnUser
方法中,将创建一个新事务,除非对持久性上下文进行扩展,否则不应传播它。使用扩展的EntityManager是为了在有状态EJB中使用,它不是线程安全的,如果使用事务范围的EntityManager的方法在同一事务中调用使用扩展EntityManager的方法,则可能会发生持久性上下文冲突。