2010-07-14 41 views
5

为什么我需要行“session.save(user);”在下面的代码片段?我认为,通过find调用,用户已经连接到会话并且更改将被跟踪并提交。你介意给我解释一下细节吗?或者我需要一个特殊的配置或其他我可能听说过这个'功能'的情况?为什么我需要在使用Hibernate查找后明确保存?

session = createSession(); 
ta = session.beginTransaction(); 
assertEquals(1, session.createCriteria(MyUser.class).list().size()); 
// find one user 
MyUser user = session.createCriteria(MyUser.class).uniqueResult(); 
user.setName("Rocker!"); 
// ### HERE ### 
// WHY this 'save' is necessary!!?? 
session.save(user); 
ta.commit(); 

ta = session.beginTransaction(); 
assertEquals(1, session.createCriteria(MyUser.class).list().size()); 
MyUser user = session.createCriteria(MyUser.class).uniqueResult(); 
assertEquals("Rocker!", user.getName()); 
ta.commit(); 

UPDATE 1

同样的问题适用于

  1. session.save(用户);
  2. user.setName(“Rocker!”);
  3. ta.commit();

UPDATE 2

的解决问题的办法是:我使用吉斯/经纱存在。在某些情况下,我通过@Transactional将一个代码块错误地绑定到了一个事务上:因此事务被提前打开,因此单独的更改未包含在提交中。多谢你们!因此,始终确保你了解的情况下,你的事务范围内使用的是春天或吉斯...

+0

你是否已经开始使用hibernate日志记录来检查从uniqueresult()和commit()返回之间会发生什么? – 2010-07-14 11:31:58

+0

我总是用明确的'保存'与休眠的最后几个月。直到今天:我自己问了这个问题。我会看看日志。但看看我的代码下面的编辑︰明确的保存也是必要的后,我已经调用了保存 – rocker 2010-07-14 11:37:50

+0

以及很长一段时间的工作“直到今天”,代码没有改变,这意味着其他一些配置已经改变 - 是务必查看自上次已知工作状态以来整个项目/应用程序发生了什么变化。很明显,事情不会停止。 – 2010-07-14 11:43:31

回答

5

你是正确的Hibernate会自动检测更改持久对象的状态:

持久 - 持久实例在数据库中有一个表示和一个标识符值。它可能只是被保存或加载,但是,它被定义在Session的范围内。 Hibernate将检测对处于持久状态的对象所做的任何更改,并在工作单元完成时将状态与数据库同步。开发人员不应执行手动UPDATE语句或DELETE语句,而应将对象设置为瞬态。

我假设条件的结果是不持久的状态恢复(但我似乎无法找到的文档证明了这一点)

尝试使用的HQL查询,用于该文档是明确:

通过查询检索

的对象处于持久化状态

还要确保会议的刷新模式设置为AUTOØ r COMMIT

+0

刷新模式'自动' - 是默认的,我怎么能改变它? – rocker 2010-07-14 11:50:22

+0

使用HQL查询它是一样的:显式保存(在更改之后)是必要的。 – rocker 2010-07-14 11:51:25

+1

@rocker,'session.setFlushMode(FlushMode.AUTO)'。 – 2010-07-14 12:06:18

相关问题