PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Хибернация UUID с PostgreSQL и SQL Server

Имах подобни изисквания, но също исках да използвам Hibernate DDL генериране и да се уверя, че SQL Server генерира уникален тип идентификатор, а също така исках да поддържам hsqldb за тестване на единици. За да използвате UUID в SQL Server, определено искате да преминете през низове, а не двоични , тъй като двоичното представяне в SQL Server е за GUID, който е различен от UUID. Вижте например различно представяне на UUID в Java Hibernate и SQL Server

Можете да създадете правилното съпоставяне и да генерирате правилния sql за SQL Server с:

@Type(type = "uuid-char")
@Column(columnDefinition="uniqueidentifier")
public UUID getUuid()

И това просто работи както е, но за съжаление няма начин в Hibernate да има различни дефиниции на колони за различни бази данни, така че това ще се провали на нещо различно от SQL Server.

Така че, трябва да изминете дългия път. Това е всичко за Hibernate 4.3:

  1. Регистрирайте нов тип GUID sql в заменен SQLServerDialect и използвайте този диалект вместо основния

    public class SQLServer2008UnicodeDialect extends SQLServer2008Dialect
    {
        public SQLServer2008UnicodeDialect() 
        {
            // the const is from the MS JDBC driver, the value is -145
            registerColumnType( microsoft.sql.Types.GUID, "uniqueidentifier" ); 

            // etc. Bonus hint: I also remap all the varchar types to nvarchar while I'm at it, like so:
            registerColumnType( Types.CLOB, "nvarchar(MAX)" );
            registerColumnType( Types.LONGVARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.LONGNVARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.VARCHAR, "nvarchar(MAX)" );
            registerColumnType( Types.VARCHAR, 8000, "nvarchar($l)" );
        }
     }
  1. Създайте обвивка UUIDCustomType, която се държи подобно на вградения UUIDCharType, но делегира в зависимост от типа база данни. Трябва да извикате init(databaseType) преди Конфигурация за хибернация. Може би персонализираният диалект би могъл да го направи, но аз наричам това при стартирането на моето Spring приложение.

DatabaseType беше изброяване, което вече имах, което е зададено въз основа на системната конфигурация, модифицирайте го по вкус с помощта на диалектен клас или низ или каквото и да било.

Това е вариант на това, което е описано на https://zorq.net/b/2012/04/21/switching-hibernates-uuid-type-mapping-per-database/

public enum DatabaseType
{
    hsqldb,
    sqlserver,
    mysql,
    postgres
}

public class UUIDCustomType extends AbstractSingleColumnStandardBasicType<UUID> implements LiteralType<UUID>
{
    private static final long serialVersionUID = 1L;

    private static SqlTypeDescriptor SQL_DESCRIPTOR;
    private static JavaTypeDescriptor<UUID> TYPE_DESCRIPTOR;

    public static void init( DatabaseType databaseType )
    {
        if ( databaseType == DatabaseType.sqlserver )
        {
            SQL_DESCRIPTOR = SqlServerUUIDTypeDescriptor.INSTANCE;
        }
        else if ( databaseType == DatabaseType.postgres  )
        {
            SQL_DESCRIPTOR = PostgresUUIDType.PostgresUUIDSqlTypeDescriptor.INSTANCE;
        }
        else
        {
            SQL_DESCRIPTOR = VarcharTypeDescriptor.INSTANCE;
        }

        TYPE_DESCRIPTOR = UUIDTypeDescriptor.INSTANCE;
    }

    public UUIDCustomType()
    {
        super( SQL_DESCRIPTOR, TYPE_DESCRIPTOR );
    }

    @Override
    public String getName()
    {
        return "uuid-custom";
    }

    @Override
    public String objectToSQLString( UUID value, Dialect dialect ) throws Exception
    {
        return StringType.INSTANCE.objectToSQLString( value.toString(), dialect );
    }

    public static class SqlServerUUIDTypeDescriptor extends VarcharTypeDescriptor
    {
        private static final long serialVersionUID = 1L;

        public static final SqlServerUUIDTypeDescriptor INSTANCE = new SqlServerUUIDTypeDescriptor();

        public SqlServerUUIDTypeDescriptor()
        {
        }

        @Override
        public int getSqlType()
        {
            return microsoft.sql.Types.GUID;
        }
    }
}
  1. Регистрирайте персонализирания тип на място, което Hibernate ще вземе (имам общ базов клас за всички обекти). Регистрирам го с помощта на defaultForType =UUID.class, така че всички UUID да го използват, което означава, че изобщо не е необходимо да коментирам свойствата на UUID.

    @TypeDefs( {
            @TypeDef( name = "uuid-custom", typeClass = UUIDCustomType.class, defaultForType = UUID.class )
    } )
    public class BaseEntityWithId { 

Предупреждение:всъщност не е тестван с postgres, но работи чудесно за hsqldb и sql сървър на Hibernate 4.3.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgresql не създава db с „createdb“ като суперпотребител, но не извежда грешки

  2. Обединете една колона в заявка с много колони

  3. Как да вмъкнете и изтриете данни в PostgreSQL

  4. Дълбоко гмуркане на доставчик на облак:PostgreSQL на AWS Aurora

  5. Как да получите последния ред на група в PostgreSQL