javax.persistence.PersistenceException:org.hibernate.persistentObject异常:传递给persistence的分离实体
在Hibernate中使用JPA时,我在运行以下代码时遇到了一个异常。我第一次运行它时,一切正常,数据被插入数据库。第二次,当数据应该更新时,它失败:javax.persistence.PersistenceException:org.hibernate.persistentObject异常:传递给persistence的分离实体,java,hibernate,jpa,persistence,Java,Hibernate,Jpa,Persistence,在Hibernate中使用JPA时,我在运行以下代码时遇到了一个异常。我第一次运行它时,一切正常,数据被插入数据库。第二次,当数据应该更新时,它失败: @AdminTx public void processSite(Site site) { FluxBoutiqueMapping mapping = mapper.generateMappingFromUrl(site); Boutique boutique; for (FluxBoutiqueMapping.Bout
@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;
}
}
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;
}
}
我正在Tomcat7.0.32服务器上运行Java7.0.11
有什么想法吗?
Persist
用于全新的瞬态对象,如果已经分配了id,则会失败。您可能应该调用saveOrUpdate
,而不是persist
或者,您可以检查对象是否已包含在实体管理器中,如果已包含,请执行以下操作:
entityManager.merge(yourObject);
,否则
您的主要问题是在一个DAO中加载实体:
boutique = daoAdmin.namedQuerySingle(
Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());
然后用另一个来保存它们:
boutiqueDao.persist(boutique);
对于现有实体,这将生成分离实体错误,因为该实体具有id,但不存在于第二个DAO的工作单元中。当然,即使在读取/持久化时使用了相同的DAO,也会遇到问题,因为不应该使用persist
保存现有实体。请尝试以下方法:
使用与保存实体时使用的DAO相同的DAO读取实体
精品店=精品店dao.namedQuerySingle(
通过_idwebc,fluxBoutique.getId()加载_精品店_
改变你对新精品店的处理方式,对物品进行即时保存
将最后一个持久化更改为合并
当然persist()仅用于插入。我修改了代码,以便为新对象调用persist(),为现有对象调用merge(),它工作得非常好。非常感谢。不客气。不过,您可以尝试更仔细地查看其他SO线程。我发现至少有3个符合您的问题。我搜索了,但实际上关于该主题的问题太多了。要决定是保留()还是合并(),我需要找出实体管理器中是否已经存在该实体。如何执行此操作?通常未保存实体的id应为0或-1。所以您可以这样做:if(myEntity.getId()>0){entityManager.persist(myEntity);}else{entityManager.merge(myEntity);}
boutique = daoAdmin.namedQuerySingle(
Boutique.LOAD_BOUTIQUE_BY_IDWEBSC, fluxBoutique.getId());
boutiqueDao.persist(boutique);
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);