Eclipselink OneToMany Merge удаляет отношения - PullRequest
0 голосов
/ 23 марта 2012

У меня есть родительский объект Compound с отношением один-ко-многим к объекту Submission. Я установил отношения следующим образом:

@Entity
public class Compound implements Serializable {

    @Id
    private long compoundId;

    ...

    @OneToMany(mappedBy="compound", fetch=FetchType.LAZY,
        cascade={ CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
    @PrivateOwned
    private List<Submission> submissions;

    ...
}

@Entity
public class Submission implements Serializable {

    @Id
    private long submissionId;

    ...

    @ManyToOne(fetch=FetchType.LAZY,
        cascade={ CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
    @JoinColumn(name="compoundId")
    private Compound compound;

    ...
}

Я настроил форму (во Flex) для изменения выбранного Соединения. Учитывая вывод формы (класс BlazeDS с именем ObjectProxy, который расширяет HashMap), я отображаю значения из формы на новый объект Compound. Данные о представлении не сохраняются в форме, поэтому список представлений в новом составном объекте остается нулевым.

public Compound decodeWebForm(final ObjectProxy proxy) {
    // create a new compound object
    final Compound c = new Compound();

    // map the proxy values onto the new compound
    c.setCompoundId(proxy.get("compoundId"));
    ...

    return updateCompound(c);
}

Далее я объединяю составной объект, который я построил, в контекст постоянства.

public Compound updateCompound(final Compound c) {
    // retrieve the entity manager
    final EntityManager em = getEntityManager();

    // begin a transaction
    em.getTransaction().begin();

    // merge changes to the managed compound
    final Compound managed = em.merge(c);

    // commit changes to the database
    em.getTransaction().commit();

    return managed;
}

Я специально пропустил директиву CascadeType.MERGE в определениях отношений. Таким образом, когда я вызываю метод EntityManager.merge (Compound), я ожидал, что отсутствие данных представлений будет проигнорировано. Тем не менее, это не тот случай, и любые материалы, относящиеся к Соединению, которое я изменяю, удаляются.

Должно быть, я что-то не так делаю или неправильно понял значение CascadeType.MERGE? Может кто-нибудь помочь, пожалуйста?

Спасибо Джеймс

1 Ответ

2 голосов
/ 23 марта 2012

Две проблемы: 1) Вы пометили отношение с помощью @PrivateOwned, что также должно привести к удалению всех разыменованных объектов.
2) вы объединяете пустую коллекцию.Каскадное слияние (или его отсутствие) означает лишь то, что слияние будет (или не будет) каскадно к сущностям Submissions.Состояние самой коллекции, тем не менее, считается составной частью и поэтому должно быть обновлено в базе данных.В сочетании с # 1 это означает, что материалы будут удалены.Если бы не № 1, в базе данных не было бы никаких изменений (поскольку Submissions владеет отношением и не изменилась), но при чтении сущности Compound она покажет нулевую или пустую коллекцию, если она не будет обновлена.

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

...