удалить объект в отношениях OneToMany - PullRequest
2 голосов
/ 30 октября 2011

Мне трудно понять, какие минимальные усилия требуются с моей стороны для удаления сущности из отношений OneToMany.Я нахожу множество примеров, просто добавляющих сущности к этим наборам (и это хорошо работает), но удалить сущности гораздо сложнее.

У меня есть следующий класс:

@Entity
public class Product {
    ... 
    OneToMany(mappedBy="product", orphanRemoval=true,
              cascade={CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},fetch=FetchType.EAGER)
    Set<Expert> experts = new HashSet<Expert>();
    ...
}

@Entity
public class Expert {
    ...
    @ManyToOne(optional=false)
    Product product;

    @ManyToOne(optional=false)
    Person person;

    ...
}

(Человек похож на продукт)

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

Product aProduct = findAProduct(...);
Expert anExpert aProduct.getExperts.get(...); // Just get the first expert that I want removed
EntityManager em = entityManager();

  em.getTransaction().begin();
  aProduct.getExperts().remove(anExpert);
  em.merge(aProduct);
  em.getTransaction().commit();

или:

  em.getTransaction().begin();
  em.remove(anExpert);
  em.getTransaction().commit();

Это слишком упрощенно?Что делает JPA и что я должен делать сам?Я решил это раньше, просто используя запросы, но я ожидаю, что JPA может сделать это для меня.

Ответы [ 3 ]

1 голос
/ 05 декабря 2011

Исходя из моего прошлого опыта, удаление ребенка в двунаправленных отношениях родитель-ребенок в Hibernate может быть очень сложным.

Вместо этого я обычно использую однонаправленное отображение, т. Е. Продукт не является экспертом.Но вы можете реализовать метод получения, чтобы все эксперты использовали вызов Hibernate.Преимущества:

  1. более простое отображение
  2. более простое кодирование
  3. управляемый behviour

Вы всегда можете вернуться и реализовать кэширование или выполнитьполучение на более поздней стадии.И большую часть времени они являются ненужной предзрелой оптимизацией.

1 голос
/ 19 декабря 2011

Чтобы заставить его работать, нужно было сделать следующее:

EntityManager em = entityManager();
// Retrieve the expert in the new EntityManager context 
Expert expertToDelete = em.find(Expert.class, anExpert.id);

em.getTransaction().begin();
expertToDelete.getProduct().getExperts().remove(expertToDelete);
expertToDelete.getPerson().getExperts().remove(expertToDelete);
em.remove(expertToDelete);
em.getTransaction().commit();

Вполне возможно, что вместо извлечения эксперта с помощью поиска вы можете вместо этого использовать merge () для anExpertно вышеупомянутое, кажется, работает.

1 голос
/ 08 ноября 2011

Попробуйте:

em.getTransaction().begin();
aProduct = em.merge(aProduct);
aProduct.getExperts().remove(anExpert);    
em.getTransaction().commit();

Проблема связана с операцией слияния, а не с удалением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...