数据库时间戳不匹配

时间:2012-08-21 15:59:05

标签: java sql-server hibernate struts timestamp

我在struts2中有一个动作,它将在数据库中查询一个对象,然后通过一些更改来复制它。然后,它需要从副本中检索新的objectID并创建一个名为objectID.txt的文件。

以下是相关代码:

行动类:

ObjectVO objectVOcopy = objectService.searchObjects(objectId);
//Set the ID to 0 so a new row is added, instead of the current one being updated
objectVOcopy.setObjectId(0);
Date today = new Date();
Timestamp currentTime = new Timestamp(today.getTime());
objectVOcopy.setTimeStamp(currentTime);
//Add copy to database
objectService.addObject(objectVOcopy);
//Get the copy object's ID from the database
int newObjectId = objectService.findObjectId(currentTime);
File inboxFile = new File(parentDirectory.getParent()+"\\folder1\\folder2\\"+newObjectId+".txt");

ObjectDAO

//Retrieve identifying ID of copy object from database
List<ObjectVO> object = getHibernateTemplate().find("from ObjectVO where timeStamp = ?", currentTime);
return object.get(0).getObjectId();

问题在于,ObjectDAO搜索方法通常不会返回任何内容。在调试时我注意到传递给它的Timestamp currentTime通常比数据库中的值大约1-2ms。我已经解决了这个错误,改变了hibernate查询以搜索时间戳超过传递的3ms内的对象,但我不确定这种差异来自何处。我不是在重新计算当前时间;我正在使用相同的一个从数据库中检索,因为我要写入数据库。我也担心当我将其部署到另一台服务器时,差异可能会更大。除了objectID之外,这是唯一的唯一标识符,因此我需要使用它来获取复制对象。

有谁知道为什么会发生这种情况,是否有更好的解决方法而不仅仅是搜索范围?我正在使用Microsoft SQL Server 2008 R2 btw。

感谢。

2 个答案:

答案 0 :(得分:3)

SQL Server的DATETIME数据类型中的精度与您在其他语言中生成的内容不完全匹配。 SQL Server舍入到最接近的0.003 - 这就是为什么你可以说:

DECLARE @d DATETIME = '20120821 23:59:59.997';
SELECT @d;

结果:

2012-08-21 23:59:59.997

然后尝试:

DECLARE @d DATETIME = '20120821 23:59:59.999';
SELECT @d;

结果:

2012-08-22 00:00:00.000

由于您使用的是SQL Server 2008 R2,因此应确保使用DATETIME2数据类型而不是DATETIME。

那就是说,@ RedFilter提出了一个很好的观点 - 当你可以使用生成的ID时,为什么还要依赖时间戳呢?

答案 1 :(得分:1)

这感觉不对。

  

除objectID外,这是唯一的唯一标识符

出于某种原因,数据库具有唯一标识符的概念。您应该使用它来检索对象的实例。

您可以在Hibernate会话中使用get方法,并利用会话和二级缓存。

使用您的方法,每次检索对象时都会执行查询。