JPA映射多个到一个已传递的已删除实体持久化

时间:2013-11-30 12:12:11

标签: java hibernate jpa hibernate-mapping

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

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

在学生中我尝试过:

@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>() ;

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

首先,我测试时未创建任何缺勤或付款对象。

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

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

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

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(学生); dint工作,我使用手动删除学生。如果我添加缺席,预计下面的代码不起作用。真正的问题是为什么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();
    }

1 个答案:

答案 0 :(得分:0)

orphanRemoval = true选项仅适用于JPA 2.如果使用旧版本,则需要尝试不推荐使用的Hibernate注释:

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

查看following question的答案。

对于你DAO,我会做类似的事情:

  

@Component     公共类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);
}
     

}