Configurar Hibernate para el uso de Oracle SYS_GUID() de la Clave Primaria

Estoy buscando una manera de conseguir que hibernate utiliza oracle SYS_GUID() función a la hora de insertar nuevas filas. Actualmente mi DB tablas tienen SYS_GUID() como el defecto, de modo que si hibernate simplemente SQL generado que se omite el valor que se debe trabajar.

Tengo todo funcionando, pero es en la actualidad la generación de los UUID/GUID en el código mediante el sistema-uuid generador:

@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "PRODUCT_ID", unique = true, nullable = false)
public String getId() {
    return this.productId;
}

Esto está muy bien, pero yo prefiero que el guid se han generado por la base de datos, de modo que será secuencial y, potencialmente, tienen un mejor rendimiento. Además, me gustaría saber cómo configurar esto.

Estoy usando anotaciones para la configuración, pero de configuración xml ejemplos son impresionantes también.

Aquí se muestra un ejemplo de definición de tabla (en el caso de que lo que importa):

CREATE TABLE SCHEMA_NAME.PRODUCT
(
    PRODUCT_ID RAW(16) DEFAULT SYS_GUID() NOT NULL,
    PRODUCT_CODE VARCHAR2(10 CHAR) NOT NULL,
    PRODUCT_NAME VARCHAR2(30 CHAR) NOT NULL,
    PRODUCT_DESC VARCHAR2(512 CHAR)
)

ACTUALIZACIÓN:

Placa sollution de la utilización de «guid» trabajado, aquí es el sql generado:

Hibernate: 
    select rawtohex(sys_guid()) 
    from dual
Hibernate: 
    insert into PRODUCT
    (PRODUCT_CODE, PRODUCT_DESC, LOB_ID, PRODUCT_NAME, PROVIDER_ID, PRODUCT_ID) 
    values (?, ?, ?, ?, ?, ?)

Parece que el uso de las columnas valor predeterminado en una inserción no es posible, así que la elección es entre una aplicación generada guid y una base de datos de ida y vuelta.

OriginalEl autor Ryan Cook | 2009-05-11

3 Kommentare

  1. 5

    Usted podría ser capaz de utilizar el «guid» generador. Ver este post de la Hibernación foro. Parece que se agregó soporte para Oracle mediante SYS_GUID() un tiempo, pero la documentación todavía dice que sólo son compatibles con SQL Server y MySQL.

    No he trabajado con las anotaciones JPA, pero aquí es un ejemplo del uso de XML de configuración:

    <id name="PRODUCT_ID">
      <generator class="guid" />
    </id>

    EDICIÓN: En cuanto a tu segunda pregunta, creo que se están preguntando por qué Hibernate no puede hacer algo como esto:

    INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
    SELECT SYSGUID(), /* etc */

    La razón es que Hibernate debe saber cuál es la ID del objeto es. Por ejemplo, considere el siguiente escenario:

    1. De crear un nuevo Producto objeto y guardarlo. Oracle asigna el ID.
    2. De separar el Producto de la sesión de Hibernate.
    3. Que más tarde vuelva a conectar y hacer algunos cambios.
    4. Ahora quiere persistir los cambios.

    Sin saber el ID, Hibernate no puede hacer esto. Se necesita el ID con el fin de emitir la instrucción UPDATE. Por lo que la implementación de org.hibernate.id.GUIDGenerator tiene que generar el ID de antemano, y luego en la re-uso en la instrucción INSERT.

    Esta es la misma razón por la que Hibernate no puede hacer cualquier lotes si utiliza una base de datos de ID generado (incluyendo el auto-incremento en las bases de datos que lo soporten). El uso de uno de los hilo generadores, o algún otro Hibernate-ID generado por el mecanismo, es la única manera de conseguir un buen rendimiento a la hora de insertar un montón de objetos a la vez.

    Esto funcionó, pero algunos extra sql, ver mis actualizaciones. Gracias por su tiempo.
    Hola Ryan. He editado mi respuesta a intentar responder a tu pregunta de seguimiento.
    FYI: Hacer esto a través de la anotación es simple: @GenericGenerator(name = «guid», estrategia = «guid»)
    Para mí, tuve que dar dos annotatations @GeneratedValue(generador=»db-guid») @GenericGenerator(name=»db-guid», estrategia = «guid»)

    OriginalEl autor Matt Solnit

  2. 1

    Tengo la misma tarea que el tema de arranque. Gracias a @Matt Solnit sugerencia que el uso de tales anotaciones:

    @Id
    @NotNull
    @Column(name = "UUID")
    @GenericGenerator(name = "db-uuid", strategy = "guid")
    @GeneratedValue(generator = "db-uuid")
    private String uuid;
    public String getUuid() { return uuid; }
    public void setUuid(String uuid) { this.uuid = uuid; }

    strategy = "guid" y String tipo son parte esencial de la solución.

    Antes de la persistencia de las nuevas entidades de Hibernación tema de consulta SQL:

    select rawtohex(sys_guid()) from dual

    Mi configuración: Oracle 11, Hibernate 4.3.4.Final De La Primavera, 3.2.x. Y el campo es raw(16) en la tabla para el almacenamiento eficiente y menor índice de tamaño, a continuación, si usted utiliza char(32).

    Cuando trato de usar java.util.UUID como campo ID de tipo I error de Hibernación en la persistencia de la nueva entidad (es tratar de establecer String tipo de java.util.UUID campo).

    También puedo usar javax.xml.bind.DatatypeConverter para los no-Hibernate consultas (Spring JDBC ayudantes), para el paso de convertir a byte[]:

    String query = "insert into TBL (UUID, COMPANY) values (:UUID, :COMPANY)";
    MapSqlParameterSource parameters = new MapSqlParameterSource()
        .addValue("COMPANY", repo.getCompany())
        .addValue("UUID", DatatypeConverter.parseHexBinary(signal.getUuid()));
    namedJdbcTemplate.update(query, parameters);

    para la extracción:

    ResultSet rs;
    sig.id = DatatypeConverter.printHexBinary(rs.getBytes("UUID"));

    Todas las web de los controladores de obtener los códigos como:

    025131763FB19522E050010A106D11E9

    sin {, -, } caracteres (como es habitual la representación de UUID es {a-b-c-d-x-y} si te acuerdas). Esta representación ya codificación URL limpia y segura. Usted no necesita implementar PropertyEditor o Convertor para String tipo:

    @RequestMapping(value = {"/signal/edit/{id}.htm"}, method = RequestMethod.POST)
    public String handleEditRequest(
            @PathVariable("id") String id,

    Comparar con el intento fallido de uso jaa.util.UUID, donde tengo que escribir:

    @Component
    public static class UUIDPropertyEditor extends PropertyEditorSupport {
        @Override
        public void setAsText(final String str) {
            if (str == null || str.isEmpty()) {
                setValue(null);
                return;
            }
            setValue(UUID.fromString(str));
        }
    }
    private @Autowired UUIDPropertyEditor juuidPE;
    
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(UUIDPropertyEditor.class, juuidPE);
    }

    con el fin de utilizar:

    @PathVariable("id") UUID id,

    OriginalEl autor gavenkoa

  3. 0

    Creo que usted puede hacerlo mediante la configuración del generador a los nativos. No estoy realmente seguro de cómo hacerlo en modo de Hibernación, pero en NHibernate te gustaría hacer algo como esto en el XML:

    <id column="PRODUCT_ID">
      <generator class="native"/>
    </id>
    «nativo» es la secuencia en Oracle. Por lo tanto, lo dudo. Pero tratando de que no es una mala idea.
    Por cierto, que ha especificado que hacer esto en NHibernate, pero no especificó la base de datos y esa es la principal gran preocupación aquí.
    Hay una muy buena probabilidad de que estoy equivocado, acabo de empezar a usar NHibernate.

    OriginalEl autor cdmckay

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea