Pregunta

Básicamente, quiero una forma de acceder a los valores de secuencia de forma neutral en la base de datos. El caso de uso es que tengo un campo en una entidad que quiero establecer en función de un valor incremental (que no sea la identificación).

Por ejemplo, supongamos que tengo una entidad Shipment . En algún momento después de que se crea el envío, se envía. Una vez que se envía, se genera un número de manifiesto y se le asigna. El número de manifiesto se parece a M000009 (donde el contenido después de la 'M' es un valor rellenado por la izquierda de una secuencia).

Algo similar se preguntó aquí en SO , pero no soy fanático de la solución, ya que requiere otra tabla para mantener y parece una relación extraña para tener.

¿Alguien sabe si es posible usar algo como MultipleHiLoPerTableGenerator de hibernate como algo más que un generador de ID?

Si eso no es posible, ¿alguien sabe de alguna biblioteca que maneje esto (ya sea usando hibernate o incluso JDBC puro)? Prefiero no tener que escribir esto yo mismo (y tener que lidiar con valores de captación previa, bloqueo y sincronización).

Gracias.

¿Fue útil?

Solución

Creo que la complejidad de tu tarea depende de si tu número manifiesto debe ser secuencial o no:

  • Si no necesita números de manifiesto secuenciales, entonces son días felices y puede usar una secuencia.
  • Si necesita números de manifiesto secuenciales (o su base de datos no admite secuencias), utilice una tabla de identificación con el bloqueo apropiado para que cada transacción obtenga un valor secuencial único.

Entonces tienes 2 opciones que se me ocurren:

  • escriba el código JDBC necesario en su cliente, asegurándose (si el número de manifiesto es secuencial) que la transacción que se está utilizando es la misma que para la actualización de la base de datos.
  • use un disparador para crear el número de manifiesto cuando se produzca la actualización apropiada.

Creo que mi preferencia sería el desencadenante porque el lado de la transacción de las cosas sería atendido, aunque significaría que el objeto necesitaría actualizarse en el cliente.

Otros consejos

No leí la solución similar vinculada, pero suena como algo que terminé haciendo. He creado una tabla solo para secuencias. Agregué una fila a la tabla para cada tipo de secuencia que necesitaba.

Luego tuve una clase de generador de secuencia que haría la consulta sql necesaria para buscar y actualizar el valor de secuencia para una secuencia con nombre en particular.

Utilicé la clase Dialecto de hibernate para hacerlo de forma neutral db.

También 'cachearía' las secuencias. Subiría el valor de la secuencia almacenada en un gran número, y luego repartiría esas secuencias asignadas de mi clase de generador. Si la clase se destruye (es decir, cierre de la aplicación), una nueva instancia del generador de secuencia se iniciará en el valor almacenado. (tener un espacio en mis números de secuencia no importaba)

Aquí hay un ejemplo de código. Me gustaría advertir esto: no he compilado esto y requiere un código de primavera. Dicho esto, aún debería proporcionar los huesos de lo que quieres hacer.

public Long getManifestNumber() {
        final Object result = getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session sess) throws HibernateException, SQLException { 
                SQLQuery sqlQuery = sess.createSQLQuery("select MY_SEQUENCE.NEXTVAL from dual");
                sqlQuery.uniqueResult();
            }
        });
        Long toReturn;
        if (result instanceof BigDecimal) {
            toReturn = ((BigDecimal)result).longValue();
        }
        return toReturn;
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top