Issue
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?
Solution
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.
Answered By - user3813463