[英]hibernate returning null for auto-generated timestamps from mysql
i have a table in mysql which has a data type of timestamp as one of the columns, which gets a default value of CURRENT_TIME upon insertion. 我在mysql中有一个表,其中一个数据类型为timestamp作为列之一,插入时获得默认值CURRENT_TIME。 and i have another timestamp column that has a default value of CURRENT_TIME upon update. 我有另一个时间戳列,更新时默认值为CURRENT_TIME。 i have these so that timestamp columns will get updated automatically on insertion and update (which works fine). 我有这些,以便时间戳列将在插入和更新时自动更新(工作正常)。
now i am using cxf, hibernate/jpa, mysql, jackson to build a web service. 现在我正在使用cxf,hibernate / jpa,mysql,jackson来构建一个Web服务。 i am simply creating a new record and retrieving it right away as below code shows. 我只是创建一个新记录并立即检索它,如下面的代码所示。
Session session = getSession(); // sessionFactory.getCurrentSession();
String accountId = (String)session.save(account);
Account newAccount = (Account)session.load(Account.class, accountId);
logger.info("created timestamp=" + newAccount.getCreatedTimestamp());
after above code is ran, i can see that new record is created in mysql with correct timestamps for createdTimestamp. 运行上面的代码之后,我可以看到在mysql中创建了新记录,并为createdTimestamp创建了正确的时间戳。 however, logger.info() line above throws an exception because newAccount.getCreatedTimestamp() returns null. 但是,上面的logger.info()行会抛出异常,因为newAccount.getCreatedTimestamp()返回null。 if i remove logger.info() line, i can see that newAccount object is populated with correct values except for createdTimestamp which is null. 如果我删除logger.info()行,我可以看到newAccount对象填充了正确的值,除了createdTimestamp为null。
what's more odd is that after above code is ran (which is a part of HTTP POST operation), i call a HTTP GET service which just fetches a record that i just inserted by doing 更奇怪的是,在运行上面的代码(这是HTTP POST操作的一部分)之后,我调用一个HTTP GET服务,该服务只提取我刚刚插入的记录
session.get(Account.class, accountId);
and it correctly shows timestamps! 它正确显示时间戳!
i tried to sleep before session.load() or session.get() thinking that there might be a delay in inserting timestamp, but that didn't do much. 我试图在session.load()或session.get()之前睡觉,认为插入时间戳可能有延迟,但这并没有做太多。 is there something special about hibernate session management that does not retrieve columns that mysql generates? hibernate会话管理有什么特别之处,它不能检索mysql生成的列吗? what am i missing here? 我在这里失踪了什么? please help. 请帮忙。
Your actual save isn't being committed until the session is flushed. 在刷新会话之前,您的实际保存不会被提交。 Hibernate doesn't actually commit anything to the database until the session is flushed or closed so that if an exception is thrown, a rollback doesn't actually have to touch the physical database, the changes are just not sent. 在刷新或关闭会话之前,Hibernate实际上不会向数据库提交任何内容,因此如果抛出异常,回滚实际上不必触及物理数据库,则不会发送更改。 However if Hibernate detects that a query is going to receive stale data, it will automatically flush before running that query. 但是,如果Hibernate检测到查询将接收过时数据,它将在运行该查询之前自动刷新。
For example, you add a record to the database and immediately call a SELECT COUNT(*)
query. 例如,您将记录添加到数据库并立即调用SELECT COUNT(*)
查询。 Hibernate will flush the session (committing the record in the process) and then perform the SELECT COUNT(*)
query on the now clean session ensuring that you get correct data. Hibernate将刷新会话(在进程中提交记录),然后在现在干净的会话上执行SELECT COUNT(*)
查询,确保您获得正确的数据。 Hibernate didn't do this in your case because it saw that you were requesting the same object that you were trying to insert (in the same session) so it just returned you that reference. Hibernate在你的情况下没有这样做,因为它看到你正在请求你试图插入的同一个对象(在同一个会话中)所以它只是返回你那个引用。
If you are letting hibernate manage its sessions (using a session factory or similar) I don't think that you have to explicitly close sessions. 如果你让hibernate管理它的会话(使用会话工厂或类似的),我认为你不必显式关闭会话。 I know that I don't, but I'm using Hibernate with Spring, and using the @Transactional
annotation which manages the actual Hibernate session. 我知道我没有,但我正在使用Hibernate和Spring,并使用管理实际Hibernate会话的@Transactional
注释。 If you want an immediate insert, make your call to save() the last call in the method. 如果要立即插入,请调用save()方法中的最后一次调用。 Usually, once the method exits, a commit()
will be called automatically. 通常,一旦方法退出,将自动调用commit()
。
All the load()
will be doing is giving you the same instance of Account
that you passed into session.save()
. 所有load()
都将为您提供传递给session.save()
的相同Account
实例。 Either close or flush the session, then try the load()
again, and your value should be set. 关闭或刷新会话,然后再次尝试load()
,并设置您的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.