本文介绍了org.hibernate.PersistentObjectException:传递给persist的分离实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我已经用hibernate成功写下了我的第一个主子例子。几天后,我又拿了一遍,升级了一些图书馆。不知道我做了什么,但我永远不能让它再次运行。有人会帮我找出错误信息返回的代码有什么问题:
org.hibernate.PersistentObjectException:detached entity传递给persist:example.forms.InvoiceItem
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java :799)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
....(截断)
hibernate映射:
< hibernate-mapping package =示例者,恕不>
< class name =Invoicetable =Invoices>
< id name =idtype =long>
< generator class =native/>
< / id>
< property name =invDatetype =timestamp/>
< property name =customerIdtype =int/>
< set cascade =allinverse =truelazy =truename =itemsorder-by =id>
< key column =invoiceId/>
< / set>
< / class>
< class name =InvoiceItemtable =InvoiceItems>
< id column =idname =itemIdtype =long>
< generator class =native/>
< / id>
< property name =productIdtype =long/>
< property name =packnametype =string/>
< property name =quantitytype =int/>
< property name =pricetype =double/>
< / class>
< / hibernate-mapping>
编辑: InvoiceManager.java
class InvoiceManager {
public long save(Invoice theInvoice)throws RemoteException {
Session session = HbmUtils.getSessionFactory()。getCurrentSession ();
Transaction tx = null;
Long id = null;
尝试{
tx = session.beginTransaction();
session.persist(theInvoice);
tx.commit();
id = theInvoice.getId();
} catch(RuntimeException e){
if(tx!= null)
tx.rollback();
e.printStackTrace();
抛出新的RemoteException(发票无法保存);
} finally {
if(session.isOpen())
session.close();
}
return id;
公共发票getInvoice(Long cid)抛出RemoteException {
Session session = HbmUtils.getSessionFactory()。getCurrentSession();
Transaction tx = null;
发票theInvoice = null;
尝试{
tx = session.beginTransaction();
Query q = session
.createQuery(
从发票作为发票+
left join fetch invoice.items as invoiceItems+
where invoice.id =:id)
.setReadOnly(true);
q.setParameter(id,cid);
theInvoice =(发票)q.uniqueResult();
tx.commit();
} catch(RuntimeException e){
tx.rollback();
} finally {
if(session.isOpen())
session.close();
}
返回发票;
$ / code $ / pre>
Invoice.java
public class Invoice implements java.io.Serializable {
private Long id;
私人日期invDate;
private int customerId;
private Set< InvoiceItem>项目;
public Long getId(){
return id;
}
public Date getInvDate(){
return invDate;
}
public int getCustomerId(){
return customerId;
}
public Set< InvoiceItem> getItems(){
返回项目;
}
void setId(Long id){
this.id = id;
}
void setInvDate(Date invDate){
this.invDate = invDate;
}
void setCustomerId(int customerId){
this.customerId = customerId;
}
void setItems(Set< InvoiceItem> items){
this.items = items;
}
}
InvoiceItem.java
public class InvoiceItem implements java.io.Serializable {
private long itemId;
私人长期产品ID;
private String packname;
private int数量;
私人双重价格;
私人发票发票;
public Long getItemId(){
return itemId;
}
public long getProductId(){
return productId;
}
public String getPackname(){
return packname;
}
public int getQuantity(){
return quantity;
}
public double getPrice(){
return price;
}
公共发票getInvoice(){
返回发票;
}
void setItemId(Long itemId){
this.itemId = itemId;
}
void setProductId(long productId){
this.productId = productId;
}
void setPackname(String packname){
this.packname = packname;
}
void setQuantity(int quantity){
this.quantity = quantity;
}
void setPrice(double price){
this.price = price;
}
void setInvoice(Invoice invoice){
this.invoice = invoice;
}
}
编辑: JSON对象从客户端发送:
{id:null,customerId:3,invDate:2005-06- 07T04:00:00.000Z,items:[
{itemId:1,productId:1,quantity:10,price:100},
{itemId :2,productId:2,quantity:20,price:200},
{itemId:3,productId:3,quantity:30,price: 300}]}
编辑:一些细节:
我试图通过以下两种方式保存发票:
-
手动制作上面提到的
json对象并通过它到新鲜
会话的服务器。在这种情况下,在调用
save方法之前,绝对
没有任何活动,因此不应该有任何打开的会话
,除了在保存方法中打开的$ <$ li> $
-
使用
getInvoice方法加载现有数据,并在删除键值后传递相同的
数据。我也相信
应该在保存之前关闭会话,因为
事务正在getInvoice方法中提交。
在这两种情况下,我都会得到相同的错误消息,迫使我相信hibernate配置文件或实体类或保存方法有问题。
请让我知道是否应该提供更多详情
你没有提供很多相关的细节,所以我猜你称之为 getInvoice
,然后你使用result对象来设置一些值并调用保存
,假设您的对象更改将被保存。但是, persist
操作适用于全新的瞬态对象,并且如果已经分配了id,它将失败。
在你的情况下,你可能想调用 saveOrUpdate
而不是 persist
。
你可以在这里找到一些讨论和参考
I had successfully written my first master child example with hibernate. After few days I took it again and upgraded some libraries. No sure what did I do but I could never make it run again. Would somebody help my figure out what is wrong in code that is returning following error message:
org.hibernate.PersistentObjectException: detached entity passed to persist: example.forms.InvoiceItem
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:799)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:791)
.... (truncated)
hibernate mapping:
<hibernate-mapping package="example.forms">
<class name="Invoice" table="Invoices">
<id name="id" type="long">
<generator class="native" />
</id>
<property name="invDate" type="timestamp" />
<property name="customerId" type="int" />
<set cascade="all" inverse="true" lazy="true" name="items" order-by="id">
<key column="invoiceId" />
<one-to-many class="InvoiceItem" />
</set>
</class>
<class name="InvoiceItem" table="InvoiceItems">
<id column="id" name="itemId" type="long">
<generator class="native" />
</id>
<property name="productId" type="long" />
<property name="packname" type="string" />
<property name="quantity" type="int" />
<property name="price" type="double" />
<many-to-one class="example.forms.Invoice" column="invoiceId" name="invoice" not-null="true" />
</class>
</hibernate-mapping>
EDIT: InvoiceManager.java
class InvoiceManager {
public Long save(Invoice theInvoice) throws RemoteException {
Session session = HbmUtils.getSessionFactory().getCurrentSession();
Transaction tx = null;
Long id = null;
try {
tx = session.beginTransaction();
session.persist(theInvoice);
tx.commit();
id = theInvoice.getId();
} catch (RuntimeException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
throw new RemoteException("Invoice could not be saved");
} finally {
if (session.isOpen())
session.close();
}
return id;
}
public Invoice getInvoice(Long cid) throws RemoteException {
Session session = HbmUtils.getSessionFactory().getCurrentSession();
Transaction tx = null;
Invoice theInvoice = null;
try {
tx = session.beginTransaction();
Query q = session
.createQuery(
"from Invoice as invoice " +
"left join fetch invoice.items as invoiceItems " +
"where invoice.id = :id ")
.setReadOnly(true);
q.setParameter("id", cid);
theInvoice = (Invoice) q.uniqueResult();
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
} finally {
if (session.isOpen())
session.close();
}
return theInvoice;
}
}
Invoice.java
public class Invoice implements java.io.Serializable {
private Long id;
private Date invDate;
private int customerId;
private Set<InvoiceItem> items;
public Long getId() {
return id;
}
public Date getInvDate() {
return invDate;
}
public int getCustomerId() {
return customerId;
}
public Set<InvoiceItem> getItems() {
return items;
}
void setId(Long id) {
this.id = id;
}
void setInvDate(Date invDate) {
this.invDate = invDate;
}
void setCustomerId(int customerId) {
this.customerId = customerId;
}
void setItems(Set<InvoiceItem> items) {
this.items = items;
}
}
InvoiceItem.java
public class InvoiceItem implements java.io.Serializable {
private Long itemId;
private long productId;
private String packname;
private int quantity;
private double price;
private Invoice invoice;
public Long getItemId() {
return itemId;
}
public long getProductId() {
return productId;
}
public String getPackname() {
return packname;
}
public int getQuantity() {
return quantity;
}
public double getPrice() {
return price;
}
public Invoice getInvoice() {
return invoice;
}
void setItemId(Long itemId) {
this.itemId = itemId;
}
void setProductId(long productId) {
this.productId = productId;
}
void setPackname(String packname) {
this.packname = packname;
}
void setQuantity(int quantity) {
this.quantity = quantity;
}
void setPrice(double price) {
this.price = price;
}
void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
}
EDIT: JSON object sent from client:
{"id":null,"customerId":3,"invDate":"2005-06-07T04:00:00.000Z","items":[
{"itemId":1,"productId":1,"quantity":10,"price":100},
{"itemId":2,"productId":2,"quantity":20,"price":200},
{"itemId":3,"productId":3,"quantity":30,"price":300}]}
EDIT: Some details:
I have tried to save invoice by following two ways:
Manually fabricated above mentionedjson object and passed it to freshsession of server. In this case absolutelyno activity has been made prior to callingsave method so there should not be any open sessionexcept the one opened in save method
Loaded existing data by usinggetInvoice method and them passed samedata after removing key value. This too I believeshould close the session before saving astransaction is being committed in getInvoice method.
In both cases I am getting same error message that is forcing me to believe that something is wrong either with hibernate configuration file or entity classes or save method.
Please let me know if I should provide more details
解决方案
You didn't provide many relevant details so I will guess that you called getInvoice
and then you used result object to set some values and call save
with assumption that your object changes will be saved.
However, persist
operation is intended for brand new transient objects and it fails if id is already assigned. In your case you probably want to call saveOrUpdate
instead of persist
.
You can find some discussion and references here "detached entity passed to persist error" with JPA/EJB code
这篇关于org.hibernate.PersistentObjectException:传递给persist的分离实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!