我在两个表User和Keyword之间有很多很多的关系。用户是关系的所有者。如果我删除了一个用户,我首先从这个用户删除所有关键字,然后删除这个用户。这与预期的一样工作。
但我不知道如何删除一个关键字,并自动删除与所有用户的关系。
这里是我到目前为止的代码。
@Entity @Table(name = "user") public class User { @Id @Column(name = "id") @GeneratedValue private Integer id; @Column(name = "name") private String name; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @Fetch(value = FetchMode.SUBSELECT) @JoinTable(name = "user_has_keyword", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "keyword_id")) private List keywords = new ArrayList(); // Getters and setters ... }
@Entity @Table(name = "keyword") public class Keyword { @Id @Column(name = "id") @GeneratedValue private Integer id; @Column(name = "keyword") private String keyword; @ManyToMany(mappedBy = "keywords") private List users = new ArrayList(); // Getters and setters ... }
@Service("myService") @Transactional("transactionManager") public class MyService { @Resource(name = "sessionFactory") private SessionFactory sessionFactory; @SuppressWarnings("unchecked") public List getAllUsers() { Session session = this.sessionFactory.getCurrentSession(); Query query = session.createQuery("FROM User"); return query.list(); } public User getUser(Integer id) { Session session = this.sessionFactory.getCurrentSession(); return (User) session.get(User.class, id); } public void addUser(User user) { Session session = this.sessionFactory.getCurrentSession(); session.save(user); } public void deleteUser(User user) { Session session = this.sessionFactory.getCurrentSession(); // 1st, delete relations user.getKeywords().clear(); session.update(user); // 2nd, delete User object session.delete(user); } public Keyword getKeyword(Integer id) { Session session = this.sessionFactory.getCurrentSession(); return (Keyword) session.get(Keyword.class, id); } public Keyword addKeyword(Keyword keyword) { Session session = this.sessionFactory.getCurrentSession(); session.save(keyword); return keyword; } public void deleteKeyword(Keyword keyword) { Session session = this.sessionFactory.getCurrentSession(); // 1st, delete relations keyword.getUsers().clear(); session.update(keyword); // 2nd, delete User object keyword = getKeyword(keyword.getId()); session.delete(keyword); } }
@Controller public class MyController { @Resource(name = "myService") private MyService myService; @RequestMapping(value = "/add", method = RequestMethod.GET) public String add(Model model) { Keyword k = new Keyword(); k.setKeyword("yellow"); k = myService.addKeyword(k); User u1 = new User(); u1.setName("Bart"); u1.getKeywords().add(k); myService.addUser(u1); User u2 = new User(); u2.setName("Lisa"); u2.getKeywords().add(k); myService.addUser(u2); return "/"; } @RequestMapping(value = "/delete/user", method = RequestMethod.GET) public String deleteUser(Model model) { User u = myService.getUser(1); myService.deleteUser(u); return "/"; } @RequestMapping(value = "/delete/keyword", method = RequestMethod.GET) public String deleteKeyword(Model model) { Keyword k = myService.getKeyword(1); myService.deleteKeyword(k); return "/"; } }
如果浏览到/delete/keyword,则会出现以下异常:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.blabla.prototype.Keyword.users, no session or session was closed
我在谷歌上搜索过,尝试过很多不同的方法,但都不奏效。
我很感激任何帮助。
非常感谢,
马可
LazyInitializationException与删除无关。您正在控制器中加载一个关键字。这使得服务加载关键字,而不初始化其惰性用户列表。然后将此关键字返回到控制器,提交事务,关闭会话,使关键字与会话分离。
然后将这个分离的关键字传递给服务以删除它。因此,该服务接收一个分离的关键字,并尝试访问其用户列表。由于关键字已分离,用户列表尚未加载,这将导致LazyInitializationException。
服务方法应该将要删除的关键字的ID作为参数,加载它,从而处理附加的关键字,然后继续删除。
现在要回答您的问题,您对用户删除做了正确的处理:您从要删除的用户中移除所有关键字,因为该用户是关联的所有者。删除关键字时应用相同的逻辑:从所有引用该关键字的用户中删除该关键字,然后删除该关键字:
public void deleteKeyword(Integer id) {
Keyword keyword = getKeyword(id);
for (User user : keyword.getUsers()) {
user.removeKeyword(keyword);
}
session.delete(keyword);
}
注意,在处理附加实体时不必调用update()。附加实体的状态会自动透明地保存到数据库中。
Django演示了如何设置或覆盖在文档中使用外键的级联删除。 但是如果我们想让这种效果反过来呢?如果我们希望fk模型的删除导致该模型的删除,该怎么办? 谢谢
问题内容: 我有一个包含两列的数据框,并且。在这种情况下,和的顺序并不重要;例如,我会考虑并将其重复。在熊猫中,从数据框中删除这些重复项的有效方法是什么? 理想情况下,输出将按column的值排序。 问题答案: 您可以在删除重复项之前对数据框的每一行进行排序: 如果您希望按列对结果进行排序:
参考阅读:什么是反向Shell 这篇教程将会教你使用Python编写一个反向shell,首先我们先演示使用Python如何利用web服务器的功能,把文件从另一台主机传送过来。我们假设你有一台傀儡主机,你现在想下载傀儡机上面的的文件。那么你就可以使用shell(或meterpreter)去访问这台傀儡机,你可以通过一行Python代码把傀儡机建立成为一个web服务器,然后下载傀儡机上面的文件. 创建
问题内容: 我有一个配对列表: 我想删除任何重复的地方 所以我们最后只是 如果不是这种情况,我可以对反向对进行内部和外部循环检查,然后追加到列表中,但是我敢肯定,有更多的Python方式可以达到相同的结果。 问题答案: 如果您需要保留列表中元素的顺序,则可以使用函数并使用以下方式设置理解: 或根本不像这样: 另一种方法是使用一个如图所示这里但是请注意,如果您的列表中有不同的元素这只是工作。因为li
问题内容: 我在寻找解决方案时遇到了麻烦。我正在尝试使用JS(或其他库)来制作它,以便当用户在鼠标滚轮上向下滚动时,页面以与通常相反的方式滚动。 基本上,我希望页面的底部首先显示,并且随着用户滚动,我希望屏幕的顶部向下显示。我能够找到的唯一示例是http://conduit.com/的右列。 我已经建立了一个JSFiddle并提供了一个示例来帮助对其进行可视化。我知道这可能与以下内容有关: 但老实
问题内容: 我在给像这样的物体 如何将字符串转换回对象? 问题答案: 您需要字符串。