How to reduce hibernate memory use in desktop application?

Viewed 424

I am developing a desktop application. I am using hibernate 4, JavaDB with Embeded Driver and JavaFx. But i am really struggling with hibernate memory use. Below i have provided my codes.

Here i am searching in a database table called MODEL_E2B_WORDLIST. I have done it in two ways,

  1. Hibernate,
  2. JDBC.

I have run the same search operation around 500 times by both JDBC and Hibernate. I have found that JDBC has taken not more than 100mb during this operation but Hibernate uses around 400mb.

Now I wanna know where i have made the wrong in hibernate that it is taken such amount of memory or it is normal with hibernate.

CFG :

<hibernate-configuration>
  <session-factory>
    <!--.Connection Properties.-->
    <property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
    <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>
    <property name="hibernate.connection.url">jdbc:derby:vocubulary;create=true;</property>
    <property name="hibernate.connection.username">app</property>
    <property name="hibernate.connection.password">app</property>
    <property name="hibernate.show_sql">true</property>
    <!--done to test.-->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!--<mapping resource="word.hbm.xml"/>-->
    <mapping class="com.vocubulary.model.Model_E2B_WordList"/>
  </session-factory>
</hibernate-configuration>

DAO Impl Class:

public class DAO_e2b_Impl implements DAO_e2b_I
    {

     SessionFactory factory = HibernateUtil.getSessionFactory();
//    Session session = factory.openSession();

    @Override
    public List dao_e2b_get_wordsList_afterSerach(String e2b_searchKey)
        {
//        SessionFactory factory = HibernateUtil.getSessionFactory();
          Session session = factory.openSession();
          List list_word = null;
          try
            {
            Transaction tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Model_E2B_WordList.class);
            criteria.setProjection(Projections.property("e2b_word")); //Projections.property is used to retrieve specific columns
            criteria.add(Restrictions.ilike("e2b_word", e2b_searchKey, MatchMode.START));
            list_word = criteria.list();
            tx.commit();
          } catch (Exception e)
          {
            e.printStackTrace();
          } finally
          {
            session.close();
//            factory.close();
            System.out.println("\n\n\n Final loadData : all conection closed");
          }
        return list_word;
//        return jdbcDB(e2b_searchKey);  
        }
}

Test Class

@Test
     public void search_in_e2b_wordList() throws Exception
         {
            hibernateTest(500);
//             jdbcTest(500);
         }

     public void hibernateTest(int loopCounter) throws  Exception
         {
            DAO_e2b_Impl dAO_e2b_Impl = new DAO_e2b_Impl();
            List l = new ArrayList();
             int x = 0;
             while (x != loopCounter)
               {
                 l = dAO_e2b_Impl.dao_e2b_get_wordsList_afterSerach("Man");
                 System.out.println("Size  :" + l.size());
                 x++;
                 l.clear();
                 System.out.println("count : " + x);
                 Thread.sleep(100);//used, to see the effect in the task manager.
               }
         }
     public void jdbcTest(int loopCounter) throws  Exception
         {
            List l = new ArrayList();
             int x = 0;
             while (x != loopCounter)
               {
                 l = jdbcDB();
                 System.out.println("Size  :" + l.size());
                 x++;
                 l.clear();
                 System.out.println("count : " + x);
                 Thread.sleep(100);//used, to see the effect in the task manager.
               }
         }


    public List jdbcDB()
             {
               // JDBC driver name and database URL
        String JDBC_DRIVER = "org.hibernate.dialect.DerbyDialect";
        String DB_URL = "jdbc:derby:vocubulary;create=true;";

        //  Database credentials
        String USER = "app";
        String PASS = "app";

        Connection conn = null;
        Statement stmt = null;

        List l = new ArrayList();

        try
          {
            //STEP 2: Register JDBC driver
            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

            //STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

            //STEP 4: Execute a query
            System.out.println("Creating statement...");
            stmt = conn.createStatement();
            String sql;
//            sql = "SELECT app.MODEL_E2B_WORDLIST.E2B_WORD from app.MODEL_E2B_WORDLIST";
            sql = "SELECT app.MODEL_E2B_WORDLIST.E2B_WORD from app.MODEL_E2B_WORDLIST WHERE E2B_WORD LIKE 'MAN%'";
            ResultSet rs = stmt.executeQuery(sql);

            //STEP 5: Extract data from result set
            while (rs.next())
              {
                //Retrieve by column name
                String last = rs.getString("E2B_WORD");
                //Display values
//                System.out.println("Last: " + last);
                l.add(last);
              }
            //STEP 6: Clean-up environment
            rs.close();
            stmt.close();
            conn.close();
          } catch (SQLException se)
          {
            //Handle errors for JDBC
            se.printStackTrace();
          } catch (Exception e)
          {
            //Handle errors for Class.forName
            e.printStackTrace();
          } finally
          {
            //finally block used to close resources
            try
              {
                if (stmt != null)
                  {
                    stmt.close();
                  }
              } catch (SQLException se2)
              {
              }// nothing we can do
            try
              {
                if (conn != null)
                  {
                    conn.close();
                  }
              } catch (SQLException se)
              {
                se.printStackTrace();
              }//end finally try
          }//end try

        System.out.println("Goodbye!");
        return l;
             }

Model CLass

@ToString
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Model_E2B_WordList
    {
//          i used "lombok"
            @Id @Getter @Setter
            private String e2b_word;
    }
1 Answers

Hibernate is very flexible, so you can tweak it to use almost the same amount of memory as JDBC variant.

Hibernate uses Session as the first level cache. You can try to decrease amount of used memory using StatelessSession. You can open StatelessSession with SessionFactory#openStatelessSession().

You don't need this

List l = new ArrayList();

in the hibernateTest() because of the assigned value new ArrayList() is never used. Just assign a result by this way

List l = dAO_e2b_Impl.dao_e2b_get_wordsList_afterSerach("Man");
Related