2009-04-30 6 views
1

Ich habe 2 EJB 3 Entity Beans:JPA Löschen mit 2 Interlocking Entitätsklassen

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

Wenn ich über die Organisation unter Verwendung von Standard Dao löschen tun:

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(); 
} 

Aber ich die folgende Ausnahme erhalten :

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Kann nicht löschen oder eine übergeordnete Zeile aktualisieren: a. Fremdschlüssel fehlschlägt (configunit, CONSTRAINT FK27D184F5D4393D FOREIGN KEY (organisation_fk) LITERATUR organisation (guid))

Ich verstehe es nicht. Was mache ich falsch? Sollte JPA/Hibernate innerhalb derselben Transaktion nicht sowohl die Einheit als auch die Organisation löschen?

Antwort

2

Eine Massenlöschabfrage lädt keine Objekte in den Speicher und umgeht alle Kaskaden, die für Zuordnungen angegeben sind.

Ich würde codiert Ihre Löschmethode als:

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

Wenn Sie eine Abfrage verwenden Bulk-Updates zu tun, die Operation direkt in die Datenbank übertragen wird. Wenn Sie untergeordnete Objekte löschen möchten, müssen Sie auf der Ebene "Datenbank" einen DELETE CASCADE-Trigger setzen.

Wenn Sie das Objekt laden und entfernen, löst Hibernate die Kaskade auf der Ebene "Objekt" aus.

Weitere lieferbare Infos unter: http://twasink.net/blog/2005/04/differences-in-behaviour-between-hibernate-delete-queries-and-the-old-way/

+0

ok, die absolut Sinn macht ... aber ... ich habe es versucht, und ich erhalte die folgende Ausnahme: Verursacht durch: javax.persistence.PersistenceException: org.hibernate .PropertyValueException: nicht-null-Eigenschaft verweist auf eine null oder transienten Wert: Unit.organisation \t bei org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException (AbstractEntityManagerImpl.java:614) \t bei org.hibernate.ejb.AbstractEntityManagerImpl.remove (AbstractEntityManagerImpl .java: 259) Irgendwelche Ideen? Prost. – TiGz