-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Removal from object structure WITHOUT removal from database?
PostPosted: Sun Mar 22, 2009 12:15 am 
Newbie

Joined: Sat Mar 21, 2009 11:44 pm
Posts: 3
Hi,

I am using BioJava to read protein files into a SQL Server database. Basically, the database and object structure is as follows: A protein file can have many (read hundreds of) 'model-chain-residue's , and a model-chain-residue can have many (read dozens to hundreds of) atoms.

I have the database structure in place to handle all of this, and I can load the protein data into SQL using Hibernate 3.2.5. The problem is as the object structure starts building up within a given session (for a given protein), the program slows down dramatically... the object hierarchy is getting very 'full'. Parsing and dumping a single 325 kb file into the database can take easily 20 minutes... and I have 4,000 protein files to load! :-) And a 325kb protein file is small compared to the larger ones! I will also run out of heap space I am reasonably sure.

Each of the SQL tables has an auto-increment field as the primary key. In the appropriate hbm.xml files I have the following settings:
Code:
...
         <generator class="identity" />
...
        <many-to-one name=... fetch="select" cascade="save-update">

Here is psuedo-code of what I have that DOES work, but slows considerably per protein as more and more ModelChainResidues and Atoms are added:

Code:
  SessionFactory factory = HibernateUtil.getSessionFactory();
  Session session = factory.getCurrentSession();
  try {
     Protein p = new Protein();
     for (int i = 0; i < numOfModelsChainsResidues; i++) {
        ModelChainResidue mcr = new ModelChainResidue(i+1);
        mcr.setProtein(p);
        p.getModelChainResidues().add(mcr);
        ...
        for (j=0; j < numOfAtoms; j++) {
           Atom a = new Atom();
           a.setModelChainResidue(mcr);
           mcr.getAtoms().add(a);
           ...
           session.save(a);
           session.flush();
        }
    }
}   


What I would like to do (just to load the data into the database) is to dump the data in the database, then remove the atom that was just loaded from the object structure but NOT from the database... so that only one atom max is in the object structure at a time (with a similar thought towards ModelChainResidue). Yet when I use code like this:

Code:
  SessionFactory factory = HibernateUtil.getSessionFactory();
  Session session = factory.getCurrentSession();
  try {
     Protein p = new Protein();
     ...
     for (int i = 0; i < numOfModelsChainsResidues; i++) {
        ModelChainResidue mcr = new ModelChainResidue(i+1);
        mcr.setProtein(p);
        p.getModelChainResidues().add(mcr);
        ...
        for (j=0; j < numOfAtoms; j++) {
           Atom a = new Atom();
           a.setModelChainResidue(mcr);
           mcr.getAtoms().add(a);
           ...
           session.save(a);
           session.flush();
-->      mcr.getAtoms().remove(a);
-->      a.setModelChainResidue(null);
        }
        //I'd also like to have this kind of logic.
---> //p.getModelChainResidues().remove(mcr);
---> //mcr.setProtein(null);
    }
}   


... I (of course) get a NOT NULL exception. Specifically: "org.hibernate.PropertyValueException: not-null property references a null or transient value: data.entities.Atom.ModelChainResidue"

Any ideas how I can accomplish what I need to do?

Thanks! I'll bet it's fairly easy, but I've only been using Hibernate for a couple of days and it has me stumped!

Paul


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 22, 2009 10:24 am 
Regular
Regular

Joined: Mon Nov 24, 2003 6:36 pm
Posts: 105
Couple of ideas. You could try evict (session.evict) to explicitly make hibernate "forget" about the object once you've flushed.

Also, you might not want to call flush as often, as that will not allow for batching of inserts AFAIK. Might want to flush every 100 records or so.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 22, 2009 3:30 pm 
Newbie

Joined: Sat Mar 21, 2009 11:44 pm
Posts: 3
Thanks for the reply! I'll look into that!

I DID find a solution. It's not very 'elegant' but it works for what I need, and it reduces my dump time to my database by a factor of 20 to 25.

What I am doing is essentially (psuedo-code here):

Code:
dumpProteinDataFromFileToDb() {
    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.getCurrentSession();
    try {
       session.beginTransaction();
       Protein p = new Protein();
       ... do Protein stuff...
       session.save(p);
       session.getTransaction.commit(); //this closes the session

       for (int i=0; i<numOfModels;i++) {
          dumpModelChainResidueDataFromFileToDb(p,i);
       }
    } catch etc
}

dumpModelChainResidueDataFromFileToDb(Protein p, int modelNumber) {
    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.getCurrentSession();
    try {
       session.beginTransaction();
       ModelChainResidue mcr = new ModelChainResidue();
       p.getModelChainResidues().add(mcr);
       mcr.setProtein(p);
       ... do mcr stuff...
       session.save(mcr);
       session.getTransaction.commit(); //this closes the session

       //Since i am no longer in a session, these are just purely
       //Java objects at my disposal, so I remove their dependence.
       //This flattens the structure back out.
       p.getModelChainResidues().remove(mcr);
       mcr.setProtein(null);

       for (int j=0; j<numOfAtoms; j++) {
           //do the same type of flattening here (method not shown)
          dumpAtomDataFromFileToDb(mcr, etc);
       }

   } catch etc
}


It's definitely not ideal, since it creates individual transactions with no master rollback. But AFAIK Hibernate does not support nested sessions/transactions due to it's reliance on JDBC/JTA. If you start a second (nested) session, the first session closes... I know that because I hit my head on that wall a few times! :-)

Paul


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 22, 2009 3:33 pm 
Newbie

Joined: Sat Mar 21, 2009 11:44 pm
Posts: 3
Double-posted somehow... removed.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.