Я пишу мастера для установки довольно сложной объектной модели. Желаемое поведение - загрузить значения в мастер из базы данных с помощью JPA, отредактировать их через различные текстовые поля и поля со списком и записать только , если пользователь нажимает кнопку «Готово» в конце. Если пользователь нажимает «Отмена», я хочу, чтобы содержимое базы данных оставалось таким, каким оно было.Редактор сущности JPA, сохраняется только на OK
Подход, который я имею в виду:
EntityManager em1; // From the Factory
EntityTransaction tx1 = em1.getTransaction();
tx1.begin();
List<?> docs = em1.createQuery("select d from DocumentRoot d").getResultList();
DocumentRoot doc = (DocumentRoot)docs.get(0);
tx1.commit();
em1.close(); // Now DocumentRoot and all associated objects are detached
if (DocumentEditor.showEditDialog(doc) == APPROVE) { // Mutates doc up the wazoo
EntityManager em2; // From the Factory
EntityTransaction tx2 = em2.getTransaction();
tx2.begin();
em2.merge(doc);
tx2.commit();
em2.close();
}
Существует, вероятно, какой-то баланс аннотаций, которые делают эту работу, но я не наткнулся на него. Я добавил cascade = CascadeType.ALL
на все мои один-ко-многим и т.д. ассоциации, которые укрепляли «object references an unsaved transient instance
» ошибку, но теперь у меня есть «Multiple representations of the same entity [...] are being merged.
»
У меня есть подозрение, что рассматриваемый объект многократно представлен, потому что есть многие-ко-многим. Там есть another thread, предлагая удалить CascadeType.MERGE из ссылок на этот объект, но это похоже на опасно протекающую бандаду. Неудивительно, что удаление этого CascadeType.MERGE означает, что новые объекты типа не сохранялись при слиянии.
Кажется, что весь этот подход - отсоединить, отредактировать, слить, если он принят, делает JPA очень несчастным. Есть ли другой подход, который считается более идиоматичным для случаев, когда вы хотите редактировать то, что является фактически локальной копией, не сохраняясь и сохраняться только тогда, когда пользователь нажимает «ОК?».
Отменить откат(), а не commit()? – Gimby