Wodric
Wodric

Reputation: 55

Why Hibernate doesn't save my object in database

I'm using Hibernate 4.3.10 with Java 8.

To be more explicit see the following code example :

public static long createBlindStructure(BlindStructure pBlindStructure){
    Transaction tcx = null;
    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.openSession();
    int id = -1;
    try{
        tcx = session.beginTransaction();
        id = session.save(pBlindStructure);
        tcx.commit();
    }
    catch( Throwable e){
        tcx.rollback();
    }
    finally{
        session.close();
    }
    return id;
}

In my mind this method save() open session and transaction, save my object and close session and transaction. From save() I tried to get back the identifier as describe in javadoc. But It doesn't work, I see the request execute in my log (thanks to Hibernate debug mode).

Hibernate: insert into PokerLeagueManager.blindStructure (structureJson) values (?)

But when I try this :

public static long createBlindStructure(BlindStructure pBlindStructure){
    Transaction tcx = null;
    SessionFactory factory = HibernateUtil.getSessionFactory();
    Session session = factory.openSession();
    try{
        tcx = session.beginTransaction();
        session.save(pBlindStructure);
        tcx.commit();
    }
    catch( Throwable e){
        tcx.rollback();
    }
    finally{
        session.close();
    }
    return pBlindStructure.getIdBlindStructure();
}

It correctly saved my object.

I test one more case : Just returning a constant and don't put Id in the variable like first example and It work. It seems that object is not save in case I get the ID directly with session.save() method.

Moreover, I observe something interesting. I made a first test with one of the solution which worked, it generated a database data with Id 117. Then I changed my code for the solution which difsn't work and reloaded it in Tomcat , I made 2nd try without success. I changed again my code for the one which succeded and the id was generated is 120. It missed 2nf id number (the 2nd try I've done ??)

To help you see my hibernate.cfg.xml file

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          '-//Hibernate/Hibernate Configuration DTD 3.0//EN'
          'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'>

<hibernate-configuration>
<session-factory>
    <!-- Database connection settings -->
    <property     name='connection.driver_class'>com.mysql.jdbc.Driver</property>
    <property name='connection.url'>jdbc:mysql://XXXXXX:XXXX/PokerLeagueManager</property>
    <property name='connection.username'>XXXXX</property>
    <property name='connection.password'>XXXXXX</property>
    <property name="show_sql">true</property>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
    <property name="hibernate.c3p0.acquire_increment">1</property>
    <property name="hibernate.c3p0.idle_test_period">120</property>
    <property name="hibernate.c3p0.min_size">1</property>
    <property name="hibernate.c3p0.max_size">10</property>
    <property name="hibernate.c3p0.max_statements">50</property>
    <property name="hibernate.c3p0.timeout">120</property>
    <property name="hibernate.c3p0.acquireRetryAttempts">1</property>
    <property name="hibernate.c3p0.acquireRetryDelay">250</property>
    <!--  Dev -->
    <property name="hibernate.c3p0.validate">true</property>

    <!-- SQL dialect -->
    <property name='dialect'>org.hibernate.dialect.MySQL5InnoDBDialect</property>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>
    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>


    <!-- Echo all executed SQL to stdout -->
    <property name='show_sql'>true</property>
    
    <mapping resource="mappings/BlindStructure.hbm.xml"/>
    <mapping resource="mappings/Tournament.hbm.xml"/>
    <mapping resource="mappings/LegalFee.hbm.xml"/>
</session-factory>

Edit: User3813463 answer for a part of a question. It explains that session are in AUTO flush mode by default which flush session in some case like :

flush occurs by default at the following points:

  • before some query executions

  • from org.hibernate.Transaction.commit()

  • from Session.flush()

But I my point of view (I maybe miss understand something), my first case should worked because I commit my transaction.

Secondly, I need advise to choose a flush mode. To my mind Commit mode is a good way to do for method which make only inserting or only reading data on database.

Do you agree with me, have you some sources where this is debate?

Upvotes: 1

Views: 4566

Answers (2)

user3813463
user3813463

Reputation: 91

This all is the magic of FlushMode read docs here

According to docs default FlushMode is AUTO that means

The Session is sometimes flushed before query execution in order to ensure that queries never return stale state.

According to another document (Here):

flush occurs by default at the following points:

before some query executions

from org.hibernate.Transaction.commit()

from Session.flush()

So when you say pBlindStructure.getIdBlindStructure(); hibernate actually perform flush on current session, resulting data is getting saved in DB.

Upvotes: 2

Roman C
Roman C

Reputation: 1

The session save method returns an object for the generated id by the generator. This value you should cast to Long.

long id = -1;
try{
    tcx = session.beginTransaction();
    id = (Long) session.save(pBlindStructure);
    tcx.commit();
}
catch( Throwable e){
    tcx.rollback();
}
finally{
    session.close();
}
return id;

Upvotes: 0

Related Questions