2011-01-24 29 views
2

爲了研究Hibernate的行爲是否與NHibernate的行爲不同,我開始編寫基於NHibernate的應用程序的相關部分的Java SE & Hibernate端口,但遇到了獲取實體,其中對應的SQL Server 2008 R2 Express表使用uniqueidentifier作爲主鍵。獲取具有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")); 

的問題是,在調用活動#得到回報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...,但這不是綁定的值,我預期,並阻止用戶從實體被定位。

如果我從java.util.UUID改變hibernatetest.entity.Userid字段的類型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值呢?

回答

6

Java UUIDjava.util.UUID)和SQL Server uniqueidentifier是兩個不同的東西。您正在告訴Hibernate在兩者之間進行映射。我很驚訝Hibernate能夠做任何事情,並不奇怪它產生的東西非常奇怪。

盡我知道(不這樣做與SQL Server大量的工作)Hibernate的是要治療uniqueidentifier作爲一個普通的老String列。因此,您最好的選擇可能是將其映射爲字符串。你仍然可以有一個getUUID()setUUID()爲...

public UUID getUUID() { 
    return UUID.fromString(id); 
} 

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

只要確保如果你正在做基於屬性的映射是Hibernate知道的UUID字段是一個短暫的領域,而不是試圖同時存儲ID和UUID。

這有可能是SQL服務器有一些一種特殊的UUID類的,你可以在Java中使用,可以轉換到/從Java UUID。這也有可能是休眠的一些新版本還推出了用於映射java.util.UUID中支持SQL Server的UUID,但我不認爲任何這些可能性是真實的。

編輯:尋找到這個問題後,我還可以看到你的一些困惑。看起來NHibernate DOES實際上是從System.GUID轉換爲SQL Server的uniqueidentifier(這是合理的,因爲兩者都是微軟相關的)。但是,我不相信有一個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> 
<!-- ... --> 
+0

對於我們這些使用註釋`@Type(type =「uuid-char」)` – sMaN 2017-06-01 05:34:17

相關問題