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

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

问题描述

我创建了一个简单的应用程序,只需使用 Java JPA 向表中插入一行(如果表不存在,创建它)。 b
$ b

我为它的可运行示例附加了一些代码。



这是我得到的异常和堆栈跟踪:

  EXCEPTION  - > org.hibernate.PersistentObjectException:传递给persist的独立实体:view.Person 
javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:传递给persist的独立实体:view.Person
在org.hibernate.jpa .spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl .convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
at view.TestJPA.main(TestJPA.java:34)
导致:org.hibernate.PersistentObjectException:传递给persist的独立实体:view.Person
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org .hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersi
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
... 1更多

以下是我的代码:

主类:

 包视图; 

导入javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class TestJPA {

public static void main(String [] args){

Person p = new Person(1,Peter ,派克);

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(TesePersistentUnit);
EntityManager entityManager = entityManagerFactory.createEntityManager();

EntityTransaction transaction = entityManager.getTransaction();
尝试{
transaction.begin();

entityManager.persist(p);
entityManager.getTransaction()。commit();

catch(Exception e){
if(transaction!= null){
transaction.rollback();
}
System.out.println(EXCEPTION - >+ e.getMessage());
e.printStackTrace();
}
finally {
if(entityManager!= null){
entityManager.close();
}
}
}
}

Person类:

 包视图; 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name =People)
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

私人字符串名称;
private String lastName;

public Person(int id,String name,String lastName){
this.id = id;
this.name = name;
this.lastName = lastName;

$ b $ public Person(){
}
}

这里是我的persistence.xml文件

 <?xml version =1.0encoding = UTF-8\" >?; 
< persistence version =2.1xmlns =http://xmlns.jcp.org/xml/ns/persistencexmlns:xsi =http://www.w3.org/2001/XMLSchema-实例xsi:schemaLocation =http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd\">
< persistence-unit name =TesePersistentUnittransaction-type =RESOURCE_LOCAL>
< provider> org.hibernate.ejb.HibernatePersistence< / provider>
< class> view.Person< / class>
<属性>
<! - SQL方言 - >
< property name =hibernate.dialectvalue =org.hibernate.dialect.MySQLDialect/>

< property name =javax.persistence.jdbc.urlvalue =jdbc:mysql:// localhost:3306 / tese_tabelas?zeroDateTimeBehavior = convertToNull/>
< property name =javax.persistence.jdbc.uservalue =root/>
< property name =javax.persistence.jdbc.drivervalue =com.mysql.jdbc.Driver/>
< property name =javax.persistence.jdbc.passwordvalue =/>

<! - 使用映射元数据自动创建/更新表格 - >
< property name =hibernate.hbm2ddl.autovalue =update/>
< / properties>
< / persistence-unit>
< /余辉>

------------------ -----编辑---------------------------



我只是将提供程序更改为EclipseLink,并且没有进一步的更改。我现在很困惑。为什么它与EclipseLink一起工作,但是使用Hibernate会产生一个异常? 解决方案

尝试使用下面的代码,它会允许你手动设置 ID



只需使用 @Id 注释,它允许您定义哪个属性是实体的标识符。如果您不希望休眠为您生成此属性,则不需要使用 @GeneratedValue 注释。

赋值 - 让应用程序在 save()被调用。如果未指定< generator> 元素,则这是默认策略。

 包视图; 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name =People)
public class Person {
@Id
// @ GeneratedValue(strategy = GenerationType。 AUTO)//注释手动设置ID
private int id;

私人字符串名称;
private String lastName;

public Person(int id,String name,String lastName){
this.id = id;
this.name = name;
this.lastName = lastName;

$ b $ public Person(){
}
}


I'm creating a simple app to just insert a row to a table (if table does not exist, create it) using Java JPA.

I'm attaching some code for a runnable example of it.

Here's the exception I'm getting and the stacktrace:

EXCEPTION -- > org.hibernate.PersistentObjectException: detached entity passed to persist: view.Person
javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: view.Person
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
    at view.TestJPA.main(TestJPA.java:34)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: view.Person
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
    ... 1 more

And here is my code:

Main class:

package view;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class TestJPA {

    public static void main(String[] args) {

        Person p = new Person(1, "Peter", "Parker");

        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("TesePersistentUnit");
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        EntityTransaction transaction = entityManager.getTransaction();
        try {
            transaction.begin();

            entityManager.persist(p);
            entityManager.getTransaction().commit();
        } 
        catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            System.out.println("EXCEPTION -- > " + e.getMessage());
            e.printStackTrace();
        } 
        finally {
            if (entityManager != null) {
                entityManager.close();
            }
        }
    }
}

And the Person class:

package view;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "People")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;
    private String lastName;

    public Person(int id, String name, String lastName) {
        this.id = id;
        this.name = name;
        this.lastName = lastName;
    }

    public Person() {
    }
}

And here's my persistence.xml file

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="TesePersistentUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>view.Person</class>
        <properties>
            <!-- SQL dialect -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/tese_tabelas?zeroDateTimeBehavior=convertToNull"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.password" value=""/>

            <!-- Create/update tables automatically using mapping metadata -->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

----------------------- EDIT ---------------------------

I just changed the provider to EclipseLink and with no further changes it is working. I'm confused now. Why does it works with EclipseLink but with Hibernate it generates an exception?

解决方案

Try with the below code then, it will allow you to set the ID manually.

Just use the @Id annotation which lets you define which property is the identifier of your entity. You don't need to use the @GeneratedValue annotation if you do not want hibernate to generate this property for you.

assigned - lets the application to assign an identifier to the object before save() is called. This is the default strategy if no <generator> element is specified.

package view;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "People")
public class Person {
    @Id
    //@GeneratedValue(strategy = GenerationType.AUTO) // commented for manually set the id
    private int id;

    private String name;
    private String lastName;

    public Person(int id, String name, String lastName) {
        this.id = id;
        this.name = name;
        this.lastName = lastName;
    }

    public Person() {
    }
}

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

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