Hibernate OneToMany und ManyToOne Objekte löschen

goodcat

Aktives Mitglied
Hi,

ich habe folgendes Problem.

Ich habe eine Tabelle Customer und eine Tabelle ContactPerson. Ein Kunde kann mehrere Ansprechpartner haben, aber ein Ansprechpartner kann nur einen Kunden haben. Löschen möchte ich aus beiden Richtungen, d.h. wenn ich den Kunden lösche sollen natürlich alle Ansprechpartner gelöscht werden. Wenn ich allerdings ein Ansprechpartner lösche soll nicht der Kunde gelöscht werden!

Das löschen des Kunden inkl. aller Ansprechpartner funktioniert wie gewollt. Jetzt habe ich ein Problem wenn ich ein Ansprechpartner lösche. Da in der Ansprechpartner Tabelle eine Referenz auf den Kunden existiert (wenn ich ein Ansprechpartner hole möchte ich auch wissen zu welchem Kunden dieser gehört) kann ich in der Tabelle ContactPerson kein Cascade nutzen um den Eintrag in der Tabelle die die beiden Tabellen verknüpft zu löschen da sonst der Kunde mitgelöscht wird.

Also die Frage wie lösche ich einen Ansprechpartner ohne den Kunden zu löschen? Allerdings möchte ich von dem Ansprechpartner auf den Kunden zugreifen und anders rum. Von dem Kunden auf den Ansprechpartner funktioniert noch nicht aber ich glaube das hat was mit dem Eager und Lazy Loading zu tun (versuche mich gerade mit Hibernate vertraut zu machen.. bin also recht unerfahren ???:L)

Oder sind die gesamten Verknüpfungen falsch?

Hier der Code:
Java:
@Entity
public class Customer {
	
	private int id;
	private int customerID;
	private String title;
	private String company;
	private String firstname;
	private String lastname;
	private Collection<ContactPerson> contactPerson = new ArrayList<ContactPerson>();
	
		
	public Customer() {
	}
	
	
	@Id	@GeneratedValue
	public int getID() {
		return id;
	}
	public void setID(int id) {
		this.id = id;
	}
	
	public int getCustomerID() {
		return customerID;
	}
	public void setCustomerID(int customerID) {
		this.customerID = customerID;
	}
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	
	public String getFirstName() {
		return firstname;
	}
	public void setFirstName(String firstname) {
		this.firstname = firstname;
	}
	
	public String getLastName() {
		return lastname;
	}
	public void setLastName(String lastname) {
		this.lastname = lastname;
	}	
	

	@OneToMany( cascade = CascadeType.ALL )
	@JoinTable( name = "tbl_customer_contactPerson", joinColumns = @JoinColumn( name = "customer_id"), inverseJoinColumns = @JoinColumn( name = "contactperson_id") )
	public Collection<ContactPerson> getContactPerson() {
		return contactPerson;
	}
	public void setContactPerson(Collection<ContactPerson> contactPerson) {
		this.contactPerson = contactPerson;
	}

	
}

Java:
@Entity
public class ContactPerson {

	private int id;
	private Customer customer;
	private String title;
	private String firstname;
	private String lastname;
	

	public ContactPerson() {
		
	}

		
	@Id	@GeneratedValue	
	public int getID() {
		return id;
	}
	public void setID(int sqlID) {
		this.id = sqlID;
	}

	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	
	@ManyToOne
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}	
	
	public String getFirstName() {
		return firstname;
	}
	public void setFirstName(String firstname) {
		this.firstname = firstname;
	}
	
	public String getLastName() {
		return lastname;
	}
	public void setLastName(String lastname) {
		this.lastname = lastname;
	}



}
 
Habe es hinbekommen...

Zeile 61 in der Customer.java:
Code:
@OneToMany( cascade = CascadeType.ALL, [B]orphanRemoval=true[/B] )

Das
Code:
orphanRemoval=true
einfügen und fertig.

Nochmal ne blöde Frage hinterher. Kann ich anstelle von Collections auch einen Vector benutzen?
Code:
private List<ContactPerson> contactPerson = new ArrayList<ContactPerson>();
 
Zuletzt bearbeitet:
mh ich habe die Frage etwas ungenau gestellt.

anstatt ArrayList einen Vector benutzen:
Code:
private List<ContactPerson> contactPerson = new ArrayList<ContactPerson>();

also so:
Code:
private List<ContactPerson> contactPerson = new Vector<ContactPerson>();


Sollte kein Thema sein, oder?
Wenn ich nämlich die Daten in einem Vector habe kann ich Daten daraus ziemlich leicht in eine JComboBox übertragen bzw. in ein ComboBox model...
 
Ja, sollte kein Problem sein, da beide Klassen List implementieren. Und Hibernate wird an der Stelle wohl hoffentlich auch gegen das Interface programmiert haben. 🙂
 
Ja, sollte kein Problem sein, da beide Klassen List implementieren. Und Hibernate wird an der Stelle wohl hoffentlich auch gegen das Interface programmiert haben. 🙂
Das ist wohl geraten und leider falsch..

Chapter*6.*Collection mapping

Ansosnten sehe ich keinen vernünftigen grund warum jemand Vector anstatt List nehmen sollte... Swing zwingt einen zu Vektor, aber ansonsten ist Vector einfach nur daneben weil veraltet... aber da der TS eben für Swing einen Vector will, muss man ihm halt ein "nein" Antwroten.
 
d.h. ich muss mir die arbeit machen das von einer List in einen Vector zu übertragen um z.B. die Daten in ein defaultComboBoxModel zu bekommen.. bzw. die list durch iterieren und die Daten direkt in ein Model übertragen.. der aufwand hält sich aber stark in grenzen 😀? Wenn Ihr mir jetzt sagt das eine List performanter ist dann bin ich mehr als zufrieden...

Achso was mir einfällt.. Ich habe gesehen das die Annotationen also @Id, @GeneratedValue etc. nicht in den klassen gemacht wurde sondern in separaten XML Dateien.. Gibt es da ne Empfehlung? Klasse oder XML?
 
Zuletzt bearbeitet:
Wenn Ihr mir jetzt sagt das eine List performanter ist dann bin ich mehr als zufrieden...
Das ist sie, kann dir aber egal sein 😉

Swing wurde leider nie "fertig" was die Anpassung an Java 1.4 und das damals neue Collections Framework betrifft...

Achso was mir einfällt.. Ich habe gesehen das die Annotationen also @Id, @GeneratedValue etc. nicht in den klassen gemacht wurde sondern in separaten XML Dateien.. Gibt es da ne Empfehlung? Klasse oder XML?
Beides hat Vor- und Nachteile, sind aber für dich wohl eher nicht so relevant 😉

Mit XML Dateien könntest du deine Domainklassen frei von JPA & Hibernatecode/imports halten.
 
Werde mal darüber nachdenken das zu trennen, bin eigentlich ein Freund davon sowas sauber zu trennen ... Aber ein großer Vorteil an den Annotationen in den Klassen (für mich zumindest) war das wenn ich Klassen verändere sofort sehe ob das Feld z.B. ein @Lob o.ä. ist bzw. wie die Felder verknüpft sind... Aber mal schauen.

Vielen Dank!
 
Noch etwas Grundsätzlich zu cascade etc:
Hibernate/JPA/ORM managen nicht deine Objektbeziehungen für dich, musst du schon selber machen.
Ich weiss, mit Cascade wird vieles einfacher, aber auch gefährlicher.

Ansonsten zu Bidirektionalen Beziehungen.
Sind nicht ganz unproblematisch, meist ist es eine Alternative in einem DAO/Repository eine Suchmethode zu haben.
 
Apropo Suchmethode... wie kann ich denn eigentlich aus einer Tabelle alle Einträge fetchen?

Zum Beispiel der Fall Customer -> Country. Zwischen Customer und Country gibt es eine @OneToOne Beziehung.
Ein Customer muss ein Land haben... Um alle Länder in ein JComboBox Model zu packen brauche ich am besten eine Liste... Benutze ich dann eine for Schleife oder gibt es noch andere Methode um an alle Daten zu kommen?

Hast Du eventuell noch ein paar Links bzgl. Hibernate für beginner?
 
Zuletzt bearbeitet:
Ahh Ok habe es herausgefunden...

Java:
Query query = session.getNamedQuery("Country.all");			
			List<Country> country = (List<Country>) query.list();
			
			for ( Country c : country ) {				
				System.out.println(c.getEn());
			}
 

Zurück
Oben