当前位置: 首页 > 知识库问答 >
问题:

Hibernate多对多提取方法eager vs lazy

百里业
2023-03-14
@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
  Criteria criteria = session.createCriteria(Group.class);
  return criteria.list();

我从mappgin表(usergroup)中获取所有行,而不是实际的组数...

例如,如果我在用户表中

 username password
 -----------------
 user1     user1
 user2     user2

在组表中

 groupname admin
 ---------------
 grp1      user1
 grp2      user2
 username groupname
 ------------------
 user1     grp1
 user2     grp2
 user1     grp2
 user2     grp1

共有1个答案

宫弘亮
2023-03-14

懒惰的人会告诉您总是反直觉地使用FetchType.Eager。这些人通常不担心数据库性能,只关心让他们的开发生活更轻松。我要说您应该使用fetchType.lazy来提高性能。因为数据库访问通常是大多数应用程序的性能瓶颈,所以每一点都有帮助。

如果您确实需要获取组的用户列表,只要您从事务会话中调用getUsers(),您就不会得到lazyLoadingException,这是所有新Hibernate用户的祸根。

下面的代码将获得所有组,而不需要填充这些组的用户列表

//Service Class
@Transactional
public List<Group> findAll(){
    return groupDao.findAll();
}
//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();
}
//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中通过将连接标准写入集合来完成,但我自己从来没有这样做过。

也就是说,如果您发现对第二个方法的调用远远多于对第一个方法的调用,请考虑将提取类型更改为eaged,并让数据库为您完成这项工作。

 类似资料:
  • 问题内容: hibernate的新手。 我有用户组多对多关系。三个表:User,Group和UserGroup映射表。 实体: 注意,在组实体中,我正在使用获取方法EAGER。现在,当我打电话给DAO时,请使用以下条件来检索系统中的所有组: 我从mappgin表(用户组)获取所有行,而不是获取组的实际数量… 例如,如果我在用户表中 在组表中 在用户组表中 结果将是以下列表-{grp1,grp2,g

  • 我试着调整我的应用程序,所以我把关系变成懒惰的,只取我需要的东西 我的多对一关系有一个问题,当我再次加载实体时转到lazy时,Hibernate将实体替换为代理,即使我获取了该实体,而该代理在应用程序的视图部分(JSF)中不工作。当多对一处于急切模式时,问题就会消失,但hibernate会为每个多对一执行一个select more(选择更多),即使我不需要它们 1/ 2/ JPQL查询: =>两次

  • null 但是在Eclipse中测试它之后,它渴望得到所有的东西。 是否取决于我使用的是JPA还是Hibernate?

  • 问题内容: 我有2个模型。 用户: 汽车: 贴图: 用户: 汽车: HomePageController: 但是当我执行line时: 以下堆栈跟踪出现错误: 我是否构造了错误的映射文件,尤其是多对多关系? 问题答案: 默认情况下,Hibernate将延迟加载集合。换句话说,除非绝对需要,否则它不会进入数据库来检索汽车列表。这意味着从您的dao层返回的对象将不会初始化汽车列表,除非您尝试访问它。当您

  • 场景中,我正在处理用户和方案应用程序。网页用于创建和更新用户。同样,可以创建和更新scheme页面。现在使用hibernate,我与user to scheme表有多对多关系。我已经创建了USER SCHEME和USER\u SCHEME表并保存了它们。 该方案用户数量巨大。现在我有一个条件,如果一个用户更新了他的详细信息,如果他有10个以上的证书,那么在schema网页中,他必须以star aw