Dan*_*ien 2 java sql-server uuid hibernate uniqueidentifier
为了研究Hibernate的行为是否与NHibernate的特定使用场景不同,我开始编写基于NHibernate的应用程序相关部分的Java SE和Hibernate端口,但遇到了获取相应SQL Server的实体的问题2008 R2 Express表使用a uniqueidentifier
作为主键.
这是映射文件:
<!-- User.hbm.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernatetest.entity.User" table="aspnet_Users">
<id name="Id">
<column name="UserId" sql-type="uniqueidentifier" not-null="true" />
</id>
<!-- ... -->
Run Code Online (Sandbox Code Playgroud)
和相应的POJO定义:
// hibernatetest/entity/User.java
package hibernatetest.entity;
import java.util.UUID;
public class User {
private UUID id;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
//...
Run Code Online (Sandbox Code Playgroud)
主要代码:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
User currentUser = (User) session.get(User.class, UUID.fromString("473D248D-8D91-41C9-BD73-8ACA45539D79"));
Run Code Online (Sandbox Code Playgroud)
问题是对Session#get的调用返回null
,因为它无法找到主键的用户实体'473D248D-8D91-41C9-BD73-8ACA45539D79'
.
当我启用完整日志记录时,我看到:
DEBUG [main] (AbstractBatcher.java:401) - select user0_.UserId as UserId0_0_ from aspnet_Users user0_ where user0_.UserId=?
Hibernate: select user0_.UserId as UserId0_0_ from aspnet_Users user0_ where user0_.UserId=?
TRACE [main] (NullableType.java:133) - binding '2c6d8085f3f2808eeae1f6e1aef5f4e9ecaed5d5c9c43c19837718ed05af828082ca808cece5e1f3f4d3e9e7c2e9f4f3ca808bedeff3f4d3e9e7c2e9f4f3f8f03df30a4ac5d31df9c7bda40d0d11c149' to parameter: 1
Run Code Online (Sandbox Code Playgroud)
我不知道Hibernate如何派生值'2c6d8085f...
,但这不是我期望的值绑定,它阻止了用户实体的定位.
如果我改变的类型id
的字段hibernatetest.entity.User
从java.util.UUID
到String
,那么这行成功地找到实体:
User currentUser = (User) session.get(User.class, "473D248D-8D91-41C9-BD73-8ACA45539D79");
Run Code Online (Sandbox Code Playgroud)
并且日志输出变为:
DEBUG [main] (AbstractBatcher.java:401) - select user0_.UserId as UserId0_0_ from aspnet_Users user0_ where user0_.UserId=?
Hibernate: select user0_.UserId as UserId0_0_ from aspnet_Users user0_ where user0_.UserId=?
TRACE [main] (NullableType.java:133) - binding '473D248D-8D91-41C9-BD73-8ACA45539D79' to parameter: 1
Run Code Online (Sandbox Code Playgroud)
Hibernate是如何计算'2c6d8085f...
为UUID绑定的值的'473D248D-8D91-41C9-BD73-8ACA45539D79'
?如何让它绑定实际的UUID值呢?
Java UUID
(java.util.UUID
)和SQL Server uniqueidentifier
是两回事.你告诉Hibernate在两者之间进行映射.我很惊讶Hibernate能够做任何事情,并且不会感到惊讶它产生的东西是非常奇怪的.
我最了解(不要对SQL Server做太多工作)Hibernate将把它uniqueidentifier
视为一个普通的旧String列.因此,您最好的选择可能是将其映射为String.你仍然可以有一个getUUID()
和setUUID()
为...
public UUID getUUID() {
return UUID.fromString(id);
}
public void setUUID(UUID val) {
id = val.toString();
}
Run Code Online (Sandbox Code Playgroud)
只是确保你正在进行基于属性的映射,Hibernate知道UUID字段是一个瞬态字段,并且不会尝试存储ID和UUID.
SQL服务器可能具有某种特殊的UUID类,您可以在Java中使用它来转换为Java UUID或从Java UUID转换.一些新版本的Hibernate也可能支持将java.util.UUID映射到SQL Server的UUID,但我不认为这些可能性都是正确的.
编辑:在进一步研究问题后,我可以看到你的一些困惑.似乎NHibernate实际上转换System.GUID
为SQL Server uniqueidentifier
(因为两者都是微软相关的).但是,我不相信有一个Hibernate等价物.
归档时间: |
|
查看次数: |
5546 次 |
最近记录: |