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
Tomcat 7.0.32サーバーでJava 7.0.11を実行しています。
何か案が?
Persist
は、新しい一時オブジェクトを対象としており、IDが既に割り当てられている場合は失敗します。おそらくsaveOrUpdate
の代わりにpersist
を呼び出す必要があります。
または、オブジェクトが既にエンティティマネージャーに含まれているかどうかを確認できます。含まれている場合は、
entityManager.merge(yourObject);
、その他
entityManager.persist(yourObject);
主な問題は、1つのDAOにエンティティをロードしていることです。
boutique = daoAdmin.namedQuerySingle(
Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());
しかし、それらを別のもので保存します:
boutiqueDao.persist(boutique);
既存のエンティティの場合、エンティティにはIDがありますが、2番目のDAOの作業単位には存在しないため、これは分離エンティティエラーを生成します。もちろん、読み取り/永続化に同じDAOを使用した場合でも、persist
を使用して既存のエンティティを保存することは想定されていないため、問題が発生します。代わりにこれを試してください:
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);