配置Hibernate以使用Oracle的SYS_GUID()作为主键 [英] Configure Hibernate to use Oracle's SYS_GUID() for Primary Key

查看:926
本文介绍了配置Hibernate以使用Oracle的SYS_GUID()作为主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法来在插入新行时让hibernate使用oracle的 SYS_GUID()函数。目前我的数据库表的默认值是 SYS_GUID(),所以如果hibernate只是简单的生成SQL,它会忽略它的值。



  

@I $
@GeneratedValue(generator =system-uuid)
@GenericGenerator(name =system-uuid,strategy =uuid)
@Column(name =PRODUCT_ID ,unique = true,nullable = false)
public String getId(){
return this.productId;
}

这很好,但我更喜欢guid是由数据库生成的所以它们将是连续的并且可能具有更好的性能。另外,我只想知道如何配置它。



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



下面是一个示例表定义(以防万一):


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)



UPDATE:



使用guid工作的Mat's sollution,这里是sql生成的:

<
从双
中选择rawtohex(sys_guid())
Hibernate:
插入到PRODUCT
(PRODUCT_CODE, PRODUCT_DESC,LOB_ID,PRODUCT_NAME,PROVIDER_ID,PRODUCT_ID)
值(?,?,?,?,?,?)






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

解决方案

您可以使用guid生成器。在Hibernate论坛上查看这篇文章。看起来他们之前使用 SYS_GUID()添加了对Oracle的支持,但是 documentation 仍然表示他们只支持SQL Server和MySQL。



我还没有使用过JPA批注,但这里是一个使用XML配置的例子:

  < id name =PRODUCT_ID> 
< generator class =guid/>
< / id>

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

 插入产品(PRODUCT_ID,/ * etc * /)
SELECT SYSGUID(),/ * etc * /

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


  1. 创建一个新的Product对象并保存。 Oracle分配ID。

  2. 将产品从Hibernate会话中分离出来。

  3. 您稍后重新附加并进行一些更改。
  4. >
  5. 您现在要保留这些更改。

不知道ID,Hibernate无法做到这一点。它需要该ID才能发出UPDATE语句。因此, org.hibernate.id.GUIDGenerator 的实现必须事先生成ID,然后再在INSERT语句中重新使用它。



如果您使用数据库生成的ID(包括支持它的数据库的自动递增),那么Hibernate无法执行任何批处理的原因是相同的。使用其中一个hilo生成器或其他Hibernate生成的ID机制是一次性插入大量对象时获得良好性能的唯一方法。


I am looking for a way to get hibernate to use oracle's SYS_GUID() function when inserting new rows. Currently my DB tables have SYS_GUID() as the default so if hibernate simply generated SQL that omited the value it should work.

I have everything working, but it is currently generating the UUID/GUID in code using the system-uuid generator:

@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;
}

This is fine, but I would prefer that the guids were generated by the database so they will be sequential and potentially have better performance. Plus I would just like to know how to configure this.

I am using annotations for configuration, but xml configuration examples are awesome as well.

Here is a sample table definition (in case it matters):

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)
)

UPDATE:

Mat's sollution of using "guid" worked, here is the sql generated:

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


It seems that using the columns default value in an insert is not possible, so the choice is between an application generated guid and a database round trip.

解决方案

You might be able to use the "guid" generator. See this post from the Hibernate forum. It looks like they added support for Oracle using SYS_GUID() a while back, but the documentation still says they only support SQL Server and MySQL.

I haven't worked with JPA annotations yet, but here is an example using XML configuration:

<id name="PRODUCT_ID">
  <generator class="guid" />
</id>

EDIT: In regards to your second question, I think you are asking why Hibernate can't do something like this:

INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
SELECT SYSGUID(), /* etc */

The reason is that Hibernate must know what the object's ID is. For example, consider the following scenario:

  1. You create a new Product object and save it. Oracle assigns the ID.
  2. You detach the Product from the Hibernate session.
  3. You later re-attach it and make some changes.
  4. You now want to persist those changes.

Without knowing the ID, Hibernate can't do this. It needs the ID in order to issue the UPDATE statement. So the implementation of org.hibernate.id.GUIDGenerator has to generate the ID beforehand, and then later on re-use it in the INSERT statement.

This is the same reason why Hibernate cannot do any batching if you use a database-generated ID (including auto-increment on databases that support it). Using one of the hilo generators, or some other Hibernate-generated ID mechanism, is the only way to get good performance when inserting lots of objects at once.

这篇关于配置Hibernate以使用Oracle的SYS_GUID()作为主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆