2013-10-28 67 views
0

我最近遇到了一个情况,我必须通过Hibernate会话删除对象时执行一些操作。hibernate EventListener和stackoverflow错误

我不想在实体被删除之前删除单向关系,但下面的代码导致了一个stackoverflow异常。

@Component("emsPreListener") 
public class IntegrationEntityDeleteListener implements PreDeleteEventListener { 

    private static final long serialVersionUID = 2245534615822054792L; 

    @Override 
    @SuppressWarnings("unchecked") 
    public boolean onPreDelete(PreDeleteEvent event) { 

     System.out.println("PRE-DELETE"); 

     Session session = event.getSession(); 

     if (event.getEntity() instanceof Project) { 
      Transaction transaction = null; 
      try 
      { 
       transaction = session.beginTransaction(); 

       Project project = (Project) event.getEntity(); 

       Criteria criteria = session.createCriteria(ProjectPoll.class); 
       criteria.add(Restrictions.eq("project", project)); 
       List<ProjectPoll> polls = criteria.list(); 
       if(polls != null) { 
        for(ProjectPoll projectPoll : polls) { 
         session.delete(projectPoll); 
        } 

        return false; 
       } 
      } 
      catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      finally 
      { 
       if(transaction != null) transaction.commit(); 
      } 

     } 

     return false; 
    } 

} 

这是它与relashonship唯一的实体。

@Entity 
@Table(name = "project_poll") 
@PrimaryKeyJoinColumn(name = "poll_id", referencedColumnName = "id") 
public class ProjectPoll extends Poll { 
    private static final long serialVersionUID = -2230614967405436988L; 

    @ManyToOne(cascade=CascadeType.ALL) 
    @JoinColumn(name = "project_id") 
    private Project project; 

    public Project getProject() { 
     return project; 
    } 

    public void setProject(Project project) { 
     this.project = project; 
    } 
} 

TNX

+0

每个项目有多少个ProjectPoll记录? –

+0

大量的ProjectPoll可能出现在每个项目中。 –

回答

0

你标注了级联= CascadeType.ALL双向关系ProjectPoll.project。删除projectPoll也会删除父项(项目)。这又会再次触发onDeDelete()。尝试去除双向关系中的级联属性。

+0

实体之间的关系不是双向的。架构被设计为尽可能模块化,并且Project处于核心模块中,不能修改。实际上,我使用ProjectService的自定义实现解决了上述问题,但我仍然很想知道为什么Listener不起作用。 –

+0

如果我理解了一个项目可能被分配给许多ProjectPolls。在这种情况下,删除onPreDelete()中的projectPoll也会触发通过级联定义删除Project!在我的未知事件中,这会调用你在同一个项目对象的if() - 子句中的行为!因为你会得到stackoverflow错误。 – Dio

+0

正如我之前所说的,删除级联= CascadeType.ALL可能会帮助你。在我未确定的清晰定义中,删除级联是一种冗余,因为项目实例已被删除。 你需要的仅仅是将引用设置为NULL。尝试projectPoll.setProject(null)而不是session.delete(projectPoll); – Dio