IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Clefs primaires assignées par trigger


Sujet :

Hibernate Java

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut Clefs primaires assignées par trigger
    Bonjour a tous,

    j'essaie de mettre en place un id auto incrémenté dans Oracle.
    Pour cela j'ai créé une séquence:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE SEQUENCE ma_sequence INCREMENT BY 1;
    et un trigger qui s'exécute avant l'insert:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    create trigger t_matable_pk
    before insert on matable for each row
    begin
       select concat('4', ma_sequence.nextval) into :new.id from dual;
    end;
    j'utilise concat dans mon trigger car j'ai besoin d'identifier ma clé par un identifiant '4'.

    Comment puis-je mapper ceci avec hibernate?
    Utiliser le generator sequence ne résout pas mon problème car seul la valeur de la séquence est renvoyée...

    En lisant la doc je suis tombé sur ceci:
    Pour les schémas de base hérités d'anciens systèmes uniquement (Hibernate ne génère pas de DDL avec des
    triggers)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <id name="id" type="long" column="person_id">
    <generator class="select">
    <param name="key">socialSecurityNumber</param>
    </generator>
    </id>
    Dans l'exemple ci-dessus, socialSecurityNumber a une valeur unique définie par la classe en tant que clef
    naturelle et person_id est une clef secondaire dont la valeur est générée par trigger.
    mais impossible de le faire fonctionner car je ne comprend pas à quoi sert
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <param name="key">socialSecurityNumber</param>

    Quelqu'un pourrait il m'aider à le mettre en place?

    Merci d'avance pour votre aide

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut
    voici ce que j'ai trouvé sur le forum d'hibernate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Mapping documents:
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
    <class name="gov.tresc.admsist.model.Usuario" table="USUARIO"
    schema="ADMSIST">
    <id name="id" column="IDO_USUARIO" type="long" >
    <generator class="select">
    <param name="key">login</param>
    </generator>
    </id>
    <property name="nome" column="NOME_USUARIO" type="string" length="70"
    not-null="true"/>
    <property name="login" column="LOGIN" type="string" length="70"
    not-null="true"/>
    <property name="email" column="E_MAIL" type="string" length="70"
    not-null="true"/>
    </class>
    </hibernate-mapping>
    Pourquoi devoir utiliser un deuxieme champ unique au sein de ma table alors que l'ID est suffisant pour rendre unique un record???
    Que faire si jamais on n'a pas d'autre champ unique que l'ID dans une table???

    Pouvez-vous m'aider?

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    Pourquoi ne pas utiliser le generator "assigned ".
    Tu récupères la valeur de ta séquence par une requête, tu concatènes le résultat avec ton "4" et ensuite tu assignes le tout à ton id.
    Qu'en penses-tu ?

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut
    Merci pour ta réponse.
    En fait c'est la méthode que nous utilisions précédemment. C'est nous même, dans notre application, qui générions nos ID en ajoutant 1 au un select max(i) concaténé avec le label '4'.
    Le seul problème c'est qu'on a eu plusieurs accès concurrentielles sur nos tables (voir le thread de vny)

    En résumé, 2 personnes ont voulu inséré en même temps des données dans une table. Chacun a reçu le même select max(id) -> le premier a bien été inséré et le second s'est fait jeter car heureusement un doublon a été détecté.

    Le fait d'ajouter une trigger+sequence garanti à l'application de toujours avoir un id unique avant l'insert(cf. le commentaire de vlord dans le thread ci-dessus).

    Mais je suis actuellement incapable de récupérer la valeur de mon trigger avec hibernate

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    Je comprends, mais là je te propose d'utiliser ta séquence au lieu d'un max(id).
    Il n'y aura plus de doublons dans ce cas la.
    Et puis à mon avis, tu peux te passer du trigger.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut
    ah ok, je viens de comprendre

    Je test de suite et je fais un feedback

    Merci Fr1man

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut
    Citation Envoyé par fr1man
    Pourquoi ne pas utiliser le generator "assigned ".
    Tu récupères la valeur de ta séquence par une requête, tu concatènes le résultat avec ton "4" et ensuite tu assignes le tout à ton id.
    Qu'en penses-tu ?
    juste une question? comment faire pour récupérer le nextval de ma séquence?
    car un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String sqlString = "select concat('4',MA_SEQ.NEXTVAL) from dual";
    Query query = HibernateUtil.getCurrentSession().createQuery(sqlString);
    list = query.list();
    me renvoi l'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    org.hibernate.hql.ast.QuerySyntaxException: dual is not mapped [select MA_SEQ.nextval from dual]
    et mon fichier de mapping:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <hibernate-mapping>
     
    	<class 
    		name="Table" 
    		table="T_TABLE"
    		dynamic-update="false" 
    		dynamic-insert="false" 
    		lazy="false">
     
    		<id name="id" column="RIN_ID" type="long" />
    	</class>
    </hibernate-mapping>

    Merci

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Par défaut
    Essaie avec createSQLQuery, car tu lui envoies du SQL.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Août 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 11
    Par défaut Ca fonctionne
    Pour résumer la petite histoire:
    Comment résoudre un problème d'accès concurrentiel sur Oracle.
    1. Créer une séquence qui correspondra a votre ID
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      CREATE SEQUENCE MA_SEQ INCREMENT BY 1;
    2. Dans le fichier mapping d'hibernate, definissez votre clé primaire en assigned
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      <id name="id" column="RIN_ID" type="long" />
    3. Avant de faire un save, générer votre id de la manière suivante:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      String sqlString = "select MA_SEQ.nextval from dual";
      SQLQuery sqlQuery = Session.createSQLQuery(sqlString);
      BigDecimal id = (BigDecimal) sqlQuery.uniqueResult();
      long retour = id.longValue();
      return retour;
      et si comme moi vous devez concaténer un label à votre séquence, voici le code:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      String sqlString = "select concat('LABEL-',MA_SEQ.nextval) from dual";
      SQLQuery sqlQuery = HibernateUtil.getCurrentSession().createSQLQuery(sqlString);
      String id = (String) sqlQuery.uniqueResult();
      long retour = Long.parseLong(id);
      return retour;


    Grâce a ceci, 2 personnes qui réalisent une insertion en simultané n'auront plus en retour 2 fois le même ID

    Je tiens a remercier fr1man pour son aide précieuse.

    a+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Commencer une Clef Primaire par une valeur specifique
    Par Bonero dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 22/08/2011, 12h23
  2. Réponses: 3
    Dernier message: 22/08/2010, 17h40
  3. Comment comment définir une clef primaire dans une table??
    Par nek_kro_kvlt dans le forum Bases de données
    Réponses: 4
    Dernier message: 07/02/2005, 21h06
  4. [VB.NET] [ADO.NET] Clef primaire auto incrémenté
    Par Guld dans le forum Accès aux données
    Réponses: 4
    Dernier message: 25/09/2004, 20h46
  5. récupérer la clef primaire d'une table
    Par orionis69 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 28/02/2004, 13h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo