Использование Glassfish 4.1, Eclipselink 2.5.1, Oracle 11g.Аутентификация прокси-сервера Oracle: откат всей транзакции
У нас возникли проблемы с откатом изменений при сохранении отношения «один ко многим» (родительские дети) с использованием Аутентификация прокси-сервера Oracle. Если какое-либо исключение возникает при сохранении одного из дочерних элементов, родительский объект по-прежнему сохраняется в БД (не откатывается, как ожидалось). Мы экономим к БД из безгосударственного EJB с управляемой контейнером JTA EntityManager с:
entitymanager.persist(parent);
cascade = CascadeType.ALL
используется на отношения на материнской стороне.
Наш persistence.xml содержит <persistence-unit name="admin_war_1.0-SNAPSHOTPU" transaction-type="JTA">
, и проблема в том, что у нас есть только один слой с сохранением (пока все работает нормально).
Родитель объект является чем-то вроде:
public class KornstoranalyseStd implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "KORNSTORANALYSE_STD_ID", nullable = false)
private Integer kornstoranalyseStdId;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "kornstoranalyseStd", fetch = FetchType.EAGER)
@OrderBy("maskestoerrelse DESC")
private Collection<KornstoranalyseStdSigte> kornstoranalyseStdSigteCollection;
}
И ребенок юридическое лицо:
public class KornstoranalyseStdSigte implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "KORNSTORANALYSE_STD_SIGTE_ID", nullable = false)
private Integer kornstoranalyseStdSigteId;
@Basic(optional = false)
@NotNull
@Column(name = "MASKESTOERRELSE", nullable = false, precision = 12, scale = 8)
private BigDecimal maskestoerrelse;
@JoinColumn(name = "KORNSTORANALYSE_STD_ID", referencedColumnName = "KORNSTORANALYSE_STD_ID", nullable = false)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private KornstoranalyseStd kornstoranalyseStd;
}
Следующий код предназначен только для тестирования:
KornstoranalyseStd parent = new KornstoranalyseStd();
parent.setKornstoranalyseStdId(1);
List<KornstoranalyseStdSigte> children = new ArrayList<>();
KornstoranalyseStdSigte child = new KornstoranalyseStdSigte();
child.setKornstoranalyseStdSigteId(1);
child.setMaskestoerrelse(new BigDecimal(11));
child.setKornstoranalyseStd(parent);
children.add(child);
parent.setKornstoranalyseStdSigteCollection(children);
getEjbFacade().create(parent);
Это СЦБ :
@Stateless
public class KornstoranalyseStdFacade {
@PersistenceContext(unitName = "admin_war_1.0-SNAPSHOTPU")
private EntityManager em;
private EntityManager getEntityManager() {
return em;
}
public void create(KornstoranalyseStd entity) {
getEntityManager().persist(entity);
}
}
Во всех вызовов через EJB, мы прокси в EntityManager с
getEntityManager().setProperty("eclipselink.oracle.proxy-type", 1);
getEntityManager().setProperty("PROXY_USER_NAME", loginBean.getUsername());
getEntityManager().setProperty("PROXY_USER_PASSWORD", loginBean.getPassword());
getEntityManager().setProperty("eclipselink.jdbc.exclusive-connection.mode", "Always");
getEntityManager().setProperty("eclipselink.jdbc.exclusive-connection.is-lazy", "true");
Вышеуказанные линии в @AroundInvoke-method
, и, следовательно, не будет работать независимо от того, что EJB-метод доступен.
Проблема возникает только при проксировании, а не при опускании этой части. Похоже, проблема связана с подключением jdbc-соединений. Мы пробовали все виды параметров в пуле соединений Glassfish; relaxAutoCommit = true, AutoCommit = false и т. д., но ничего не изменилось.
Как мы можем гарантировать, что родитель также откатывается назад, когда не удается продолжить работу с ребенком?
Вы не указали демаркацию транзакции, определение источника данных или само исключение, поэтому мы не можем понять, в чем проблема. Я предполагаю, что вы не настроили источник данных JTA в стеклянной платке, так что EclipseLink пишет через соединение за пределами транзакции, в результате чего каждый оператор автоматически настраивается. – Chris
Большое спасибо Крис - вы правы, я пропустил многое для краткости. Демаркация дается с использованием CMT в STSB, не так ли? Извините, я не указал прямо. Что-то особенное необходимо для источника данных JTA в GF (у нас есть «стандартный» источник данных/пул соединений)? Тем не менее, похоже, проблема заключалась в аутентификации Oracle proxy, что было еще одним пропуском для простоты. Как вы говорите, похоже, соединение за пределами транзакции. Удалит вопрос, если подтвердится. Спасибо за комментарий снова –