Question

En gros, je veux un moyen d’accéder aux valeurs de séquence de manière neutre. Le cas d'utilisation est que j'ai un champ sur une entité que je veux définir en fonction d'une valeur d'incrémentation (autre que l'id).

Par exemple, disons que j'ai une entité Envoi . À un moment donné, une fois l'envoi créé, il est expédié. Une fois expédié, un numéro de manifeste est généré et attribué. Le numéro de manifeste ressemble à quelque chose comme M000009 (où le contenu après le "M" est une valeur complétée à gauche d'une séquence).

Quelque chose de similaire a été demandé ici à SO , mais je ne suis pas un fan de la solution car il nécessite une autre table à maintenir et semble être une relation étrange d'avoir.

Est-ce que quelqu'un sait s'il est possible d'utiliser quelque chose comme le MultipleHiLoPerTableGenerator d'Hibernate comme autre chose qu'un générateur d'identifiant?

Si cela n’est pas possible, est-ce que quelqu'un connaît des bibliothèques qui gèrent cela (en utilisant le mode hibernation ou même simplement du JDBC pur)? Je préférerais ne pas avoir à écrire moi-même (et gérer les valeurs de pré-extraction, le verrouillage et la synchronisation).

Merci.

Était-ce utile?

La solution

Je pense que la complexité de votre tâche dépend de si votre numéro de manifeste doit être séquentiel ou non:

  • Si vous n'avez pas besoin de numéros de manifeste séquentiels, alors c'est un jour heureux et vous pouvez utiliser une séquence.
  • Si vous avez besoin de numéros de manifeste séquentiels (ou si votre base de données ne prend pas en charge les séquences), utilisez une table d'id avec le verrouillage approprié pour que chaque transaction obtienne une valeur séquentielle unique.

Ensuite, vous avez 2 options auxquelles je peux penser:

  • écrivez le code JDBC nécessaire sur votre client, en vous assurant (si le numéro de manifeste est séquentiel) que la transaction utilisée est la même que celle utilisée pour la mise à jour de la base de données.
  • utilisez un déclencheur pour créer le numéro de manifeste lorsque la mise à jour appropriée est effectuée.

Je pense que ma préférence serait le déclencheur, car les transactions seraient prises en charge même si cela signifierait que l'objet aurait besoin d'être actualisé sur le client.

Autres conseils

Je n’ai pas lu la solution similaire liée, mais cela ressemble à quelque chose que j’ai fini par faire. J'ai créé une table juste pour les séquences. J'ai ajouté une ligne à la table pour chaque type de séquence dont j'avais besoin.

J'ai ensuite eu une classe de générateur de séquence qui effectuait la requête SQL nécessaire pour extraire et mettre à jour la valeur de séquence d'une séquence nommée particulière.

J'ai utilisé la classe Dialect d'Hibernate pour le faire de manière neutre.

Je voudrais aussi "mettre en cache" les séquences. Je supprime un grand nombre la valeur de séquence stockée, puis je les sépare des séquences attribuées à partir de ma classe de générateur. Si la classe était détruite (c.-à-d. Arrêt de l'application), une nouvelle instance du générateur de séquence serait lancée à la valeur stockée. (avoir un espace dans mes numéros de séquence n'avait pas d'importance)

Voici un exemple de code. Je tiens à le préciser - je ne l’ai pas fait et cela nécessite un code de printemps. Cela dit, il devrait toujours fournir les os de ce que vous voulez faire.

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;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top