Проблема получения сущностей с уникальным идентификатором первичного ключа - PullRequest
2 голосов
/ 25 января 2011

Чтобы выяснить, отличается ли поведение Hibernate от поведения NHibernate для конкретного сценария использования , я начал писать порт Java SE & Hibernate для соответствующих частей моего приложения на основе NHibernate, но столкнулся с проблемойс получением объекта, в котором соответствующая таблица 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..., но это не та привязка значения, которую я ожидал, ион предотвращает нахождение объекта пользователя.

Если я изменю тип поля 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?

Ответы [ 2 ]

6 голосов
/ 25 января 2011

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();
}

Просто убедитесь, что при выполнении сопоставления на основе свойств Hibernate знает, что поле UUID является временным полем, и не пытается хранить как идентификатор, так и UUID.

Вполне возможно, что SQL-сервер имеет какой-то особый класс UUID, который вы можете использовать в Java, который может конвертировать в / из Java UUID. Также возможно, что в какой-то новой версии Hibernate появилась поддержка отображения java.util.UUID в UUID SQL Server, но я не думаю, что какая-либо из этих возможностей верна.

Редактировать: После более подробного изучения проблемы я вижу некоторую вашу путаницу. Похоже, что NHibernate действительно конвертирует из System.GUID в uniqueidentifier SQL Server (имеет смысл, так как оба выпущены Microsoft). Тем не менее, я не верю, что есть эквивалент Hibernate.

2 голосов
/ 15 августа 2014

У меня была такая же проблема, и я решил ее, добавив тип 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>
<!-- ... -->
...