My Java program which uses Hibernate is falling over on me with an OutOfMemoryError exception. I'd appreciate any advice on how to reduce the memory usage. Do I need to disable some caching that Hibernate does by default? Do I need to reduce some cache size?
Some BackgroundI have a problem with a Java program that I have written and I was hoping to use Hibernate to help me solve it. My Java program generates loads of objects and consumes large amounts of memory. So I was hoping to use Hibernate to store the objects in a database and then just retrieve them when I need them.
Test ProgramSo to test this, I decided to create a large number of objects and store them to the database using Hibernate to ensure that the memory usage did not rise. Each time I would create an object I would save it to the database and then dereference the object straight away. Below is my little bit of code. When I run this code it falls over with an java.lang.OutOfMemoryError exception.
I decided then to profile the code and it seems the large amounts of memory are being used up in instances of these two classes
org.hibernate.engine.EntityEntry	
org.hibernate.engine.EntityKey	
So, pretty much a 1-to-1 mapping for each object I save to the database. I presume that Hiberate is holding on to the reference in some cache? But how do I clear this so that my memory usage stays constant regardless of how many objects I create (i.e. stays constant after a certain startup period)?
My CodeCode:
        
---------------------------------------------------------
 Main Java Class
---------------------------------------------------------
        SessionFactory sessions = new Configuration().configure().buildSessionFactory();
        Session session = sessions.openSession();
        try {
            for (int i = 1; i <= 500000; i++){
                Person p1 = new Person();
                p1.setName("Person" + i);
                session.save(p1);                
                p1 = null;
                if (i % 1000 == 0){
                   System.out.println(i + " objects");
                   session.flush();
                }
            }
        } catch ( HibernateException e ) {
            e.printStackTrace();
        } finally {
            session.close();
        }
----------------------------------------------------------------
 My Entity Java Class
---------------------------------------------------------
import java.io.Serializable;
public class Person implements Serializable {
   
    private int id;
    private String name;
   
    protected Person() {
    }
   
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
   
    public int getId() {
        return id;
    }
   
    public void setId(int id) {
        this.id = id;
    }
   
    public String getName() {
        return name;
    }
   
    public void setName(String name) {
        this.name = name;
    }
   
}
---------------------------------------------------------
 hibernate.cfg.xml
---------------------------------------------------------
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="connection.url">jdbc:derby://localhost:1527/myDB</property>
        <property name="connection.username">me</property>
        <property name="connection.password">mine</property>
        
        <property name="connection.autocommit">true</property> 
        
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.DerbyDialect</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">false</property>
        <!-- Mapping files -->
        <mapping resource="Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>