2013-01-06 41 views
1

我遇到了一個問題,當我在ManyToOne關係的多方刪除一條記錄時,它會工作,但在下一個數據庫事務中,我收到一個異常,說我剛刪除的實體沒有找到(例如,當試圖添加另一個鏈接,它說它找不到我剛剛刪除的鏈接)。我在數據庫中驗證記錄正在被刪除。彈出數據JPA JpaObjectRetrievalFailureException在刪除ManyToOne記錄後發生

我使用Spring MVC和Spring數據JPA與Hibernate。我有一個用戶類和一個NewsLink類。用戶可以有很多新聞鏈接,我想刪除其中一個新聞鏈接。我只是通過構建一個簡單的應用程序來學習如何使用Spring框架。所以這對我來說很新。我感謝任何幫助!

用戶實體類

@Entity 
@Table(name = "users") 
public class User implements Serializable{ 

@Id 
@Column(name = "idusers") 
@GeneratedValue(strategy = GenerationType.AUTO)  
private Long id; 

....  

@OneToMany(mappedBy="user", fetch= FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval= true) 
private Set<NewsLink> newsLink; 

新聞鏈接實體類

@Entity 
@Table(name = "news_links") 
public class NewsLink implements Serializable{ 

@Id 
@Column 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(insertable=false, updatable=false) 
private Long idusers; 
.... 

@ManyToOne 
@JoinColumn(name="idusers") 
private User user; 

這是在正在執行的刪除的服務類的方法。我想,這是我沒有做正確的部分:

@Override 
@Transactional 
public User deleteNewsLink(int id, User user){ 

    Iterator<NewsLink> links = user.getNewsLink().iterator(); 

    while(links.hasNext()){ 
     NewsLink link = links.next(); 

     if (link.getId() == id){ 
      links.remove(); 
     } 

    } 

    userRepository.save(user); 

    return user; 
} 

這是我看到了異常:

Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.test.dailyemail.repository.NewsLink with id 8; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.test.dailyemail.repository.NewsLink with id 8 
javax.persistence.EntityNotFoundException: Unable to find com.test.dailyemail.repository.NewsLink with id 8 
at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:155) 
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:210) 
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:260) 
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148) 
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1078) 
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1005) 
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:651) 
at org.hibernate.type.EntityType.resolve(EntityType.java:471) 
at org.hibernate.type.EntityType.replace(EntityType.java:328) 
at org.hibernate.type.CollectionType.preserveSnapshot(CollectionType.java:581) 
at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:534) 
at org.hibernate.type.CollectionType.replace(CollectionType.java:664) 
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:177) 
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:372) 
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:309) 
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151) 
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76) 
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:903) 
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:887) 
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:891) 
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:879) 

回答

4

我不知道,如果這是你的問題,因爲我可以」沒有看到代碼的其餘部分,但我認爲如果您在刪除NewsLink之後仍想使用該對象,則應該返回User實例返回userRepository.save(user)而不是原始用戶對象。

save方法,它說的javadoc的:

保存給定的實體。使用返回的實例進一步操作 ,因爲保存操作可能已完全更改實體實例 。

嘗試類似的東西:

@Override 
@Transactional 
public User deleteNewsLink(int id, User user){ 

    Iterator<NewsLink> links = user.getNewsLink().iterator(); 

    while(links.hasNext()){ 
     NewsLink link = links.next(); 

     if (link.getId() == id){ 
      links.remove(); 
      break; 
     } 

    } 

    return userRepository.save(user); 
} 
0

嘗試調用saveAndFlush從數據庫中刷新的實體。

@Override 
@Transactional 
public User deleteNewsLink(int id, User user){ 

    Iterator<NewsLink> links = user.getNewsLink().iterator(); 

    while(links.hasNext()){ 
     NewsLink link = links.next(); 

     if (link.getId() == id){ 
      links.remove(); 
     } 

    } 

    userRepository.saveAndFlush(user); 

    return user; 
}