2012-03-23 6 views
2

Je suis confronté à un problème lors de la suppression d'un enregistrement référencé par une autre table.JPA cascade remove

Ceci est un exemple de code (scénario le plus simple):

@Entity 
@Table(name = "user") 
public class User 
{ 
    @Id 
    @GeneratedValue(generator="user_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") 
    private Set<UserLog> userLogSet; 

    // Other attributes 
    // Getters/setters 
} 

@Entity 
@Table(name = "user_log") 
public class UserLog 
{ 
    @Id 
    @GeneratedValue(generator="user_log_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_log_id_seq", sequenceName="user_log_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "user_id", nullable = false) 
    private User user; 

    // Other attributes 
    // Getters/setters 
} 

Chaque fois que je tente de supprimer un enregistrement de la table "utilisateur", je reçois l'erreur suivante de postgreSQL:

ERROR: update or delete on table "user" violates foreign key constraint "fk228a019fd2495d20" on table "user_log"
Detail: Key (id)=(5) is still referenced from table "user_log".

Qu'est-ce que je fais mal?

Merci! J'ai essayé de coder un petit exemple, il peut être trouvé here. Après avoir lancé l'application avec Tomcat, le schéma de base de données est automatiquement créé (vérifiez les détails de connexion dans /src/main/webapp/WEB-INF/jdbc.properties). Lorsque vous visitez http://localhost:8080 certaines données sont insérées dans la base de données. Si j'essaye de supprimer n'importe quel teacher qui est référencé dans la table student (using phpPgAdmin), j'obtiens une erreur semblable à celle ci-dessus.

Répondre

1

Votre correspondance semble être erronée.

L'utilisateur peut avoir beaucoup de UserLogs.

Egalement @OneToMany doit être sur une collection, par ex. java.util.Set. La cascade que vous avez placée est dans UserLog qui aura lieu si vous agissez sur l'instance de UserLog et non User. Dans la mesure où je comprends le changement de mappage comme suit. Je suppose que vous voulez supprimer utilisateur et tout son UserLog simplement en supprimant User et en laissant UserLogs n'a pas de sens.

Espérons que cela aide.

Mise à jour:

Cascades as annotated in entity classes are managed by ORM, not if you externally try to delete them from external tools like phpPgAdmin.

+0

Merci, @ gbagga - voir mon commentaire dans madth3 question, je viens de me confus en postant l'exemple ici. Maintenant, le fait est que je n'ai pas besoin de 'Set' dans la classe' User', est-ce obligatoire? Y at-il de toute façon pour éviter de l'avoir? – satoshi

+0

@satoshi n'est pas obligatoire pour utiliser Set, son fondamentalement utilisé pour que les objets dupliqués ne finissent pas dans la collection avec des objets. Dans le cas où vous êtes intéressé par look @ hibernate [docs] (http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/collections.html) –

+0

Merci, @gbagga. Malheureusement, je suis confronté au même problème, même avec votre solution. JPA/Hibernate devrait-il créer des index dans PostgreSQL? Ou toutes les actions en cascade sont-elles gérées par l'ORM? Je vous remercie. – satoshi

0

Votre mappage est incorrect, le OneToMany doit être dans User appliqué à une collection de UserLog. Voir examples.

+0

Désolé, vous avez raison. Dans le code sur lequel je travaille, j'utilise 'ManyToOne', je suis juste confus en publiant un exemple ici. (édité la question originale) – satoshi