2012-07-06 113 views
0

嗨,我在休眠中創建了多對一的關係。 以下是該代碼。休眠狀態下的內存不足

有成千上萬的存在於乙表中的記錄是鏈接表A的單記錄當我用getBList()方法它將返回數千記錄和JAVA的熄滅存儲器。 那麼我該如何解決這個問題。

@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); 
     } 
    } 
+0

所以你說什麼問題是,我建議你改變你的算法。您想做什麼?我相信有非常罕見的情況,當你需要把數千個「關係」的關係放在一起時。 – 2012-07-06 06:31:44

+0

您也可以測試'StatelessSession',它可以幫助.... – 2012-07-06 06:32:53

回答

1

你可以爲了檢索B分頁的方式給予A對象記錄引入DAO

例如:

public interface BDao { 

    Page findByA(A a, PageRequest pageRequest); 

} 

也許你可以採取從方法中Spring Data

1

MaxResults數據源的屬性抽放的想法,它將對你得到的記錄數設置限制。

另外,還可以使用-Xmx256m增加Java堆內存的大小。這會將最大堆分配大小設置爲256MB。您可以根據需要進行設置。

+0

我們可以在查詢對象中設置MaxResults屬性。但我只是使用getBList()方法。所以我將如何控制這個功能。而事情是,我想從A中的特定記錄中記錄所有記錄,但不是一成不變的,我可以在大量記錄中使用它,但是我怎麼做才能保證沒有內存不足。 – Anant 2012-07-06 07:02:05

+0

不錯,你也可以這樣做。但是你不覺得,你每次執行查詢時都會設置它。 – 2012-07-06 07:05:16

+0

這就是我不想使用查詢的原因。並請再次閱讀上面的評論,我已編輯。這樣你就可以得到我的問題。 – Anant 2012-07-06 07:11:02

1

您可以使用查詢分頁用於這一目的。在Query類中,您可以找到setFirstResultsetMaxResults方法,這些方法可以幫助您迭代記錄。如果您需要加載所有B對象並存儲它們,您可以通過設置-Xmx選項來調整java的內存設置。你也可以嘗試申報某種減少B類(例如ReducedB),其中只包含所需的字段,並使用帶有轉換BReducedB減少內存使用迭代。你

還可以檢查this問題。我認爲它足夠接近你想要的東西。

P.S.最終解決方案將取決於您想要解決的特定問題。

+0

我已經完成了相同的工作,但我又收到了內存不足。我在我的問題中更新了我的代碼,以便您可以查看它。 – Anant 2012-07-09 10:45:51

+0

我覺得'OUT OF MEMORY'的原因是一樣的。你是否同時存儲所有B對象?可能從DB獲取的對象不是垃圾收集?你可以嘗試'jvisualvm'工具來發現內存已經走了。 – gkuzmin 2012-07-10 05:59:59