0

我在 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");

对象DAO

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

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

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

谢谢。

4

2 回答 2

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 时,为什么还要依赖时间戳呢?

于 2012-08-21T16:04:13.060 回答
1

这感觉不对。

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

数据库具有唯一标识符的概念是有原因的。您应该真正使用它来检索对象的实例。

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

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

于 2012-08-21T16:04:50.490 回答