@Version不能与@DynamicInsert一起使用

时间:2016-05-10 20:43:14

标签: hibernate

我试图让hibernate处理并发,经过一些研究后,@ Version的使用出来了。 下面是我到目前为止所做的一个例子:

CREATE TABLE MY_TABLE (
    ID NUMBER NOT NULL
  , VERSION NUMBER NOT NULL
);

ALTER TABLE MY_TABLE ADD CONSTRAINT PK_MY_TABLE KEY (ID);

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;

@Entity
@Table(name = "MY_TABLE")
@SequenceGenerator(name = "SQ_NAME", sequenceName = "SQ_MY_TABLE", initialValue = 1, allocationSize = 1)
@DynamicUpdate
@DynamicInsert
public class MyTable implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQ_NAME")
    private Long id;

    @Column(name = "VERSION", insertable = false, updatable = false)
    @Version
    @Generated(GenerationTime.ALWAYS)
    private Long version;

    ... getters and setters
}

当我的应用程序尝试在MY_TABLE中插入新行时,Oracle会抛出异常

ORA-01400: cannot insert NULL into ("MY_TABLE"."VERSION")

我错过了什么?它仅在我删除@DynamicInsert ...

时才有效

PS:我使用的是@Generated(GenerationTime.ALWAYS),因为如果我不使用它,我不能在同一条记录上执行2次更新而不首先要求它。

环境:JBoss EAP 6.3,java 1.7.0_79,hibernate 4.3.11.Final(使用JTA),JSF 2.0和Oracle 12c。

1 个答案:

答案 0 :(得分:0)

经过更多的研究,我发现当我们使用GenerationTime.ALWAYS或GenerationTime.INSERT时,我们需要提供一个数据库触发器来填充用@Version注释的字段。

例如,在Oracle中,触发器是这样的:

CREATE OR REPLACE TRIGGER TRG_MY_TABLE_BIUR
BEFORE INSERT OR UPDATE
    ON MY_TABLE
    FOR EACH ROW
DECLARE
BEGIN
    IF INSERTING THEN
        :NEW.VERSION := 0;
    ELSE
        :NEW.VERSION := :OLD.VERSION + 1;
    END IF;
END TRG_MY_TABLE_BIUR;
/