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

查看:18
本文介绍了org.hibernate.PersistentObjectException:分离的实体传递给持久化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经成功地用 hibernate 编写了我的第一个主子示例.几天后我又拿了它并升级了一些库.不知道我做了什么,但我永远无法让它再次运行.有人能帮我找出返回以下错误消息的代码有什么问题吗:

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 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>

InvoiceManager.java

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;
    }
}

发票.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

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;
    }
}

从客户端发送的 JSON 对象:

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}]}

一些细节:
我尝试通过以下两种方式保存发票:

Some details:
I have tried to save invoice by following two ways:

  1. 上面提到的手工制作json 对象并将其传递给 fresh服务器会话.在这种情况下绝对在调用之前没有进行任何活动save 方法所以不应该有任何打开的会话除了在save方法中打开的那个

  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

通过使用加载现有数据getInvoice 方法和他们通过相同的删除键值后的数据.这我也相信在另存为之前应该关闭会话事务正在 getInvoice 方法中提交.

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.

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

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.

如果我应该提供更多详细信息,请告诉我

推荐答案

你没有提供很多相关的细节,所以我猜你是调用了 getInvoice 然后你使用了 result 对象来设置一些值并调用 save 并假设您的对象更改将被保存.

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.

然而,persist 操作是为全新的瞬态对象设计的,如果 id 已经分配,​​它就会失败.在您的情况下,您可能想要调用 saveOrUpdate 而不是 persist.

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.

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

You can find some discussion and references here "detached entity passed to persist error" with JPA/EJB code

这篇关于org.hibernate.PersistentObjectException:分离的实体传递给持久化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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