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

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

我有 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 并坚持教师,但这不是我想要的。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

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

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

    【讨论】:

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