org.hibernate.PersistentObjectException:传递给persist的分离实体 [英] org.hibernate.PersistentObjectException: detached entity passed to persist

查看:105
本文介绍了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}]}

编辑:一些细节:

我试图通过以下两种方式保存发票:


  1. 手动制作上面提到的
    json对象并通过它到新鲜
    会话的服务器。在这种情况下,在调用
    save方法之前,绝对
    没有任何活动,因此不应该有任何打开的会话
    ,除了在保存方法中打开的$ <$ li> $


  2. 使用
    getInvoice方法加载现有数据,并在删除键值后传递相同的
    数据。我也相信
    应该在保存之前关闭会话,因为
    事务正在getInvoice方法中提交。


在这两种情况下,我都会得到相同的错误消息,迫使我相信hibernate配置文件或实体类或保存方法有问题。

请让我知道是否应该提供更多详情

你没有提供很多相关的细节,所以我猜你称之为 getInvoice ,然后你使用result对象来设置一些值并调用保存,假设您的对象更改将被保存。但是, persist 操作适用于全新的瞬态对象,并且如果已经分配了id,它将失败。

在你的情况下,你可能想调用 saveOrUpdate 而不是 persist

你可以在这里找到一些讨论和参考分离的实体传递给持久性错误与JPA / EJB代码


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:

  1. Manually fabricated above mentioned json object and passed it to fresh session of server. In this case absolutely no activity has been made prior to calling save method so there should not be any open session except the one opened in save method

  2. Loaded existing data by using getInvoice method and them passed same data after removing key value. This too I believe should close the session before saving as transaction 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的分离实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆