休眠时的内存不足

时间:2012-07-06 06:20:05

标签: java hibernate

您好我在hibernate中创建了多对一的关系。 以下是该代码。

B表中存在数千条记录,这些记录链接到表A的单个记录。当我使用getBList()方法时,它将返回数千条记录,JAVA将返回OUT OF MEMORY。 那我怎么能解决这个问题呢。

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

    private int Id;
    private String aName;
    private List<MksReleaseInfo> bList;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    public int getId() {
        return releaseId;
    }

    public void setId(final int Id) {
        this.Id = Id;
    }

    @Column(name = "aname", unique = true)
    public String getAName() {
        return aName;
    }

    public void setAName(final String aName) {
        this.aName = aName;
    }
    @OneToMany(mappedBy = "aName")
    public List<MksReleaseInfo> getBList() {
        return bList;
    }

    public void setBList(final List<B> bList) {
        this.bList = bList;
    }
}   


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

    private int bIndex;
    private int bpriority;
    private A aName;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    protected int getBIndex() {
        return mksReleaseInfoIndex;
    }

    protected void setBIndex(final int bIndex) {
        this.bIndex = bIndex;
    }

    @Column(name = "priority")
    public int getBPriority() {
        return bpriority;
    }

    public void setBPriority(final int bpriority) {
        this.bpriority = bpriority;
    }

    @ManyToOne
    @JoinColumn(name = "Id")
    public A getAName() {
        return aName;
    }

    public void setAName(final A aName) {
        this.aName = aName;
    }
}

在所有评论之后我实现了以下代码。但它再次给出了记忆。我应该明确地清除内存以及如何清除内存?

public List<B> getList(String name, int offset, int limit) throws DAOException {
        try {
            String hql = "from B where name = :name";
            begin();
            Query query = getSession().createQuery(hql);
            query.setString("name", name);

            if(offset > 0){
                query.setFirstResult(offset);
            }

            if(limit > 0){
                query.setMaxResults(limit);
                query.setFetchSize(limit);
            }
            commit();
            return query.list();
        } catch (HibernateException e) {
            rollback(); 
        }
    }

    public Long countB(String name) throws DAOException {
        try {
            String hql = "select count(*) from B where name = :name";
            begin();
            Query query = getSession().createQuery(hql);
            query.setString("name", name);
            commit();
            return (Long)query.uniqueResult();
        } catch (HibernateException e) {
            rollback();
        }
    }


    long count = countB(name);
    int counter = (int) (count / 200);
    if(count%200 > 0){
        counter++;
    }
    for(int j = 0;j<counter;j++){
        lists = getList(name, j*200, 200);

        for(B count1 : lists){
            System.out.println(count1);
        }
    }

4 个答案:

答案 0 :(得分:1)

您可以引入DAO,以便以分页的方式从B对象中A检索记录。

例如:

public interface BDao {

   Page findByA(A a, PageRequest pageRequest);

}

也许你可以从Spring Data

中采取的方法中获取一个想法

答案 1 :(得分:1)

设置数据源的MaxResults属性,它将设置您获得的记录数限制。

此外,您可以使用-Xmx256m增加Java堆内存大小。这会将最大堆分配大小设置为256MB。您可以根据需要进行设置。

答案 2 :(得分:1)

为此,您可以将查询与分页一起使用。在Query课程中,您可以找到可以帮助您迭代记录的setFirstResultsetMaxResults方法。如果需要加载所有B对象并存储它们,可以通过设置-Xmx选项来调整java的内存设置。您还可以尝试声明某种简化类B(例如ReducedB),其中只包含必填字段,并使用迭代将B转换为ReducedB以减少内存使用量。

您也可以查看this问题。我认为它很接近你想要的东西。

P.S。最终解决方案取决于您要解决的特定问题。

答案 3 :(得分:0)

我有同样的问题。我查看了我的代码和服务器空间,但没有任何帮助。后来我研究了数据,发现错误放置的数据使应用程序使用了大量的处理能力。确保子类中没有重复的数据。