PersistenceException:传递给持久化的分离实体

Posted

技术标签:

【中文标题】PersistenceException:传递给持久化的分离实体【英文标题】:PersistenceException: detached entity passed to persist 【发布时间】:2017-04-01 13:08:59 【问题描述】:

我在 *** 上阅读了很多关于同一异常的线程,但我没有找到任何对我真正有帮助的东西,所以我在这里:

我有 2 个实体类:

教师班:

@Entity
@Table(name="teachers")
public class Teacher extends Model

public Teacher()

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

@OneToMany(fetch=FetchType.LAZY, mappedBy="teacher")
private List<Student> students;

//getter and setter

学生班:

@Entity
@Table(name="students")
public class Student extends Model

public Student()
public Student(Teacher teacher)this.teacher = teacher;

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

@ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name="teacher_id")
private Teacher teacher;

//getter and setter

模型类:

public abstract class Model implements Serializable 

public void save() 
EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
entityManager.getTransaction().begin();
entityManager.persist(this);
entityManager.getTransaction().commit();
entityManager.close();


public void merge()
EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
entityManager.getTransaction().begin();
entityManager.merge(this);
entityManager.getTransaction().commit();
entityManager.close();


我创建了一个测试类来将一些值插入到数据库中:

public class TestClass

Teacher teacher;
teacher = new Teacher();

Student student_1;
Student student_2;

student_1 = new Student(teacher);
student_1.save();

student_2 = new Student(teacher);
student_2.save();


student_2.save() 抛出异常(老师是一个分离的实体)。但为什么?我知道,那个老师已经被保留并且交易已经结束,但是 CascadeType.ALL 也包括合并,它应该处理它(或者显然不是......我在这里可能是错的)但是下面的工作:

student_2.merge() 代替 student_2.save() 有效~

另一种解决方案是在坚持学生之前删除 cascadeType.ALL 并坚持教师,但这不是我想要的。

【问题讨论】:

【参考方案1】:

Cascade 的工作方式与您的想法不同。它在相关对象上调用相同的函数。所以如果你打电话给 em.persist(student) 它会打电话给老师坚持。

我认为您可能不想将任何东西从学生级联到老师。如果您在交易中坚持教师,然后仅将其链接到其他交易中的学生,则您没有将任何东西级联到教师。

【讨论】:

哦,我明白了。我使用 cascade 的原因是因为 Student 类可以有一个 List。如果我创建一个没有老师的新学生并稍后分配老师和科目怎么办 - 那么我也只想坚持学生而不做任何其他事情,这需要 CascadeType.ALL (并且基本上说明了为什么我需要让它工作在我的原始帖子中) 您可以稍后将老师添加到学生中,并在没有级联的情况下更新学生,它将很好地保存。请注意,如果您在事务中,您可以在对象上设置道具,它将更新到数据库(无需调用合并..) 对于主题的链接,您需要级联。否则,如果它们是新的,您需要对单个主题调用 save。 好的,谢谢。我找到了解决方法。要将测试值插入数据库,我只需将学生添加到教师列表并保存教师。 CascadeType.ALL 仍然是必需的,因为学生尚未持久化,我会收到异常。当我稍后更新学生时,我可以简单地调用 student.merge(),它也会更新教师列表,因为我包含了 cascadeALL。

以上是关于PersistenceException:传递给持久化的分离实体的主要内容,如果未能解决你的问题,请参考以下文章

javax.persistence.PersistenceException:无法构建实体管理器工厂

Proguard - PersistenceException:构造函数与类不匹配

SimpleXML 转换器的问题 - PersistenceException

JPA javax.persistence.PersistenceException:org.hibernate.MappingException:没有 JDBC 类型的方言映射:-101

线程“主”javax.persistence.PersistenceException 中的异常:org.hibernate.InstantiationException:实体没有默认构造函数:[重复

PersistenceException:没有为名为 default 的持久性单元的模式生成找到持久性提供程序