因此,我发现自己在Hibernate方面陷入了相当的困境。当我开始开发我的web应用程序时,我在任何地方都使用“渴望”加载,这样我就可以轻松地访问孩子、父母等。
过了一段时间,我遇到了我的第一个问题--重新保存已删除的对象。多个堆栈溢出线程建议我应该从它所在的所有集合中删除该对象。阅读这些建议让我感到“蜘蛛式的感觉”,因为我的关系并不是真的很简单,我不得不迭代多个对象,这让我的代码看起来有点丑陋,让我怀疑这是不是最好的方法。
例如,删除员工时(从某种意义上说,该员工属于用户,用户可以充当多个不同的员工)。假设员工可以将反馈留给Party,这样员工可以有多个反馈,Party也可以有多个反馈。此外,Employee和Party都属于某种父对象,比如说Organization。基本上,我们有:
class User {
// Has many
Set<Employee> employees;
// Has many
Set<Organization> organizations;
// Has many through employees
Set<Organization> associatedOrganizations;
}
class Employee {
// Belongs to
User user;
// Belongs to
Organization organization;
// Has many
Set<Feedback> feedbacks;
}
class Organization {
// Belongs to
User user;
// Has many
Set<Employee> employees;
// Has many
Set<Party> parties;
}
class Party {
// Belongs to
Organization organization;
// Has many
Set<Feedback> feedbacks;
}
class Feedback {
// Belongs to
Party party;
// Belongs to
Employee employee;
}以下是我在删除员工时得到的结果:
// First remove feedbacks related to employee
Iterator<Feedback> iter = employee.getFeedbacks().iterator();
while (iter.hasNext()) {
Feedback feedback = iter.next();
iter.remove();
feedback.getParty().getFeedbacks().remove(feedback);
session.delete(feedback);
}
session.update(employee);
// Now remove employee from organization
Organization organization = employee.getOrganization();
organization.getEmployees().remove(employee);
session.update(organization);根据我的定义,这是丑陋的。我会假设通过使用
@Cascade({CascadeType.ALL})然后Hibernate会神奇地将Employee从所有关联中删除,只需执行以下操作:
session.delete(employee);相反,我得到的是:
Error during managed flush [deleted object would be re-saved by cascade (remove deleted object from associations)因此,为了让我的代码更整洁,甚至是优化(有时延迟抓取就足够了,有时我需要渴望),我尝试了延迟抓取几乎所有的东西,并希望如果我这样做了,例如:
employee.getFeedbacks()然后,反馈被很好地获取,没有任何问题,但不是,一切都会崩溃:
failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session我考虑的下一件事是消除对象插入/删除其相关子对象的可能性,但从性能上讲这可能不是一个好主意-使用
child.parent=parent
而不是批量使用
parent.children().add(children)。
最后,我看到许多人推荐创建我自己的自定义查询和东西,但在这一点上,我为什么还要费心使用Hibernate呢?是不是真的没有好的方法来处理我的问题呢?还是我错过了什么,或者我是个笨蛋?
发布于 2016-10-05 19:21:35
如果我没理解错的话,这一切都是关于通过简单的1:N关系进行级联的。在这种情况下,Hibernate可以很好地完成这项工作:
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(cascade = CascadeType.ALL,
mappedBy = "post", orphanRemoval = true)
private List<Comment> comments = new ArrayList<>();
}
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne
private Post post;
}代码:
Post post = newPost();
doInTransaction(session -> {
session.delete(post);
});生成:
delete from Comment where id = 1
delete from Comment where id = 2
delete from Post where id = 1但是如果你有一些其他的(合成的)集合,Hibernate没有机会知道是哪一个,所以你必须自己处理它们。
对于Hibernate和自定义查询,Hibernate提供了HQL,它比传统SQL更紧凑,但仍不如注释透明。
https://stackoverflow.com/questions/39872070
复制相似问题