Question

J'ai 2 beans entité EJB 3:

@Entity
public class Organisation
{
    @Id
    @Column(length = 64)
    private String guid;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @JoinColumn(name = "home_unit_fk", nullable = true)
    private Unit homeUnit;          
}

@Entity
public class Unit
{
    @Id
    @Column(length = 64)
    private String guid;

    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "organisation_fk", nullable = false)
    private Organisation organisation;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_unit_fk", nullable = true)
    private Unit parentUnit;

    @OneToMany(mappedBy = "parentUnit", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("shortName")
    @OptimisticLock(excluded = true)
    private Set<Unit> childUnits;   
}

Si je supprime l'organisation avec la norme Dao:

public int deleteByGuid(final String guid) 
{
    final Query query = entityManager.createQuery("delete from " + getPersistentClass().getName() + " where guid = :guid");
    query.setParameter("guid", guid);
    return query.executeUpdate();
}

Mais j'obtiens l'exception suivante:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: impossible de supprimer ou de mettre à jour une ligne parente: une contrainte de clé étrangère échoue ( config . unité , CONSTRAINT FK27D184F5D4393D CLÉ ÉTRANGÈRE ( organisation_fk ) RÉFÉRENCES organisation ( guid ))

Je ne comprends pas. Qu'est-ce que je fais mal? JPA / Hibernate ne devrait-il pas effectuer des suppressions à la fois sur l'unité et sur l'organisation au sein d'une même transaction?

Était-ce utile?

La solution

Une requête de suppression en bloc ne charge pas les objets en mémoire et contourne les cascades spécifiées dans les associations.

Je coderais votre méthode de suppression comme suit:

public int deleteByGuid(final String guid){
    Organization org = entityManager.find(Organization.class, guid);
    entityManager.remove(org);
}

Si vous utilisez une requête pour effectuer des mises à jour en masse, l'opération est déléguée directement à la base de données. Si vous souhaitez supprimer des objets enfants, vous devez définir un déclencheur DELETE CASCADE dans la base de données " base de données " niveau.

En chargeant et en supprimant l'objet, Hibernate déclenchera la cascade au niveau de "l'objet". niveau.

Plus d'informations disponibles sur: http://twasink.net/blog/2005/04/differences-in-behaviour-between-hibernate-delete-queries-and-the-old-way/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top