PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Hibernuj UUID z PostgreSQL i SQL Server

Miałem podobne wymagania, ale chciałem też użyć generowania Hibernate DDL i upewnić się, że SQL Server wygenerował typ uniqueidentifier, a także chciałem wspierać hsqldb do testów jednostkowych. , ponieważ reprezentacja binarna w SQL Server dotyczy identyfikatora GUID, który różni się od identyfikatora UUID. Zobacz na przykład Różne reprezentacje UUID w Java Hibernate i SQL Server

Możesz utworzyć poprawne mapowanie i wygenerować poprawny sql dla SQL Server za pomocą:

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

Działa to po prostu tak, jak jest, ale niestety w Hibernate nie ma sposobu, aby mieć różne definicje kolumn dla różnych baz danych, więc nie powiedzie się to na czymkolwiek innym niż SQL Server.

Więc musisz iść daleko. To wszystko dla Hibernate 4.3:

  1. Zarejestruj nowy typ GUID sql w nadpisanym SQLServerDialect i użyj tego dialektu zamiast podstawowego

    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. Utwórz opakowanie UUIDCustomType, które zachowuje się podobnie do wbudowanego UUIDCharType, ale deleguje w zależności od typu bazy danych. Musisz wywołać init(databaseType) przed Konfiguracja hibernacji. Może niestandardowy dialekt mógłby to zrobić, ale nazywam to podczas uruchamiania aplikacji Spring.

DatabaseType to wyliczenie, które już miałem, które zostało ustawione na podstawie konfiguracji systemu, zmodyfikuj go według własnego gustu za pomocą klasy dialektu, ciągu lub czegokolwiek.

Jest to odmiana tego, co opisano na 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. Zarejestruj typ niestandardowy w lokalizacji, którą wybierze Hibernate (mam wspólną klasę bazową dla wszystkich encji). Rejestruję go przy użyciu defaultForType =UUID.class, aby wszystkie identyfikatory UUID go używały, co oznacza, że ​​nie muszę w ogóle dodawać adnotacji do właściwości UUID.

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

Zastrzeżenie:właściwie nie testowane z postgresem, ale działa świetnie na serwerze hsqldb i sql w 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. Mieszanie sprzężeń jawnych i niejawnych kończy się niepowodzeniem z Istnieje wpis dla tabeli ... ale nie można się do niego odwoływać z tej części zapytania

  2. Jak Asind() działa w PostgreSQL

  3. Eliminacja podziału mózgu PostgreSQL w bazach danych w wielu chmurach

  4. Maksymalna (użyteczna) liczba wierszy w tabeli Postgresql

  5. Postgres SELECT gdzie WHERE jest UUID lub ciągiem