【问题标题】:JPA mapping many to one Deleted entity passed to persistJPA 映射多对一已删除的实体传递给持久化
【发布时间】:2013-12-16 11:54:12
【问题描述】:

我的基本域模型如下所示:

我的问题存在于其他实体和出勤实体之间的映射。

在学生中我尝试过:

@OneToMany(orphanRemoval=true,mappedBy = "student",cascade= CascadeType.ALL) 
    //@Cascade(org.hibernate.annotations.CascadeType.ALL)
    private Set<Attendance> attendance = new HashSet<Attendance>() ; 

关于出勤:

@ManyToOne( cascade= {CascadeType.PERSIST, CascadeType.MERGE} )
    //@Cascade(org.hibernate.annotations.CascadeType.PERSIST)
    @JoinColumn(name="studentId", nullable = true)
    private Student student;

    @OneToMany(mappedBy = "attendance",cascade=CascadeType.ALL)  
    private Set<Absence> absence = new HashSet<Absence>() ; 

    @ManyToOne()
    @JoinColumn(name="seminarId", nullable = false)
    private Seminar seminar;

    @OneToMany(mappedBy = "attendance",cascade=CascadeType.ALL)  
    private Set<Payment> payment = new HashSet<Payment>() ;

我遇到的问题是删除学生(或研讨会)。 我想要做的是,当一个学生被删除时,他/她的所有出勤也必须被删除。

首先我在没有创建任何 Absence 或 payment 对象的情况下进行了测试。

如果我删除级联选项,我会得到以下跟踪

java.lang.IllegalStateException: org.hibernate.TransientObjectException: object is an unsaved transient instance - save the transient instance before merging: com.seminars.domain.Attendance

如果我离开级联选项并尝试调用 em.remove(student) 我会得到

javax.persistence.RollbackException: Error while committing the transaction
    ..........
Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.seminars.domain.Student#<null>]

如果最重要的是,我尝试在出勤中添加缺勤,我仍然会得到与上述相同的结果(即使有人告诉我,即使学生被移除,其他东西也会中断)

我开始相信域模型是完全错误的...... 甚至可以用 JPA 和 hibernate 做我想做的事吗? 在我的情况下,我需要设置哪些正确的映射选项? (注意:我也尝试了this answer 中显示的内容,但后来我遇到了缺勤问题

java.lang.IllegalStateException: org.hibernate.TransientObjectException: object is an unsaved transient instance - save the transient instance before merging: com.seminars.domain.Attendance

我完全迷路了,任何帮助将不胜感激

编辑: 以下是删除学生的方法(请注意,由于 em.remove(student); 有效,我采取了手动删除学生的方法。如果我添加了缺勤,预计下面的代码将不起作用。真正的问题是为什么 em.remove() 不起作用,以及必须设置哪些正确的映射才能使其起作用)

public void Delete(Object object) {
        int id=(Integer) object;
        if (!tx.isActive()) {
            tx.begin();
        } 
        Attendance att = em.find(Attendance.class, student.getStudentId());

        Query query = em.createQuery( "DELETE FROM Attendance c WHERE c.student = :id");
        query.setParameter("id", student);
        query.executeUpdate();
        em.clear();
        //findObject(null, id,null);
        //student=em.merge(student);
        //em.persist(student);
        student=em.find(Student.class, id);
        query = em.createQuery( "DELETE FROM Student c WHERE c.studentId = :id");
        query.setParameter("id", id);
        query.executeUpdate();
        //em.remove(student);

        tx.commit();
        //em.clear();
    }

【问题讨论】:

  • 显示您的删除代码
  • 感谢您的回复。我添加了用于删除学生的代码(我这样做了,并且在将缺勤添加到等式之前它起作用了)
  • 这真的让我发疯了.. 任何可以提供帮助的东西都是受欢迎的,即使是您认为无用的想法也可能对我有所帮助。欢迎一切可能有帮助的东西:)

标签: java hibernate jpa hibernate-mapping


【解决方案1】:

orphanRemoval=true 选项仅适用于 JPA 2。如果您使用的是旧版本,您想尝试已弃用的 Hibernate 注释:

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

查看following question的答案。

对于你的 DAO,我会做这样的事情:

@组件 公共类 GenericDao {

@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

public <T> T save(final T o){
  return (T) sessionFactory.getCurrentSession().save(o);
}

public void delete(final Object object){
  sessionFactory.getCurrentSession().delete(object);
}

public <T> T get(final Class<T> type, final Long id){
  return (T) sessionFactory.getCurrentSession().get(type, id);
}

public <T> T merge(final T o)   {
  return (T) sessionFactory.getCurrentSession().merge(o);
}

}

【讨论】:

    猜你喜欢
    • 2014-11-22
    • 1970-01-01
    • 2017-05-10
    • 2018-05-25
    • 1970-01-01
    • 2013-06-26
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多