Hibernate关联使用太多内存

nik*_*kel 9 java hibernate one-to-many memory-profiling heap-profiling

我有一个表"课",它与表"学生"和"老师"相关联.通过外围关键关系将"班级"与多个学生和教师联系起来.

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

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

这是架构的方式:

class(id,className) 

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

class_id is foreign key..
Run Code Online (Sandbox Code Playgroud)

案例#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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

使用的查询:

sessionFactory.openSession().createQuery("from Class where id<5000");
Run Code Online (Sandbox Code Playgroud)

然而,这需要大量的记忆.

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

1)类实体中没有映射

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

private Integer id;
private String className;
Run Code Online (Sandbox Code Playgroud)

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

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

private Integer id;
private String studentName;
private Integer class_id;
Run Code Online (Sandbox Code Playgroud)

使用的查询:

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");
Run Code Online (Sandbox Code Playgroud)

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

我也试过标志着如下情况#1,不提高内存的使用情况非常查询为只读; 只是一点点.所以这不是解决方案.

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

    query.setReadOnly(true);
    List<Class> classList = query.list();
    sessionFactory.getCurrentSession().close();
Run Code Online (Sandbox Code Playgroud)

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

Hapnate Association程序的Heapdump快照 Hapnate Association程序的Heapdump快照

heapdump的快照,用于使用单独的实体获取 heapdump的快照,用于使用单独的实体获取

Ash*_*hab 7

您正在使用以下注释进行EAGER提取.即使您没有访问getStudents(),也可以获取所有学生.让它变得懒惰,它只在需要时才会获取.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "classRef")
Run Code Online (Sandbox Code Playgroud)

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "classRef")
Run Code Online (Sandbox Code Playgroud)