Postgresql UUID поддерживается Hibernate?

Я не могу заставить Hibernate работать с java.util.UUID для PostgreSQL.

Вот отображение с использованием javax.persistence. * Аннотации:

private UUID itemUuid; @Column(name="item_uuid",columnDefinition="uuid NOT NULL") public UUID getItemUuid() { return itemUuid; } public void setItemUuid(UUID itemUuid) { this.itemUuid = itemUuid; } 

При сохранении переходного объекта я получаю исключение SQLGrammarException:

 column "item_uuid" is of type uuid but expression is of type bytea at character 149 

Версия PostgreSQL – 8.4.4
Драйвер JDBC – 8.4.4-702 (также пробовал 9.0 – то же самое)
Версия Hibernate – 3,6, основные свойства конфигурации:

 org.hibernate.dialect.PostgreSQLDialect org.postgresql.Driver jdbc:postgresql://192.168.1.1/db_test 

Это можно решить, добавив в UUID следующую аннотацию:

 import org.hibernate.annotations.Type; ... @Type(type="pg-uuid") private java.util.UUID itemUuid; 

Что касается того, почему Hibernate не просто делает это настройкой по умолчанию, я не могу сказать вам …

UPDATE: по-прежнему возникают проблемы с использованием метода createNativeQuery для открытия объектов с полями UUID. К счастью, метод createQuery до сих пор отлично работал для меня.

Вы пытаетесь сохранить объект типа UUID, который не является аннотированным объектом с гибернацией. Таким образом, hibernate хочет сериализовать его в байтовый массив (тип blob). Вот почему вы получаете это сообщение «выражение типа bytea».

Вы можете либо хранить UUID в виде блоков в базе данных (не изящно), либо предоставлять свой собственный сериализатор (много работы) или вручную конвертировать этот объект. Класс UUID имеет методы fromString и toString, поэтому я бы сохранил его как String.

Как уже упоминалось, решение этой проблемы заключается в добавлении @Type(type = "pg-uuid") . Однако этот тип несовместим с типами UUID других поставщиков, поэтому это связывает ваши classы Hibernate с Postgres. Чтобы обойти это, можно вставить эту аннотацию во время выполнения. Ниже приведено описание для Hibernate 4.3.7.

Во-первых, вам нужно вставить пользовательский поставщик метаданных для вставки аннотаций. Сделайте это как первый шаг после создания экземпляра classа Configuration :

 // Perform some test to verify that the current database is Postgres. if (connectionString.startsWith("jdbc:postgresql:")) { // Replace the metadata provider with our custom metadata provider. MetadataProviderInjector reflectionManager = MetadataProviderInjector)cfg.getReflectionManager(); reflectionManager.setMetadataProvider(new UUIDTypeInsertingMetadataProvider(reflectionManager.getMetadataProvider())); } 

Этот пользовательский поставщик метаданных находит поля и методы типа UUID . Если он находит один, он вставляет экземпляр annotations org.hibernate.annotations.Type что тип должен быть "pg-uuid" :

 package nl.gmt.data; import org.hibernate.annotations.Parameter; import org.hibernate.annotations.Type; import org.hibernate.annotations.common.reflection.AnnotationReader; import org.hibernate.annotations.common.reflection.MetadataProvider; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.UUID; class UUIDTypeInsertingMetadataProvider implements MetadataProvider { private final Map cache = new HashMap<>(); private final MetadataProvider delegate; public UUIDTypeInsertingMetadataProvider(MetadataProvider delegate) { this.delegate = delegate; } @Override public Map getDefaults() { return delegate.getDefaults(); } @Override public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) { // This method is called a lot of times on the same element, so annotation // readers are cached. We only cache our readers because the provider // we delegate to also caches them. AnnotationReader reader = cache.get(annotatedElement); if (reader != null) { return reader; } reader = delegate.getAnnotationReader(annotatedElement); // If this element is a method that returns a UUID, or a field of type UUID, // wrap the returned reader in a new reader that inserts the "pg-uuid" Type // annotation. boolean isUuid = false; if (annotatedElement instanceof Method) { isUuid = ((Method)annotatedElement).getReturnType() == UUID.class; } else if (annotatedElement instanceof Field) { isUuid = ((Field)annotatedElement).getType() == UUID.class; } if (isUuid) { reader = new UUIDTypeInserter(reader); cache.put(annotatedElement, reader); } return reader; } private static class UUIDTypeInserter implements AnnotationReader { private static final Type INSTANCE = new Type() { @Override public Class annotationType() { return Type.class; } @Override public String type() { return "pg-uuid"; } @Override public Parameter[] parameters() { return new Parameter[0]; } }; private final AnnotationReader delegate; public UUIDTypeInserter(AnnotationReader delegate) { this.delegate = delegate; } @Override @SuppressWarnings("unchecked") public  T getAnnotation(Class annotationType) { if (annotationType == Type.class) { return (T)INSTANCE; } return delegate.getAnnotation(annotationType); } @Override public  boolean isAnnotationPresent(Class annotationType) { return annotationType == Type.class || delegate.isAnnotationPresent(annotationType); } @Override public Annotation[] getAnnotations() { Annotation[] annotations = delegate.getAnnotations(); Annotation[] result = Arrays.copyOf(annotations, annotations.length + 1); result[result.length - 1] = INSTANCE; return result; } } } 

Решение для тех, кто не использует JPA.

До:

    

После:

   
  • PostgreSQL: состояние состояния сбрасывания без блокировки
  • PostgreSQL Autoincrement
  • Postgres вручную изменяют последовательность
  • Массив Unnest на один уровень
  • Есть ли ярлык для SELECT * FROM?
  • Почему PostgreSQL выполняет последовательное сканирование индексированного столбца?
  • Как я могу использовать UTF-8 в Linux из Windows 7 через PuTTY?
  • Вставить текст с одинарными кавычками в PostgreSQL
  • INSERT с динамическим именем таблицы в триггерной функции
  • Не удается найти заголовок libpq-fe.h при попытке установить pg gem
  • Postgres sql вставляет запрос синтаксиса запроса из phpPgAdmin
  • Interesting Posts

    Заполните большой диапазон формулой в Excel, без перетаскивания мышью, чтобы расширить

    CUDA несовместим с моей версией gcc

    CSS ‘>’ селектор; что это?

    Как создать открытую беспроводную сеть вместе с частной беспроводной сетью?

    POI. Как установить значение ячейки в Date и применить формат даты по умолчанию Excel?

    Где EXE для подсистемы для Unix-приложений, поэтому я могу использовать его?

    Функции вызова со специальным префиксом / суффиксом

    Android SAF (Storage Access FrameWork): получите конкретный файл Uri от TreeUri

    Будет ли работать разъем HDMI-VGA?

    Правильное измерение нового блока питания

    Является ли переход от Windows 8.1 Pro к Windows 7 Professional обратимым?

    Как остановить процентное расширение в пакетном файле?

    Возможно ли иметь BitLocker и FileVault на том же MacBoock Pro с Mac OS X Yosemite или El Capitan и Windows 10?

    Можем ли мы перегрузить основной метод в Java?

    iPhone – UIWebview – Получите URL-адрес ссылки, нажатой

    Давайте будем гением компьютера.