0

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)

然后继续

4

1 回答 1

0

You may try something like this:

@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);
  }
}

Please note:

  • this is not tested
  • I assumed that your "Language" Entity has a reference to your JobOffer Entity. Although I do not know your domain, this may indicate a bad design
  • If the parameter joboffer is in detached state, then you have to reattach it to the current session (using em.merge()).

Edit: Adapted Query in response to the comment of DataNucleus.

于 2013-10-21T18:05:39.300 回答