【发布时间】:2015-07-19 19:55:41
【问题描述】:
我正在使用带有 Java 8 的 Hibernate 4.3.10。
要更明确,请参见以下代码示例:
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;
}
在我看来这个方法save()打开会话和事务,保存我的对象并关闭会话和事务。从save() 我试图取回javadoc 中描述的标识符。但它不起作用,我看到请求在我的日志中执行(感谢 Hibernate 调试模式)。
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();
}
它正确地保存了我的对象。
我再测试一个案例:
只需返回一个常量,不要像第一个示例那样将 Id 放入变量中,它可以工作。如果我直接使用session.save() 方法获取ID,似乎没有保存对象。
此外,我观察到一些有趣的事情。我使用其中一个有效的解决方案进行了第一次测试,它生成了一个 ID 为 117 的数据库数据。然后我更改了我的解决方案的代码,该解决方案无法正常工作并将其重新加载到 Tomcat 中,我进行了第二次尝试但没有成功。我再次更改了我的代码,成功生成的 id 是 120。它错过了 2nf id 号(我已经完成了第二次尝试??)
为了帮助您查看我的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>
编辑:User3813463 回答部分问题。它解释了会话在默认情况下处于自动刷新模式,在某些情况下刷新会话,例如:
flush 默认发生在以下几点:
在一些查询执行之前
来自 org.hibernate.Transaction.commit()
来自 Session.flush()
但我的观点(我可能错过了一些理解),我的第一个案例应该有效,因为我提交了我的交易。
其次,我需要建议选择冲洗模式。在我看来,提交模式是一种只在数据库中插入或读取数据的方法的好方法。
你同意我的观点吗,你有一些关于辩论的来源吗?
【问题讨论】:
-
如果你不介意先回答我的问题,当行`return pBlindStructure.getIdBlindStructure();`被执行时,你在控制台/日志上看到了什么? :)
-
...并发布您的休眠配置...
-
pBlindStructure.getIdBlindStructure() => 在我的第二种情况下,它返回生成的 Id 的值。我在主消息上进行了休眠配置
-
在第一种情况下,你为什么不在
transaction.commit()之前尝试session.flush()。 -
没用。但我终于找到了为什么它不起作用。我返回一个 Integer 而不是 Long。我没有注意,也没有人通知我我没有任何记录器....实际上我的代码引发了异常。感谢您的所有建议:)