开发者

Hibernate memory management

I have an application that uses hibernate. At one part I am trying to retrieve documents. Each document has an account number. The model looks something like this:

    private Long _id;
private String _acct;  
private String _message;  
private String _document;    
private String _doctype;  
private Date _review_date;  

I then retrieve the documents with a document service. A portion of the code is here:

public List<Doc_table> getDocumen开发者_开发问答ts(int hours_, int dummyFlag_,List<String> accts) {
        List<Doc_table> documents = new ArrayList<Doc_table>();
    Session session = null;
    Criteria criteria = null;
    try {
        // Lets create a previous Date by subtracting the number of
        // subtractHours_ passed.
        session = HibernateUtil.getSession();
        session.beginTransaction();
        if (accts == null) {
            Calendar cutoffTime = Calendar.getInstance();
            cutoffTime.add(Calendar.HOUR_OF_DAY, hours_);
            criteria = session.createCriteria(Doc_table.class).add(
                    Restrictions.gt("dbcreate_date",  cutoffTime.getTime()))
                    .add(Restrictions.eq("dummyflag", dummyFlag_));
        } else 
        {   criteria = session.createCriteria(Doc_table.class).add(Restrictions.in("acct", accts));
        }
        documents = criteria.list();
        for (int x = 0; x < documents.size(); x++) {
            Doc_table document = documents.get(x);
               ......... more stuff here
                    }

This works great if I'm retrieving a small number of documents. But when the document size is large I get a heap space error, probably because the documents take up a lot of space and when you retrieve several thousand of them, bad things happen.

All I really want to do is retrieve each document that fits my criteria, grab the account number and return a list of account numbers (a far smaller object than a list of objects). If this were jdbc, I would know exactly what to do.

But in this case I'm stumped. I guess I'm looking for a way where I can bring just get the account numbers of the Doc_table object back.

Or alternatively, some way where I can retrieve documents one at a time from the database using hibernate that fit my criteria (instead of bringing back the whole List of objects which uses too much memory).


There are several ways to deal with the problem:

  • loading the docs in batches of an smaller size
  • (The way you noticed) not to query for the Document, but only for the account numbers:

    List accts = session.createQuery("SELECT d._acct FROM Doc d WHERE ...");

or

 List<String> accts = session.createCriteria(Doc.class).
             setProjection(Projections.property("_acct")).
             list();
  • When there is a special field in you Document class that contains the huge amount Document byte data, then you could map this special field as a Lazy loaded field.
  • Create a second entity class (read only) that contains only the fields that you need and map it to the same table


Instead of fetching all documents i.e, all records at once, try to limit the rows being fetched. Also, deploy a strategy where in you can store documents temporarily as flat files and fetch them later or delete after usage. Though its a bit long process,its efficient way of handling and delivering documents from database.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜