我遇到一个问题,当我删除ManyToOne关系的许多方面的记录时,它有效,但在下一个数据库事务中,我得到一个异常,说明我刚删除的实体未找到(例如,当试图添加时另一个链接,它说它找不到我刚刚删除的那个)。我在数据库中验证了记录被删除。
我正在使用Spring MVC和Spring Data 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;
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)
答案 0 :(得分:4)
我不确定这是不是你的问题,因为我看不到剩下的代码,但我认为你应该返回User
实例返回userRepository.save(user)
而不是原始用户如果在删除NewsLink后仍想使用该对象,则为对象。
在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);
}
答案 1 :(得分: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;
}