2015-05-23 3 views
2

Я обновляю приложение на основе RCP для использования JPA 2.1 (реализация EclipseLink) из Hibernate 3.x. Поведение JPA-слияния вызывает у меня проблемы. Проблема, которую я вижу, - это когда я присваиваю возвращаемое значение объекту модели в редакторе RCP (унаследованному от FormEditor), это новый объект, и изменения не сохраняются при последующих сбережениях.RCP Editor и JPA merge

Я ищу информацию о том, как лучше всего обновить модель редактора RCP новым объектом, возвращенным из JPA.merge().

Примечание: Я понимаю, что разница между сохранением save-url и сохранением JPA сохраняется.

Этих два подхода, которые я вижу, является:

  1. В моем слое службы сделать глубокую копию нового объекта возвращается из JPA.merge() в объект, который был принят в service.save() и не выполняйте назначение в методе editor.doSave().
  2. 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(); 
     } 
    } 

ответ

0

Проблема оказалась в том, что контекст привязки, который отображает поля редактора для модели создавались только при создании формы. Эта привязка продолжала указывать на исходную сущность.

Решение состоит в том, чтобы перестроить контекст привязки данных после вызова к motor = Activator.getAcMotorEntity().save(motor);. Это обновило привязку, чтобы указать на объект, возвращенный из JPA.merge().

Смежные вопросы