配置Hibernate使用Oracle的SYS_GUID()主键
题
我要寻找一种方式来获得冬眠中插入新行的时候使用Oracle的SYS_GUID()
功能。目前我的数据库表已SYS_GUID()
作为默认的,所以如果只是冬眠生成的SQL是被遗漏它应该工作的价值。
我有一切工作,但它当前生成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;
}
这是不错,但我更希望是由数据库生成的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)
)
UPDATE:
使用 “GUID” 的垫的sollution工作,这里是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 (?, ?, ?, ?, ?, ?)
<强>看来,在插入件使用的列默认值是不可能的,所以在选择是应用程序生成的GUID和数据库往返之间。强>
解决方案
您也许能够使用“GUID”发电机。请参见从Hibernate论坛上这个帖子。看起来他们使用SYS_GUID()
而回,增加了对甲骨文的支持,但的文档还是说,他们只支持SQL Server和MySQL。
我还没有被使用XML配置的示例与JPA注释工作尚未,但这里:
<id name="PRODUCT_ID">
<generator class="guid" />
</id>
编辑:在关于你的第二个问题,我想你会问,为什么休眠不能做这样的事情:
INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
SELECT SYSGUID(), /* etc */
原因是,休眠必须知道对象的ID是什么。例如,考虑以下情形:
- 您创建一个新的产品对象,并将其保存。甲骨文分配ID。
- 您分离从休眠会话的产品。
- 您稍后重新连接,并做出一些改变。
- 您现在要坚持这些更改。 醇>
如果不知道ID,Hibernate无法做到这一点。它需要以发出UPDATE语句的ID。所以org.hibernate.id.GUIDGenerator
的实现必须预先以后生成ID,然后在INSERT语句上重新使用它。
这是一样的道理,为什么休眠不能做的的任何配料的,如果你使用一个数据库生成的ID(包括支持它的数据库自动递增)。使用希洛发电机中的一个或一些其他的Hibernate生成的ID机构,是唯一的方法在一次插入大量的对象时获得良好的性能。
其他提示
我有相同的任务,该主题首发。与感谢的 @马特索尔尼特强>建议我使用这种注释:
@Id
@NotNull
@Column(name = "UUID")
@GenericGenerator(name = "db-uuid", strategy = "guid")
@GeneratedValue(generator = "db-uuid")
private String uuid;
public String getUuid() { return uuid; }
public void setUuid(String uuid) { this.uuid = uuid; }
和strategy = "guid"
类型String
是溶液的主要部分。
坚持新的实体Hibernate的问题SQL查询之前:
select rawtohex(sys_guid()) from dual
我的设置:甲骨文11,休眠4.3.4.Final,春季3.2.x.和字段是raw(16)
在表有效存储和较小索引的大小,然后如果使用char(32)
。
当我尝试使用java.util.UUID
作为ID字段I型从休眠得到错误上持续新实体(其尝试设置String
类型java.util.UUID
字段)。
此外,我使用javax.xml.bind.DatatypeConverter
用于非Hibernate查询(弹簧JDBC助手),用于使转换为byte[]
:
String query = "insert into TBL (UUID, COMPANY) values (:UUID, :COMPANY)";
MapSqlParameterSource parameters = new MapSqlParameterSource()
.addValue("COMPANY", repo.getCompany())
.addValue("UUID", DatatypeConverter.parseHexBinary(signal.getUuid()));
namedJdbcTemplate.update(query, parameters);
用于提取:
ResultSet rs;
sig.id = DatatypeConverter.printHexBinary(rs.getBytes("UUID"));
所有web控制器得到这样的代码:
025131763FB19522E050010A106D11E9
无{
,-
,}
字符(UUID的通常表示是{a-b-c-d-x-y}
如果记得)。这表示已经URL编码清洁和安全。你并不需要实现PropertyEditor
或Convertor
为String
类型:
@RequestMapping(value = {"/signal/edit/{id}.htm"}, method = RequestMethod.POST)
public String handleEditRequest(
@PathVariable("id") String id,
与失败的尝试使用jaa.util.UUID
,在这里我需要写比较:
@Component
public static class UUIDPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(final String str) {
if (str == null || str.isEmpty()) {
setValue(null);
return;
}
setValue(UUID.fromString(str));
}
}
private @Autowired UUIDPropertyEditor juuidPE;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(UUIDPropertyEditor.class, juuidPE);
}
为了使用:
@PathVariable("id") UUID id,
我想你可以通过发电机设置为本地做。我真的不知道怎么做,在休眠,但NHibernate的你会做的XML是这样的:
<id column="PRODUCT_ID">
<generator class="native"/>
</id>