26

HibernateでJPAを使用すると、次のコードを実行すると例外が発生しました。初めて実行すると、すべてが正常に実行され、データがデータベースに挿入されます。2回目は、データを更新する必要があるときに失敗します。

@AdminTx
public void processSite(Site site) {
    FluxBoutiqueMapping mapping = mapper.generateMappingFromUrl(site);

    Boutique boutique;
    for (FluxBoutiqueMapping.Boutique fluxBoutique : mapping.getListe().getBoutiques()) {
        log.error("Dans la boucle");
        boutique = daoAdmin.namedQuerySingle(Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());
        log.error("boutique : "+boutique);

        if (boutique==null) {
            log.error("Dans le new");
            boutique = new Boutique();
        }

        boutique.setSite(site);
        boutique.setUrlLogo(fluxBoutique.getLogo());
        boutique.setUrlBoutique(fluxBoutique.getUrl());
        boutique.setSelected(false);
        boutique.setIdWebSC(fluxBoutique.getId());
        boutique.setDateModification(new Date());

        boutiqueDao.persist(boutique);

        boutique = null;
    }
}

boutiqueDao.persist()は、単にEntityManager.persist()メソッドを呼び出します。

そしてここに私のブティッククラス:

@Entity
@Table(name = "BOUTIQUE")
@SequenceGenerator(name = "SEQ_BOUTIQUE", sequenceName = "SEQ_BOUTIQUE")
@NamedQueries(value = {
        @NamedQuery(name = Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, query = "from Boutique b where b.idWebSC=?1"),
})
public class Boutique implements IPersistentObject, IPubliable<Manifestation> {

    /**
     * 
     */
    private static final long serialVersionUID = -3038903536445432584L;

    public static final String LOAD_BOUTIQUE_BY_IDWEBSC = "load.boutique.by.idwebsc";

    protected long idBoutique;

    protected Site site;

    protected Long idOrigine;

    protected String urlLogo;

    protected String urlBoutique;

    protected boolean selected;

    protected long idWebSC;

    protected Date datePublication;

    protected Date dateModification;

    @Override
    @Id
    @GeneratedValue(generator="SEQ_BOUTIQUE")
    @Column(name = "ID_BOUTIQUE", unique = true, nullable = false, precision = 8, scale = 0)
    public Long getId() {
        return this.idBoutique;
    }

    public void setId(Long idBoutique) {
        this.idBoutique = idBoutique;
    }

    @Override
    public void setIdOrigine(Long idOrigine) {
        this.idOrigine = idOrigine;
    }

    @Override
    @Column(name = "IDORIGINE", length = 7)
    public Long getIdOrigine() {
        return this.idOrigine;
    }

    @Override
    @Temporal(TemporalType.DATE)
    @Column(name = "DATE_PUBLICATION", length = 7)
    public Date getDatePublication() {
        return datePublication;
    }

    @Override
    public void setDatePublication(Date datePublication) {
        this.datePublication = datePublication;

    }

    @Override
    @Temporal(TemporalType.DATE)
    @Column(name = "DATE_MODIFICATION", length = 7)
    public Date getDateModification() {
        return dateModification;
    }

    public void setDateModification(Date dateModification) {
        this.dateModification = dateModification;
    }

    @Override
    public void update(Manifestation newer) {
        // TODO Auto-generated method stub

    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_SITE")
    @ForeignKey(name = "FK_BOUTIQUE_SITE")
    public Site getSite() {
        return site;
    }

    public void setSite(Site site) {
        this.site = site;
    }

    @Column(name = "URL_LOGO", length = 255)
    public String getUrlLogo() {
        return urlLogo;
    }

    public void setUrlLogo(String urlLogo) {
        this.urlLogo = urlLogo;
    }

    @Column(name = "URL_BOUTIQUE", length = 255)
    public String getUrlBoutique() {
        return urlBoutique;
    }

    public void setUrlBoutique(String urlBoutique) {
        this.urlBoutique = urlBoutique;
    }

    @Column(name = "SELECTED")
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    @Column(name = "ID_WEBSC", length = 7)
    public long getIdWebSC() {
        return idWebSC;
    }

    public void setIdWebSC(long idWebSC) {
        this.idWebSC = idWebSC;
    }

}

そして最後に、私のスタックトレース:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: fr.u2m.viparis.business.Boutique
        at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:219)
        at fr.u2m.dao.jpa.GenericDaoJPAImpl.persist(GenericDaoJPAImpl.java:60)
        at fr.u2m.viparis.service.impl.BoutiqueService.processSite(BoutiqueService.java:81)
        at fr.u2m.viparis.service.impl.BoutiqueService.processAllFluxBoutique(BoutiqueService.java:52)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:196)
        at $Proxy136.processAllFluxBoutique(Unknown Source)
        at fr.u2m.viparis.fluxboutique.action.FluxBoutiqueAction.loadFlux(FluxBoutiqueAction.java:27)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:270)
        at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:187)
        at fr.u2m.struts.OpenViewRequestProcessor.processJpaActionPerform(OpenViewRequestProcessor.java:270)
        at fr.u2m.struts.OpenViewRequestProcessor.processActionPerform(OpenViewRequestProcessor.java:115)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
        at fr.u2m.struts.OpenViewRequestProcessor.process(OpenViewRequestProcessor.java:230)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
        at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.filter.MultiTabSessionFilter.doFilter(MultiTabSessionFilter.java:75)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.filter.MonitoringFilter.doFilter(MonitoringFilter.java:54)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.viparis.cms.util.auditing.AuditingFilter.doFilter(AuditingFilter.java:44)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at fr.u2m.util.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:71)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: fr.u2m.viparis.business.Boutique
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79)
        at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:38)
        at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
        at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
        at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:213)
        ... 65 more

Tomcat7.0.32サーバーでJava7.0.11を実行しています。

何か案が?

4

2 に答える 2

48

Persist真新しい一時オブジェクトを対象としており、ID が既に割り当てられている場合は失敗します。saveOrUpdateの代わりに呼び出す必要がありpersistます。

または、オブジェクトがエンティティ マネージャーに既に含まれているかどうかを確認できます。含まれている場合は、

entityManager.merge(yourObject);

、そうしないと

entityManager.persist(yourObject);
于 2013-03-04T09:56:36.067 に答える
8

あなたの主な問題は、エンティティを 1 つの DAO にロードしていることです。

boutique = daoAdmin.namedQuerySingle(
    Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());

しかし、それらを別のもので保存します:

boutiqueDao.persist(boutique);

既存のエンティティの場合、エンティティには ID がありますが、2 番目の DAO の作業単位には存在しないため、エンティティの切り離しエラーが発生します。もちろん、読み取り/永続化に同じ DAO を使用したとしても、persist既存のエンティティを保存するために使用することは想定されていないため、問題が発生します。代わりにこれを試してください:

保存に使用するのと同じ DAO を使用してエンティティを読み取ります

Boutique = BoutiqueDAO.namedQuerySingle(Boutique.LOAD_BOUTIQUE_BY_IDWEBSC、fluxBoutique.getId());

新しいブティックの取り扱いを変更して、オブジェクトの即時永続化を行います

if (boutique==null) {
    log.error("Dans le new");
    boutique = new Boutique();
    boutiqueDAO.persist(boutique);
}

最後の持続をマージに変更する

boutique.setIdWebSC(fluxBoutique.getId());
boutique.setDateModification(new Date());

boutique = boutiqueDao.merge(boutique);
于 2013-03-04T10:14:58.267 に答える