配置Hibernate以将Oracle的SYS_GUID()用于主键

Rya*_*ook 7 java oracle uuid hibernate guid

我正在寻找一种方法来让hibernate SYS_GUID()在插入新行时使用oracle的函数.目前我的数据库表具有SYS_GUID()默认值,因此如果hibernate只生成了SQL,则省略了它应该工作的值.

我有一切工作,但它当前使用system-uuid生成器在代码中生成UUID/GUID:

@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "PRODUCT_ID", unique = true, nullable = false)
public String getId() {
    return this.productId;
}
Run Code Online (Sandbox Code Playgroud)

这很好,但我更希望guid是由数据库生成的,因此它们将是顺序的并且可能具有更好的性能.另外,我想知道如何配置它.

我正在使用注释进行配置,但xml配置示例也很棒.

这是一个示例表定义(如果重要):

CREATE TABLE SCHEMA_NAME.PRODUCT
(
    PRODUCT_ID RAW(16) DEFAULT SYS_GUID() NOT NULL,
    PRODUCT_CODE VARCHAR2(10 CHAR) NOT NULL,
    PRODUCT_NAME VARCHAR2(30 CHAR) NOT NULL,
    PRODUCT_DESC VARCHAR2(512 CHAR)
)
Run Code Online (Sandbox Code Playgroud)

更新:

Mat的使用"guid"的解决方法有效,这里是sql生成的:

Hibernate: 
    select rawtohex(sys_guid()) 
    from dual
Hibernate: 
    insert into PRODUCT
    (PRODUCT_CODE, PRODUCT_DESC, LOB_ID, PRODUCT_NAME, PROVIDER_ID, PRODUCT_ID) 
    values (?, ?, ?, ?, ?, ?)
Run Code Online (Sandbox Code Playgroud)

似乎在插入中使用列默认值是不可能的,因此选择在应用程序生成的guid和数据库往返之间.

Mat*_*nit 5

您也许可以使用"guid"生成器.请参阅Hibernate论坛中的这篇文章.看起来他们在SYS_GUID()一段时间后添加了对Oracle的支持,但文档仍然说他们只支持SQL Server和MySQL.

我还没有使用JPA注释,但这是一个使用XML配置的示例:

<id name="PRODUCT_ID">
  <generator class="guid" />
</id>
Run Code Online (Sandbox Code Playgroud)

编辑:关于你的第二个问题,我想你问为什么Hibernate不能做这样的事情:

INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
SELECT SYSGUID(), /* etc */
Run Code Online (Sandbox Code Playgroud)

原因是Hibernate必须知道对象的ID是什么.例如,请考虑以下情形:

  1. 您创建一个新的Product对象并保存它.Oracle分配ID.
  2. 您从Hibernate会话中分离产品.
  3. 您稍后重新附加它并进行一些更改.
  4. 您现在想要坚持这些更改.

在不知道ID的情况下,Hibernate无法做到这一点.它需要ID才能发出UPDATE语句.所以执行org.hibernate.id.GUIDGenerator必须事先生成ID,然后再在INSERT语句中重用它.

这就是为什么如果你使用数据库生成的ID(包括支持它的数据库的自动增量),Hibernate不能进行任何批处理的原因.使用其中一个hilo生成器或其他一些Hibernate生成的ID机制是在一次插入大量对象时获得良好性能的唯一方法.

  • 仅供参考:通过注释做到这一点很简单:@GeGeneGenerator(name ="guid",strategy ="guid") (3认同)