2013-10-28 38 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