Pregunta

Estoy buscando una manera de conseguir hibernate para el uso de 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 del 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:

Estera del 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.

¿Fue útil?

Solución

Usted puede ser capaz de utilizar el generador "GUID". Ver este post del foro de hibernación. Parece que se ha añadido soporte para Oracle mediante SYS_GUID() hace un tiempo, pero el documentación todavía dice que sólo son compatibles con SQL Server y MySQL.

No he trabajado con anotaciones JPA todavía, pero aquí hay un ejemplo usando la configuración de XML:

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

EDIT: En lo que respecta a su segunda pregunta, creo que usted está 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 tiene que saber cuál es el ID del objeto. Por ejemplo, considere la situación siguiente:

  1. Se crea un nuevo objeto del producto y guardarlo. Oracle asigna el ID.
  2. extrae el producto de la sesión de Hibernate.
  3. más tarde volver a adjuntarlo y hacer algunos cambios.
  4. Ahora desea persistir esos cambios.

Sin conocer la identificación, 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 más tarde volver a utilizarlo en la instrucción INSERT.

Esta es la misma razón por la que Hibernate no puede hacer cualquier dosificación si utiliza una base de datos ID-generado (incluyendo auto-incremento en las bases de datos que lo soporten). Utilizando uno de los generadores de Hilo, o algún otro mecanismo de identificación generada Hibernate, es la única manera de conseguir un buen rendimiento cuando se inserta un montón de objetos a la vez.

Otros consejos

Tengo la misma tarea que el tema de arranque.Gracias a @Matt Solnit una 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 de 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,

Creo que se puede hacer ajustando el generador para nativo. No estoy muy seguro de cómo hacerlo en Hibernate pero en NHibernate que haría algo como esto en el XML:

<id column="PRODUCT_ID">
  <generator class="native"/>
</id>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top