查找和删除集合中的项目

时间:2013-10-21 16:16:24

标签: jpa collections

我对JPA的方法有以下问题。 我无法从集合中删除项目。 实际上,该方法仅在不是插入的最后一个元素时才有效。 哪里我错了?

这是我的模特课程:

@Entity
public class JobOffer {

  @SequenceGenerator(name="JobOffer_Gen", sequenceName="JobOffer_Seq", initialValue=1, allocationSize=1)
  @Id @GeneratedValue(generator="JobOffer_Gen") @Column(name="ID_JOBOFFER")
  private Long id;

  @Column
  private String title;

    ...

  @OneToMany
  @JoinTable(joinColumns = @JoinColumn(name = "JOBOFFER_IDFK"), inverseJoinColumns = @JoinColumn(name = "LANGUAGE_IDFK"))
  private Collection<Language> languages = new HashSet<Language>();

    ...
}

这是我在JPA中的方法:

@Override
@Transactional
public void deleteLanguage(JobOffer joboffer, Long idLingua) throws BusinessException {
    for(Language l : joboffer.getLanguages()){
        if (l.getId() == idLingua){ 
            joboffer.getLanguages().remove(l);

        }
    }
    em.merge(joboffer);
}

在JPA中搜索集合中的项目并删除的正确方法是什么?

这是我从控制台得到的错误:

21-ott-2013 18.22.27 org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [jobbook] in context with path [/jobbook] threw     exception [Request processing failed; nested exception is       java.util.ConcurrentModificationException] with root cause
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at org.eclipse.persistence.indirection.IndirectList$1.next(IndirectList.java:571)
at it.univaq.mwt.j2ee.jobbook.business.impl.JPAJobOfferService.deleteLanguage(JPAJobOfferService.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)

然后继续

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

@Override
@Transactional
public void deleteLanguage(JobOffer joboffer, Long idLingua) throws BusinessException {
  Language language = em.createQuery("SELECT lang from Language lang where lang.jobOffer.id = :job_id", Language.class).setParameter("job_id", joboffer.getId()).getSingleResult();
  if(language != null){
    joboffer.getLanguages().remove(language);
  }
}

请注意:

  • 未经测试
  • 我假设您的“语言”实体引用了您的JobOffer实体。虽然我不了解您的域名,但可能表示设计不合理
  • 如果参数joboffer处于分离状态,则必须将其重新连接到当前会话(使用em.merge())。

编辑:改编查询以响应DataNucleus的评论。