【问题标题】:Problem obtaining entities with uniqueidentifier primary key获取具有唯一标识符主键的实体的问题
【发布时间】:2011-06-14 20:18:48
【问题描述】:

为了调查 Hibernate 的行为是否与 NHibernate 的 for a particular usage scenario 不同,我开始为我的基于 NHibernate 的应用程序的相关部分编写 Java SE & Hibernate 端口,但在获取对应 SQL 的实体时遇到问题Server 2008 R2 Express 表使用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>
    <!-- ... -->

以及对应的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;
    }
    //...

主要代码:

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

问题是对 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

我不知道 Hibernate 是如何得出值 '2c6d8085f... 的,但这不是我期望的值绑定,它会阻止用户实体的定位。

如果我将hibernatetest.entity.Userid字段的类型从java.util.UUID更改为String,那么这一行就成功找到了实体:

User currentUser = (User) session.get(User.class, "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 '473D248D-8D91-41C9-BD73-8ACA45539D79' to parameter: 1

Hibernate 是如何计算值 '2c6d8085f... 以绑定 UUID '473D248D-8D91-41C9-BD73-8ACA45539D79'?我怎样才能让它绑定实际的 UUID 值?

【问题讨论】:

    标签: java sql-server hibernate uuid uniqueidentifier


    【解决方案1】:

    Java UUID (java.util.UUID) 和 SQL Server uniqueidentifier 是两个不同的东西。您是在告诉 Hibernate 在两者之间进行映射。我很惊讶 Hibernate 能够做任何事情,而且它生成的东西非常奇怪,这并不奇怪。

    据我所知(不要对 SQL Server 做太多工作)Hibernate 会将uniqueidentifier 视为普通的旧字符串列。因此,您最好的选择可能是将其映射为字符串。您仍然可以将getUUID()setUUID() 作为...

    public UUID getUUID() {
        return UUID.fromString(id);
    }
    
    public void setUUID(UUID val) {
        id = val.toString();
    }
    

    只要确保 Hibernate 知道 UUID 字段是临时字段并且不会尝试同时存储 ID 和 UUID 的基于属性的映射。

    SQL Server 可能有某种特殊的 UUID 类,您可以在 Java 中使用该类可以与 Java UUID 相互转换。也有可能一些新版本的 Hibernate 支持将 java.util.UUID 映射到 SQL Server 的 UUID,但我认为这两种可能性都不是真的。

    编辑:进一步研究问题后,我可以看到您的一些困惑。看起来 NHibernate 实际上确实从 System.GUID 转换为 SQL Server 的 uniqueidentifier(因为两者都与 Microsoft 相关,所以很有意义)。但是,我不相信有 Hibernate 等价物。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,我通过在列中添加uuid-char 类型解决了它。

      <!-- User.hbm.xml -->
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http //www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
      <hibernate-mapping>
          <class name="hibernatetest.entity.User" table="aspnet_Users">
              <id name="Id" type="uuid-char">
                  <column name="UserId" sql-type="uniqueidentifier" not-null="true" />
              </id>
      <!-- ... -->
      

      【讨论】:

      • 对于我们这些使用注释的人@Type(type = "uuid-char")
      猜你喜欢
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      相关资源
      最近更新 更多