Domanda

Ho 2 bean di entità 3 EJB:

@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;   
}

Se faccio una cancellazione sull'organizzazione usando lo standard 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();
}

Ma ottengo la seguente eccezione:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: impossibile eliminare o aggiornare una riga principale: un vincolo di chiave esterna non riesce ( config . unità , CONSTRAINT FK27D184F5D4393D CHIAVE ESTERA ( organisation_fk ) RIFERIMENTI organizzazione ( guid ))

Non capisco. Che cosa sto facendo di sbagliato? JPA / Hibernate non dovrebbero eseguire cancellazioni sia sull'unità che sull'organizzazione all'interno della stessa transazione?

È stato utile?

Soluzione

Una query di eliminazione in blocco non carica gli oggetti in memoria e ignora qualsiasi cascata specificata nelle associazioni.

Vorrei codificare il metodo di eliminazione come:

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

Se si utilizza una query per eseguire aggiornamenti in blocco, l'operazione viene delegata direttamente al database. Se desideri eliminare oggetti figlio, devi impostare un trigger DELETE CASCADE sul "database" " livello.

Caricando l'oggetto e rimuovendolo, Hibernate attiverà la cascata sull'oggetto " oggetto " livello.

Maggiori informazioni disponibili su: http://twasink.net/blog/2005/04/differences-in-behaviour-b Between-hibernate-delete-queries-and-the-old-way/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top