2016-06-22 8 views
0

ich eine Entität löschen möchten, die eine @OneToMany Beziehung mit einem anderen hat, wie diese ein:Wie Beziehung zu aktualisieren, bevor Einheit Löschen

public class Dealership implements Serializable { 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "dealership", orphanRemoval = true) 
    private Set<Car> cars; 
} 

public class Car implements Serializable { 

    @ManyToOne 
    @JoinColumn(name="co_id") 
    private Dealership dealership; 

} 

Die Sache ist die, dass, wenn ich die Händler löschen, ich möchte nur die Autos löschen, die nicht verkauft wurden. Und egal, was ich versuche, löscht Hibernate ALLE Autos, die mit dem Autohaus verbunden sind, durch die Kaskade. Hier ist, was ich versucht habe. In diesem Beispiel versuche ich, die verkauften Autos zu einem anderen Händler zu übertragen, und dann lösche ich den Händler. Dies soll die Händler löschen, seine Mitarbeiter, und nur die Autos, die nicht verkauft wurden:

Session session = SessionManager.getSession(); 
Transaction tx = session.beginTransaction(); 

Dealership dealershipToDelete = (Dealership) session.load(Dealership.class, idDealership); 

for(Car c: dealershipToDelete.getCars().stream().filter(c -> c.isSold()).toArray(Car[]::new)){ 
    Dealership newDealership = (Dealership) session.load(Dealership.class, idNewDealership); 
    c.setDealership(newDealership); 
    dealershipToDelete.getCars().remove(c); 
} 

session.update(dealershipToDelete); 

session.flush(); 

session.delete(dealershipToDelete); 

tx.commit(); 

session.close(); 

Aber es löscht immer alle Autos. Auch wenn es mir gelingt Hibernate die Autos mit dem neuen Autohaus zu aktualisieren. Es aktualisiert sie und löscht sie dann. Hilfe würde sehr geschätzt werden. Vielen Dank.

+0

Sie fügen die Autos dem neuen Autohändler nicht hinzu. Sie entfernen die Autos nicht von ihrem alten Händler. –

+0

Entschuldigung, ich habe vergessen, die Zeile hinzuzufügen, die das Auto aus dem alten Autohaus entfernt hat. Ich habe es bereits getestet, bevor ich das gepostet habe. Es funktioniert immer noch nicht. Jetzt habe ich es nicht zu der neuen Beziehung hinzugefügt. Aber jetzt, da ich diese Linie auf der Schleife hinzugefügt (am Ende davon): 'newDealership.getCars() in (c);' Es wirft diese Ausnahme:. Exception in thread "main" org. hibernate.ObjectDeletedException: Gelöschtes Objekt wird erneut durch Kaskadenspeicherung gespeichert (entferntes Objekt aus Assoziationen entfernen): [hibernate.entities.Car # 14] – MatiasP

+0

@MatiasMGS ist Ihr Problem gelöst? –

Antwort

1

Nur refresh() dem Dealership Objekt, bevor es zu reflektieren, die Änderungen an seine Beziehung mit dem Auto class.Have leicht modifizierten Code zu löschen, versuchen Sie dies:

Dealership dealershipToDelete = (Dealership) session.load(Dealership.class, idDealership); 
Dealership newDealership = (Dealership) session.load(Dealership.class, idNewDealership); 
for(Car c: dealershipToDelete.getCars().stream().filter(c -> c.isSold()).toArray(Car[]::new)){ 
    c.setDealership(newDealership); 
    newDealership.getCars().add(c); 
} 
session.flush(); //this will flush the updates to sold Car, with the new Dealership details 
session.refresh(dealershipToDelete); //this will load the updated "dealershipToDelete" without the 'Sold Car' object,the 'Unsold' ones will still be there 
session.delete(dealershipToDelete); //this will delete the Dealership and its related unsold car objects. 

tx.commit(); 

session.close(); 
1

Sie könnte etwa so versuchen:

zuerst die Fremdschlüssel NULL-Werte zulassen:

public class Car implements Serializable { 

    @ManyToOne 
    @JoinColumn(name="co_id" , nullable = true) 
    private Dealership dealership; 

} 

dann erhalten Sie die Id von dealershipToRemove:

int id = dealershipToRemove.getId(); 

dann löschen Sie alle Autos die als Händler mit der angegebenen ID

query = session.createNativeQuery("delete from cars where co_id = :id and date is null"); 
query.setParameter(1,id); 
query.executeUpdate(); 
haben

Sie die Beziehung zwischen dealershipToRemove und seinen Autos dann brechen:

dealershipToRemove .setCars(null); 
session.remove(dealershipToRemove); 
+0

Würde das nicht alle Autos entfernen? So hätte 'session.remove (dealershipToRemove)' genau den gleichen Effekt wie all das. Hinzufügen von '" und Datum ist Null "' zu der Abfrage würde es beheben, aber ich suchte mehr nach einer Lösung mit Hibernate anstelle von Abfragen, wie SB Antwort. – MatiasP

+0

ja dein Recht! (y) –

Verwandte Themen