2013-01-11 131 views
2

我们有一个表格,每个更新的值都有新的行。主键由一个ID和一个时间戳组成。还有一个状态栏。对于一个特定的ID,我们将有一行代表每次该值被更新,并且我们使用具有最近时间戳的代表来表示“当前”值。有没有办法使用Hibernate有条件地插入?

我们有一个将根据用户输入更新状态的进程。因此,当用户单击UI中的按钮时,将会使用新状态和新用户标识创建一个新行。

如果两个用户同时点击该按钮,我们只是插入两条新记录,其中一条记录会获胜(具有最新时间戳的记录)。我们希望避免让两个用户同时点击此按钮,并且可能会创建一个新行,而不知道他们踩到别人的状态更改。在Oracle中,我们只希望做这样的事,并检查行插入(其中PREVIOUS_KNOWN_MAX_TS是TS“当前”的记录,当用户浏览网页):

INSERT INTO SOME_TABLE 
    (ID, REVISION_TS, USER_ID, STATUS, ...) 
SELECT 1, 'SOME_TIMESTAMP', 'user123', 'NEW_STATUS', ... 
FROM DUAL 
WHERE NOT EXISTS 
    (SELECT * 
    FROM SOME_TABLE 
    WHERE USER_ID = 1 
     AND REVISION_TS >= 'PREVIOUS_KNOWN_MAX_TS')); 

如果有一个插入在用户查看页面和插入用户更新信息的时间之间,插入操作不会发生,我们会通过知道插入零行来检测该插入。

有没有办法在Hibernate中做到这一点,或者我们应该尝试做某种SELECT FOR UPDATE?

+0

['saveOrUpdate'](http://www.javabeat.net/2008/09/difference-between-hibernates-saveupdate-and-saveorupdate-methods/)hibernate方法呢? –

+0

我总是想要做一个插入,所以保存或更新将无法正常工作。我遇到问题的地方在于,有时我想确保在数据库不处于我认为处于的状态时不会发生插入。 –

+0

[JPA - create-if-not-exist实体?](http://stackoverflow.com/questions/3562105/jpa-create-if-not-exists-entity) – mindas

回答

0

如果你用org.hibernate.annotations.SQLInsert注解你的实体类,你可以覆盖由Hibernate生成的插入。这有点棘手,因为你必须以完全相同的方式使用绑定参数,Hibernate通常的插入会使用它们。

相关问题