Как удалить записи в отношениях JPA @ManyToMany?

Я определил однонаправленное отношение ManyToMany следующим образом:

@Entity
@Table(name = "ODE_PROCESS_INSTANCE")
Public class ProcessInstanceDAOImpl extends OpenJPADAO implements ProcessInstanceDAO {
  @Id
  @Column(name = "ID")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long _instanceId;

  @ManyToMany(targetEntity = PolicyAttachmentDAOImpl.class)
  private Collection<PolicyAttachmentDAO> _policyAttachments = new ArrayList<PolicyAttachmentDAO>();

  public ProcessInstanceDAOImpl() {
  }

  public Collection<PolicyAttachmentDAO> getPolicyAttachments(){
    return _policyAttachments;
  }

  public void setPolicyAttachments(Collection<PolicyAttachmentDAO> policyAttachments){
    _policyAttachments = policyAttachments;
    getEM().merge(this);
    getEM().flush();
  }
}

@Entity
@Table(name = "ODE_POLICY_ATTACHMENT")
public class PolicyAttachmentDAOImpl extends OpenJPADAO implements PolicyAttachmentDAO{
  @Id
  @Column(name = "POLICYATTACHMENT_ID")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long _attachmentId;

  @Basic
  @Column(name = "POLICYATTACHMENT_NAME")
  private String _attachmentName;

  public PolicyAttachmentDAOImpl(String policyAttachmentName) {
    _attachmentName = policyAttachmentName;
  }

  public void deletePolicyAttachment(){
    //delete policy attachment DAO
getEM().remove(this);
getEM().flush();
  }
}

Таблица соединений создана. Проблема в том, что когда я удаляю запись из ODE_POLICY_ATTACHMENT, таблица соединений не обновляется. Как я могу решить эту проблему?

Вот как я добавляю к та

Collection<PolicyAttachmentDAO> policyAttachments = new ArrayList<PolicyAttachmentDAO>();

attachmentDAO = new PolicyAttachmentDAOImpl("attachment_1");
policyAttachments.add(attachmentDAO);

attachmentDAO = new PolicyAttachmentDAOImpl("attachment_2");
policyAttachments.add(attachmentDAO);

attachmentDAO = new PolicyAttachmentDAOImpl("attachment_3");
policyAttachments.add(attachmentDAO);

//inst is an exisiting ProcessInstanceDAOImpl
inst.setPolicyAttachments(policyAttachments);

Чтобы удалить запись из таблицы «ODE_PROCESS_INSTANCE», я вызываю метод deletePolicyAttachment() для объекта PolicyAttachmentDAOImpl.


person Peter    schedule 07.02.2014    source источник
comment
Вы уверены, что table не обновляется или runtime relationships между объектами? Потому что в JPA программист отвечает за управление runtime relationships сущностями. Это будет полезно: blog.xebia.com/ 16.03.2009/   -  person Svetlin Zarev    schedule 07.02.2014


Ответы (1)


Таблица соединений — это то, что отображает ассоциацию «многие ко многим». Это то, что позволяет Hibernate знать, что какое-то вложение связано с каким-то процессом. Итак, если вы не хотите, чтобы вложение упоминалось в таблице соединения, это означает, что вы больше не хотите, чтобы вложение было связано с каким-либо процессом. Итак, ответ прост: найти все процессы, имеющие вложение в своей коллекции, и удалить вложение из их коллекции:

process.getPolicyAttachments().remove(theAttachment);

Примечание: ваше имя ужасно. Предварительное подчеркивание к полям не является стандартным соглашением и заставит вас добавлять это начальное подчеркивание во все ваши запросы. А то, что у вас есть, это не DAO, а сущности. DAO — это объекты, используемые для запроса и обновления баз данных. Сущности — это постоянные объекты, возвращаемые DAO. И вы не должны сливать и сбрасывать каждый раз, когда вы меняете вложения процесса. Слияние требуется редко, а сброс почти никогда, и в любом случае это не должна делать сущность, которая вообще не должна обращаться к EM.

person JB Nizet    schedule 07.02.2014
comment
Я начинающий. Верно ли то, что вы написали, если я использую OpenJPA вместо Hibernate? Что я должен использовать вместо слияния и сброса при изменении вложений экземпляра процесса? Я сделал это так, потому что использовал пример отсюда blog.jbaysolutions.com/2012/12/17/ - person Peter; 07.02.2014
comment
JPA есть JPA. Да, это действительно. Вы не должны ничего использовать. слияние используется для копирования состояния отсоединенного объекта в присоединенный объект. Это не тот случай здесь. flush() используется, чтобы заставить механизм JPA выполнять все свои запросы на вставку, обновление и удаление сейчас, вместо того, чтобы ждать, пока он не сделает это, когда это необходимо, автоматически. - person JB Nizet; 07.02.2014