最后经过一段时间的测试,我找到了一种适用于我的场景的解决方案。
我没有发布所有代码,只发布与问题解决方案相对应的主要部分:
经理类
@ManagedBean
@ApplicationScoped
@TransactionManagement(TransactionManagementType.BEAN)
public class CarsManager implements Serializable {
@Resource
private UserTransaction userTransaction;
private CarsRepositorySameEM carsRepoSameEM;
private CarsPartsRepositorySameEM carsPartsRepoSameEM;
private EntityManager entityManager;
private Cars car;
private List<CarsParts> carPartList;
@Inject
public CarsManager(@MainEM EntityManager em) {
this.entityManager = em;
this.carsRepoSameEM = new CarsRepositorySameEM(this.entityManager);
this.carsPartsRepoSameEM = new CarsPartsRepositorySameEM(this.entityManager);
}
public Cars getCar() {
return car;
}
public void setCar(Cars car) {
this.car = car;
}
public List<CarsParts> getCarPartList() {
return carPartList;
}
public void setCarPartList(List<CarsParts> carPartList) {
this.carPartList = carPartList;
}
public Boolean save() {
Boolean result = Boolean.TRUE;
try {
this.userTransaction.begin();
this.car = carsRepoSameEM.saveCar(this.car);
if(carsPartsRepoSameEM.getEntityException().getCode() != 0) {
this.userTransaction.setRollbackOnly();
}
for (int i = 0; i < carPartList.size(); i++) {
carPartList.get(i).setCarsId(car.getID());
}
this.carPartList = carsPartsRepoSameEM.saveParts(carPartList);
if(carsPartsRepoSameEM.getEntityException().getCode() != 0) {
this.userTransaction.setRollbackOnly();
}
car.setCarsPartsList(this.carPartList);
this.userTransaction.commit();
} catch (Exception e) {
//e.printStackTrace();
result = Boolean.FALSE;
try {
this.userTransaction.rollback();
} catch (Exception ex) {
}
}
return result;
}
}
存储库类:
@Stateless
public class CarsRepositorySameEM extends AbstractRepository<Cars, Long> {
...
public Cars saveCar(Cars car) throws SystemException {
try {
this.entityManager.joinTransaction();
car = this.create(car);
this.entityManager.flush();
} catch (Exception e) {
this.setEntityException(GenericExceptionType.EX_JPA, -1, "CarsRepositorySameEM", "saveCar()", "Error al persistir el Car", null, e.getMessage());
//throw e;
}
return car;
}
}
-
@Stateless
public class CarsPartsRepositorySameEM extends AbstractRepository<CarsParts, Long> {
...
public List<CarsParts> saveParts(List<CarsParts> carsPartsList) throws SystemException {
try {
this.entityManager.joinTransaction();
for (int i = 0; i < carsPartsList.size(); i++) {
carsPartsList.set(i, this.create(carsPartsList.get(i)));
}
this.entityManager.flush();
} catch (Exception e) {
this.setEntityException(GenericExceptionType.EX_JPA, -1, "CarsPartsRepositorySameEM", "saveParts()", "Error al persistir las CarsParts", null, e.getMessage());
//throw e;
}
return carsPartsList;
}
}
观察:EntityManager 是从 Producer 方法注入的,该方法根据配置动态创建 EntityManagerFactory。
正如 EclipseLink 文档中提到的用于配置将用于启用与主机容器集成的 ServerPlatform 一样,我必须在 persistence.xml 中放入属性
<property name="eclipselink.target-server" value="Glassfish"/>
使用此属性确保动态创建的 EntityManager 将使用事务类型 JTA。
感谢答案,希望这个例子可以帮助任何面临类似问题的人。