Наконец, после некоторого времени тестирования, я прихожу к одному решению, которое подходит для моего сценария.
Я публикую не весь код, а только основные части, соответствующие решению проблемы:
Менеджерский класс
@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.
Спасибо за ответы и надеюсь, что этот пример может помочь любому, кто сталкивается с подобной проблемой.