Слияние родителя вызывает сироту - PullRequest
0 голосов
/ 11 июня 2018

у меня есть два класса / объекта ProcJobData и SubstrateData

ProcjobData:

...
@OneToMany(mappedBy = "procJobData", orphanRemoval = true, cascade = { CascadeType.ALL })
private List<SubstrateData> substrateData;
...

и SubstrateData:

@ManyToOne
@JoinColumn(name = "procjobdata_fk")
privateProcJobData procJobData();

в моем менеджере заданий на коде я создаю новыйprocjobdata и установите некоторые значения и удерживайте его в качестве члена.

EntityManager em = emf.createEntityManager();

try {
     em.getTransaction().begin();
     pjData = new ProcJobData();
     ... set some values
     pjData = ProcJobDataDAO.create(em, pjData);
     em.getTransaction().commit();
} catch (Exception ex) {
     LOG.error("Failed to persist ProcJob[" + procJobNo + "]", ex);
     if (em.getTransaction().isActive()) {
           em.getTransaction().rollback();
     }
} finally {
     if (em != null && em.isOpen()) {
           em.close();
     }
}

, затем чуть позже я добавляю SubstrateData:

em.getTransaction().begin();
for(int i = 0; i < MAX_SUBSTRATES; i++){
    ...
    SubstrateData substrate = new SubstrateData();
    ...
    substrate.setProcJobData(this.procJobData);
    SubstrateData create = SubstrateDataDAO.create(em, substrate);
    procJobData.addSubstrateData(create);
}
this.procJobData = em.merge(this.procJobData);
em.getTransaction().commit();

метод создания SubstrateDataDAO:

public static SubstrateData create(final EntityManager entityManager, final    SubstrateData entity) {
    entityManager.persist(entity);
    entityManager.flush();
    return entity;
}

Теперь моя проблема: я всегда использую транзакции, если я изменяю некоторые значения.Если я объединяю сущность procJobData в открытой транзакции, я получу новый экземпляр, и все мои substDatas являются сиротами, потому что они все еще ссылаются на старый экземпляр, а hibernate удалит записи.я удалил слияние внутри транзакции и все нормально - но почему ??вопрос заключается в следующем: нужно ли объединение внутри транзакции?

РЕДАКТИРОВАТЬ: также, если я объединю сущность procjobdata позже - субстраты все равно будут удалены.как в этом коде чуть позже - на данный момент есть записи банка данных для подложек:

em.getTransaction().begin();
this.procJobData.setLoadOn(new Date());
this.procJobData = em.merge(this.procJobData); //edit -> using return value
em.getTransaction().commit(); 

1 Ответ

0 голосов
/ 11 июня 2018

Ваш код слияния должен сделать это:

this.procJobData = em.merge( this.procJobData );

Причина ясна из документации java

Returns: the managed instance that the state was merged to

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

...