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 :

nullify on delete?


Sujet :

Hibernate Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut nullify on delete?
    Bonjour,

    J'ai un petit cas d'école qui me donne des cheveux blancs, peux-être que vous saurez comment m'aider. Voici le contexte :
    J'ai trois entités : User, Game et Player: User <--->> Player <<--> Game
    Particularité : Game possède un lien to-one vers player indiquant le joueur courant.

    Supposons une partie et un utilisateur créés. On crée un joueur liant les deux, qu'on affecte comme joueur courant.

    Problématique : Je souhaite maintenant supprimer cet utilisateur, et le joueur associé en cascade, mais garder la partie intacte. Et donc, il faudrait que le joueur courant soit remis à null dans ma partie. J'aimerai que tout ceci soit définit juste via la configuration Hibernate. Possible? Jusqu'ici, je n'y arrive pas...

    Voici mes fichiers 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
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    <hibernate-mapping default-lazy="true">
        <class name="be.asterius.model.Game" table="&quot;Game&quot;">
            <cache usage="read-write" />
            <id name="id" column="&quot;id&quot;" type="java.lang.Long">
                <generator class="sequence">
                    <param name="sequence">game_id_sequence</param>
                </generator>
            </id>
            <many-to-one name="currentPlayer" class="be.asterius.model.Player" lazy="proxy" cascade="none">
                <column name="&quot;currentPlayerId&quot;" />
            </many-to-one>
            <set name="players" cascade="delete" lazy="true" inverse="true">
                <key column="&quot;gameId&quot;" />
                <one-to-many class="be.asterius.model.Player" />
            </set>
        </class>
    </hibernate-mapping>
     
    <hibernate-mapping default-lazy="true">
        <class name="be.asterius.model.User" table="&quot;UserAccount&quot;">
            <cache usage="read-write" />
            <id name="id" column="&quot;id&quot;" type="java.lang.Long">
                <generator class="sequence">
                    <param name="sequence">useraccount_id_sequence</param>
                </generator>
            </id>
            <set name="players" cascade="delete" lazy="true" inverse="true">
                <key column="&quot;userId&quot;" />
                <one-to-many class="be.asterius.model.Player" />
            </set>
        </class>
    </hibernate-mapping>
     
    <hibernate-mapping default-lazy="true">
        <class name="be.asterius.model.Player" table="&quot;Player&quot;">
            <cache usage="read-write" />
            <id name="id" column="&quot;id&quot;" type="java.lang.Long">
                <generator class="sequence">
                    <param name="sequence">player_id_sequence</param>
                </generator>
            </id>
            <many-to-one name="user" class="be.asterius.model.User" lazy="proxy" cascade="none">
                <column name="&quot;userId&quot;" />
            </many-to-one>
            <many-to-one name="game" class="be.asterius.model.Game" lazy="proxy" cascade="none">
                <column name="&quot;gameId&quot;" />
            </many-to-one>
        </class>
    </hibernate-mapping>
    Voici un exemple de code a exécuter

    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
     
    Game game = new Game();
    getHibernateTemplate().save(game);
     
    User user = new User();
    getHibernateTemplate().save(user);
     
    Player player = new Player();
    player.setGame(game);
    player.setUser(user);
    getHibernateTemplate().save(player);
     
    game.getPlayers().add(player);
    game.setCurrentPlayer(player);
    getHibernateTemplate().merge(game);
     
    getHibernateTemplate().delete(user);
    Et voici le genre d'erreur que j'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    6552 [main] ERROR org.hibernate.util.JDBCExceptionReporter - L'élément du batch 0 /* delete be.asterius.model.Player */ delete from "Player" where "id"=1 a été annulé. Appeler getNextException pour en connaître la cause.
    6552 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23503
    6552 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: update or delete on table "Player" violates foreign key constraint "fk21c01226a19d1e" on table "Game"
      Détail : Key (id)=(1) is still referenced from table "Game".
    Cette erreur est assez claire, c'est la contrainte d'intégrité qui lève l'exception parce que la partie référence current player.
    Ma question donc : comment faire en sorte que Hibernate mette cette valeur à null automatiquement?

    Merci d'avance pour vos réponses,

    Asterius

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    Mon cas d'école serait-il si complexe que personne n'ait une piste à me proposer?
    A votre bon coeur m'sieur dame, si j'arrive à comprendre ceci, j'aurais fait un grand pas en avant dans ma compréhension d'Hibernate

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    Toujours pas de réponse?

    Merci de me rediriger si je me suis trompé de forum?

  4. #4
    Expert confirmé
    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
    Points : 4 141
    Points
    4 141
    Par défaut
    Pourquoi ne pas faire un player.setUser(null) puis un merge ou update pour enlever le lien et ainsi pouvoir faire ton delete ?

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 109
    Points : 57
    Points
    57
    Par défaut
    Merci pour ton retours.

    C'est effectivement la solution que j'utilise maintenant, mais je trouve ça fort lourd. Surtout que le cas présenté ici est fort simple, mais si la table concernée se trouve à plusieurs joins, cela demande de nombreuses requêtes (ou de nombreux joins) pour aller mettre un liens à null à la main. Ce n'est pas très efficace.

    Par ailleurs, c'est une opération qu'il est facile de faire en sql natif avec un nullify on cascade. Je trouve ça fort étonnant que le fait d'utiliser Hibernate impose de passer par plusieurs requêtes. Hibernate est plutôt sensé nous simplifier la vie, c'est ce qui me fait sérieusement penser qu'il doit exister une solution...

Discussions similaires

  1. Delete on cascade avec SQL server
    Par fadoua dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 14/01/2004, 11h02
  2. delete en cascade
    Par bruno270579 dans le forum Requêtes
    Réponses: 8
    Dernier message: 16/12/2003, 17h17
  3. fonction postgresql qui delete un enr
    Par access dans le forum Requêtes
    Réponses: 1
    Dernier message: 16/11/2003, 14h44
  4. [requête] DELETE + SELECT
    Par doohan dans le forum Requêtes
    Réponses: 6
    Dernier message: 07/07/2003, 12h27
  5. [langage] delete de fichier
    Par lolive dans le forum Langage
    Réponses: 2
    Dernier message: 24/04/2003, 15h04

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