2011-01-24 2 views
2

Чтобы выяснить, отличается ли поведение Hibernate от NHibernate for a particular usage scenario, я начал писать порт Hibernate Java SE & соответствующих частей моего приложения на базе NHibernate, но столкнулся с проблемой получения где соответствующая таблица 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")); 

Проблема заключается в том, что вызов Session # получить возврат 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..., но это не значение связывания, что я ожидал, и это предотвращает объект пользователя от находясь.

Если изменить тип id области hibernatetest.entity.User от 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?

ответ

6

Java UUID (java.util.UUID) и SQL Server uniqueidentifier - это две разные вещи. Вы говорите Hibernate, чтобы отобразить между ними. Я удивлен, что Hibernate может вообще что-то сделать, и не удивляется, что то, что он создает, очень странно.

Насколько я знаю (не очень много работаю с SQL Server). Спящий режим будет обрабатывать 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, который может конвертировать в/из UUID Java. Также возможно, что появилась новая версия Hibernate с поддержкой сопоставления java.util.UUID с UUID SQL Server, но я не думаю, что любая из этих возможностей верна.

Редактировать: После дальнейшего изучения проблемы я вижу некоторые из ваших замешательств.Похоже, что 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> 
<!-- ... --> 
+0

Для тех из нас, кто использует аннотации '@Type (type =" uuid-char ")' – sMaN

Смежные вопросы