2015-07-19 116 views
0

我在Hibernate的自我训练。 我刚刚发现奇怪的行为,我不解释了。休眠不要保存我的对象

我使用Hibernate的4.3.10与Java 8

我希望你能帮助我明白发生了什么。 更明确的看到下面的代码示例:

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; 
} 

在我看来这种方法保存打开的会话和交易,拯救我的对象,然后关闭会话和交易。从保存我试图找回javadoc中描述的标识符。但它不起作用,我看到请求在我的日志中执行(感谢休眠调试模式)。

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

但当我尝试这个办法:

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(); 
} 

它正确保存我的对象。

我测试更多的情况: 就返回一个常量,不要把标识的变量像第一个例子和它的工作。看来这个对象不会保存,以防直接用“session.save”方法获得ID。

此外,我注意到一些有趣的事情。我做第一个试验与工作解决方案之一,它产生的ID为117数据库中的数据然后我改变我的代码不Tomcat中工作,并重新加载它的解决方案,我做2尝试没有成功。我再次改变我对所产生的其中一个成功的ID码120.错过2 ID号(2试试我做?)

为了帮助你看到我的hibernate.cfg.xml文件

<?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> 

编辑:用户3813463回答问题的一部分。它解释说,会议是在自动刷新模式在默认情况下它在像一些情况下冲洗会议:

冲洗默认情况下在以下几点情况:

  • 在某些查询执行

  • 来自org.hibernate.Transaction.commit()

  • from Session.flush()

但我以我的观点(我可能想念某事),我的第一个案例应该工作,因为我犯了我的交易。其次,我需要建议选择一种冲洗模式。在我看来,对于仅在数据库中插入或仅读取数据的方法,“提交”模式是一种很好的方法。

你是否同意我的观点,你有一些资料来源,这是辩论吗?

+0

如果你不介意第一次你能回答我的问题,你看到在控制台/日志当行'返回pBlindStructure.getIdBlindStructure();'得到执行? :) – Amogh

+0

...并发布您的休眠配置... – Amogh

+0

pBlindStructure.getIdBlindStructure()=>它返回我的第二种情况下生成的Id的值。我在主消息 – Wodric

回答

1

这一切的FlushMode读取文档here

根据文档默认FlushModeAUTO这意味着

会话,以便查询执行之前有时刷新到 确保魔术查询永远不会返回陈旧状态。

根据另一个文件(Here):

flush在以下点发生默认:

之前某些查询执行

从org.hibernate.Transaction.commit( )

from Session.flush()

所以,当你说pBlindStructure.getIdBlindStructure(); hibernate实际上在当前会话上执行刷新,结果数据被保存在数据库中。

+0

对不起,如果不回答,我会在今天晚些时候研究你的答案,我最后一天没有时间。 – Wodric

+0

对不起,延迟的答案,我有很多想做IRL;)。这解释了为什么在我的第二种情况下,我一定会有结果。但我第一个案例是应该刷新当前会话的事务提交?在那种情况下,为什么它不是冲水呢?哪种刷新模式更适合在低并发应用程序中使用? – Wodric

0

会话保存方法为生成器生成的ID返回一个对象。这个值应该投射到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; 
+0

先生,但是为什么记录没有在方法1中保存呢?我认为这是因为'flushmode'。我认为在第二种方法中,当'pBlindStructure.getIdBlindStructure();'得到执行会话刷新写入(插入)记录到DB。 – Amogh

+0

对不起,我忘了我的演员,但我在我的测试中完全像你(日食不要让我选择) – Wodric

+0

我没有听到你说的话。 –