hibernate的新手。
我有用户组多对多关系。三个表:User,Group和UserGroup映射表。
实体:
@Entity
@Table(name = "user")
public class User {
@Id
@Column (name = "username")
private String userName;
@Column (name = "password", nullable = false)
private String password;
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(name="usergroup",
joinColumns={@JoinColumn(name="username")},
inverseJoinColumns={@JoinColumn(name="groupname")})
private Set<Group> userGroups = new HashSet<Group>();
... setter and getters
@Entity
@Table(name = "group")
public class Group {
@Id
@Column(name = "groupname")
private String groupName;
@Column(name = "admin", nullable = false)
private String admin;
@ManyToMany(mappedBy = "userGroups", fetch = FetchType.EAGER)
private Set<User> users = new HashSet<User>();
... setter and getters
注意,在组实体中,我正在使用获取方法EAGER。现在,当我打电话给DAO时,请使用以下条件来检索系统中的所有组:
Criteria criteria = session.createCriteria(Group.class);
return criteria.list();
我从mappgin表(用户组)获取所有行,而不是获取组的实际数量…
例如,如果我在用户表中
username password
-----------------
user1 user1
user2 user2
在组表中
groupname admin
---------------
grp1 user1
grp2 user2
在用户组表中
username groupname
------------------
user1 grp1
user2 grp2
user1 grp2
user2 grp1
结果将是以下列表-{grp1,grp2,grp2,grp1}
代替{grp1,grp2}
如果我将组实体的获取方法更改为LAZY,我将获得正确的结果,但是hibernate将LazyException抛出到另一个地方…
请协助我使用哪种提取方法,为什么?
谢谢!
懒惰的人会告诉你要始终FetchType.EAGER
凭直觉来使用。这些人通常不担心数据库性能,只关心使开发工作更轻松。我要说的是您应该利用它FetchType.LAZY
来提高性能。由于数据库访问通常是大多数应用程序的性能瓶颈,因此一点点帮助。
如果确实需要获取组的用户列表,只要您getUsers()
在事务会话中进行呼叫,就不会得到LazyLoadingException
所有新Hibernate用户的麻烦。
以下代码将为您提供所有组,而无需填充这些组的用户列表
//Service Class
@Transactional
public List<Group> findAll(){
return groupDao.findAll();
}
以下代码将为您提供DAO级别的所有组的用户:
//DAO class
@SuppressWarnings("unchecked")
public List<Group> findAllWithUsers(){
Criteria criteria = getCurrentSession().createCriteria(Group.class);
criteria.setFetchMode("users", FetchMode.SUBSELECT);
//Other restrictions here as required.
return criteria.list();
}
编辑1:感谢Adrian Shum的这段代码
有关不同类型的FetchMode
的更多信息,请参见此处
如果您不想只为访问集合对象而编写其他DAO方法,只要您与Session
用于获取父对象的对象相同,则可以使用该Hibernate.initialize()
方法来强制初始化子集合宾语。我不建议您List<T>
对父对象执行此操作。这将对数据库造成相当大的负担。
//Service Class
@Transactional
public Group findWithUsers(UUID groupId){
Group group = groupDao.find(groupId);
//Forces the initialization of the collection object returned by getUsers()
Hibernate.initialize(group.getUsers());
return group;
}
我没有遇到必须使用上述代码的情况,但是它应该相对有效。有关更多信息,Hibernate.initialize()
请参见此处
我已经在服务层中完成了此操作,而不是在DAO中获取它们,因为那样的话,您只需要在服务中创建一个新方法,而不必再创建单独的DAO方法。重要的是您已将getUsers()
调用包装在事务中,因此将创建一个会话,Hibernate可以使用该会话来运行其他查询。也可以在DAO中通过向您的集合编写联接条件来完成此操作,但是我从来不必自己做。
就是说,如果您发现调用第二个方法的次数比调用第一个方法的次数多,请考虑将获取类型更改为EAGER
并让数据库为您完成工作。
我从mappgin表(usergroup)中获取所有行,而不是实际的组数... 例如,如果我在用户表中 在组表中
问题内容: SQLAlchemy支持渴望加载关系,这基本上是一条语句。但是,如果模型具有两个或多个关系,则可能是非常庞大的联接。例如, 该查询的性能实在是太差了,因为中和会产生一个巨大的表。但是和在这里没有关系,因此它们不应该是。它应该是两个分开的查询。并且由于会话具有某种程度的缓存,因此我将查询更改为此。 这次的性能要好得多。但是,我不认为这样做是正确的。我不确定会话结束时标签缓存是否会过期。
问题内容: 我有一个我认为应该很普遍的问题,但找不到答案。 我有2个对象:组和用户。我的课程如下所示: 现在,当我尝试从数据库中获取用户时,它带来了所有组,所有组都带来了所有用户,依此类推。最后,我遇到了stackoverflow异常。 如何解决此问题,并且仍然具有双向关联以及到达列表中对象的能力? 问题答案: 如果使用属性(无论如何都应使用)将双向关联的一侧设为关联的 拥有 侧,是否会遇到相同的
场景中,我正在处理用户和方案应用程序。网页用于创建和更新用户。同样,可以创建和更新scheme页面。现在使用hibernate,我与user to scheme表有多对多关系。我已经创建了USER SCHEME和USER\u SCHEME表并保存了它们。 该方案用户数量巨大。现在我有一个条件,如果一个用户更新了他的详细信息,如果他有10个以上的证书,那么在schema网页中,他必须以star aw
在使用Hibernate几年后,问这个问题有点尴尬... 我有一个master_table,它: null
我现在被IFPH第7章的一个问题困住了。 练习7.1.2内容如下: “排序的一个定义是取 详细给出表达式排序[3,4,2,1]的渴望和懒惰求值减少序列,解释它们的区别。” 现在,我先从急切的求值缩减序列开始,我假设它是最内部的缩减。 对我来说,这产生了... 这是已排序的列表。 现在对于惰性评估,我能想到的唯一减少序列与渴望评估完全相同。当然,Haskell对惰性评估进行最左边的最外层评估:但是我