加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用太多内存的Hibernate关联

发布时间:2020-12-14 05:45:36 所属栏目:Java 来源:网络整理
导读:我有一个表“类”,与表“学生”和“老师”相关联. “类”通过关系关系与多位学生和老师联系起来. 当我使用hibernate关联并获取大量实体(尝试5000)时,我看到它比使用外键占位符占用了4倍多的内存. hibernate协会有什么问题吗? 我可以使用任何内存分析器找出
我有一个表“类”,与表“学生”和“老师”相关联.
“类”通过关系关系与多位学生和老师联系起来.

当我使用hibernate关联并获取大量实体(尝试5000)时,我看到它比使用外键占位符占用了4倍多的内存.
hibernate协会有什么问题吗?

我可以使用任何内存分析器找出使用太多内存的内容吗?

这是模式如何:

class(id,className) 

student(id,studentName,class_id)
teacher(id,teacherName,class_id)

class_id is foreign key..

案例1 – Hibernate协会

1)在类实体中,将学生和教师映射为:

@Entity
@Table(name="class")
public class Class {

private Integer id;
private String className;

private Set<Student> students = new HashSet<Student>();
private Set<Teacher> teachers = new HashSet<Teacher>();

@OneToMany(fetch = FetchType.EAGER,mappedBy = "classRef")
@Cascade({ CascadeType.ALL })
@Fetch(FetchMode.SELECT)
@BatchSize(size=500)
public Set<Student> getStudents() {
    return students;
}

2)在学生和教师中,映射班为:

@Entity
@Table(name="student")
public class Student {

private Integer id;
private String studentName;
private Class classRef;

@ManyToOne
@JoinColumn(name = "class_id")
public Class getClassRef() {
    return classRef;
}

使用查询:

sessionFactory.openSession().createQuery("from Class where id<5000");

然而,这是一个巨大的记忆.

案例#2-删除关联并单独提取

1)在类实体中没有映射

@Entity
@Table(name="class")
public class Class {

private Integer id;
private String className;

2)只有学生,教师的外键占位符

@Entity
@Table(name="student")
public class Student {

private Integer id;
private String studentName;
private Integer class_id;

查询使用:

sessionFactory.openSession().createQuery("from Class where id<5000");
sessionFactory.openSession().createQuery("from Student where class_id = :classId");
sessionFactory.openSession().createQuery("from Teacher where class_id = :classId");

注 – 仅显示imp.部分代码.我正在通过JAMM库测量所获取的实体的内存使用情况.

我也尝试将查询标记为readOnly,如果#1如下,这不会非常改善内存使用;只是一点点所以这不是解决.

Query query = sessionFactory.openSession().
            createQuery("from Class where id<5000");

    query.setReadOnly(true);
    List<Class> classList = query.list();
    sessionFactory.getCurrentSession().close();

以下是按大小排序的heapdump快照.看起来像由hibernate维护的实体正在创建问题

Hibernate协会程序的Heapdump快照

使用单独实体进行抓取的heapdump快照

解决方法

您正在使用以下注释进行EAGER抓取.即使您访问getStudents(),这也可以让所有的学生获取所有学生.让它懒惰,只有在需要的时候才能获取.
@OneToMany(fetch = FetchType.EAGER,mappedBy = "classRef")

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读