0

こんにちは、休止状態で多対 1 の関係を作成しました。以下はそのためのコードです。

テーブルAの単一のレコードにリンクされているBテーブルに何千ものレコードが存在します。 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);
        }
    }
4

4 に答える 4

1

を導入して、指定された オブジェクトDAOからページ形式でレコードを取得できます。BA

例えば:

public interface BDao {

   Page findByA(A a, PageRequest pageRequest);

}

たぶん、SpringDataで採用されたアプローチからアイデアを得ることができます

于 2012-07-06T06:37:06.000 に答える
1

データソースのプロパティを設定MaxResultsします。取得するレコード数の制限を設定します。

また、を使用してJavaヒープのメモリサイズを増やすことができます-Xmx256m。これにより、最大ヒープ割り当てサイズが256MBに設定されます。必要に応じて設定できます。

于 2012-07-06T06:37:25.863 に答える
1

この目的のために、ページングでクエリを使用できます。クラスでは、レコードを反復処理するのに役立つメソッドを見つけるQueryことができます。すべての B オブジェクトをロードして保存する必要がある場合は、オプションを設定して Java のメモリ設定を調整できます。また、必要なフィールドのみを含むある種の削減されたクラス B (たとえば ) を宣言し、への変換で反復処理を使用してメモリ使用量を削減することもできます。setFirstResultsetMaxResults-XmxReducedBBReducedB

また、この質問を確認できます。ご希望に十分近いと思います。

PS 最終的な解決策は、解決したい特定の問題によって異なります。

于 2012-07-06T08:52:43.237 に答える