Jpa 从集合中查找和删除项目

Jpa 从集合中查找和删除项目,jpa,collections,Jpa,Collections,我对JPA的方法有以下问题。 我无法从集合中删除项目。 实际上,该方法只有在不是最后插入的元素时才有效。 我错在哪里 这是我的模型的类: @Entity public class JobOffer { @SequenceGenerator(name="JobOffer_Gen", sequenceName="JobOffer_Seq", initialValue=1, allocationSize=1) @Id @GeneratedValue(generator="JobOffer_G

我对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中删除的正确方法是什么

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

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)

然后继续

您可以尝试以下方法:

@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的评论。

请添加错误跟踪的摘录。如果您在集合上进行迭代(使用迭代器,就像使用隐式via for(语言l:joboffer.getLanguages()),则不得修改集合(通过joboffer.getLanguages().remove(l);)mmmm。。。好吧,我明白了。如何从jpa中的集合中删除项目?如何在JobOffer.getLanguages中创建entityManager.find​​()使用迭代器并调用iter.removeThank。成功了。但我的问题也是要知道这样做是否正确,或者是否有一种方法可以搜索集合中的对象,其中实体管理器的FIND作为非法JPQL查询的前缀“SELECT lang”。语言实体没有对JobOffer的引用-(语言)​​是独立的。@DataNucleus:刚刚尝试了一个小示例,效果如预期:em.createQuery(“from Pojo p where p.myNumber=:job_id”,Pojo.class.).setParameter(“job_id”,1.getSingleResult()”;所以不需要选择lang,或者我错过了一些重要的东西吗?user1826663:那么没关系,我没有仔细查看映射;)是的,你错过了一些东西-阅读JPA规范。Hibernate文档描述为有效的JPQL不是(它是“HQL”,并且是特定于供应商的…因此你将应用程序限制在可以使用的地方…这超出了使用标准的范围),用户没有说他们在使用Hibernate的任何地方。我不知道-->+1来指出这一点。据我所知,你是对的;)
@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);
  }
}