Я обновляю приложение на основе RCP для использования JPA 2.1 (реализация EclipseLink) из Hibernate 3.x. Поведение JPA-слияния вызывает у меня проблемы. Проблема, которую я вижу, - это когда я присваиваю возвращаемое значение объекту модели в редакторе RCP (унаследованному от FormEditor), это новый объект, и изменения не сохраняются при последующих сбережениях.RCP Editor и JPA merge
Я ищу информацию о том, как лучше всего обновить модель редактора RCP новым объектом, возвращенным из JPA.merge().
Примечание: Я понимаю, что разница между сохранением save-url и сохранением JPA сохраняется.
Этих два подхода, которые я вижу, является:
- В моем слое службы сделать глубокую копию нового объекта возвращается из JPA.merge() в объект, который был принят в service.save() и не выполняйте назначение в методе editor.doSave().
- Associate модель в редакторе RCP к новой сущности вернулась из JPA.merge()
Объекта граф является довольно сложным и глубоким, так писать глубокую копию не является тривиальным. Однако я не знаю, как подойти к № 2 выше.
Я открыт для любых идей о том, как подойти к # 1/# 2 или если есть варианты # 3 - #n, которых я не вижу.
Спасибо, что нашли время, чтобы прочитать мой вопрос!
Вот мой текущий метод Editor.doSave
@Override
public void doSave(IProgressMonitor monitor) {
this.overviewPage.getDataBindingContext().updateModels();
this.getActivePageInstance().getManagedForm().commit(true);
try {
motor = Activator.getAcMotorEntity().save(motor);
} catch (BusinessException e) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Unable to save the motor to the database", e),
StatusManager.LOG | StatusManager.SHOW);
}
if (motor.getId() == 1L) {
this.setPartName("[DEFAULT VALUES]");
} else {
this.setPartName(this.motor.getJobNumber());
}
this.setDirty(false);
}
и мой service.save(), который вызывает слияние JPA в
@Override
public IT save(IT entity) throws BusinessException {
EntityManager em = factory.createEntityManager();
IT savedEntity = null;
getLogger().debug("Save {} with id of {} ", entity.getClass().getName(), ((IDatabaseEntity) entity).getId());
try {
em.getTransaction().begin();
savedEntity = em.merge(entity); // re-attach
em.getTransaction().commit();
this.firePropertyChange(entity, savedEntity);
} catch (OptimisticLockException ole) {
getLogger().error("Load " + entity.getClass().getName() + " with id of " + ((IDatabaseEntity) entity).getId(), ole);
throw JpaExceptionFactory.createRecordChanged(ole, entity == null ? 0 : ((IDatabaseEntity) entity).getId(),
entity == null ? "null entity" : entity.getClass().getName());
} catch (PersistenceException pe) {
getLogger().error("Load " + entity.getClass().getName() + " with id of " + ((IDatabaseEntity) entity).getId(), pe);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
throw JpaExceptionFactory.createPersistence(pe, entity == null ? 0 : ((IDatabaseEntity) entity).getId(),
entity == null ? "null entity" : entity.getClass().getName());
} catch (Throwable t) {
getLogger().error("Load " + entity.getClass().getName() + " with id of " + ((IDatabaseEntity) entity).getId(), t);
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
throw JpaExceptionFactory.createUnknownDatabase(t, entity == null ? 0 : ((IDatabaseEntity) entity).getId(),
entity == null ? "null entity" : entity.getClass().getName());
} finally {
if (em != null && em.isOpen()) {
em.close();
}
}