Hibernate probleme mit Verlinkungstabelle

der_guenn

Mitglied
Habe folgendes Problem mit Hibernate.

Kleines Beispiel um meine Problem zu verdeutlichen, ich habe drei Klassen:

Auto.java
Fahrer.java
LinkFahrerAuto.java

Die Klasse Auto erzeugt eine Datenbanktabelle mit Spalte ID_AUTO, und NAME_AUTO sowie füllt diese. Auf NAME_AUTO habe ich ein UniqueConstraint angewandt, also ein Autotyp darf nur einmal in der Tabelle geschrieben werden.
Die Klasse Fahrer mach das Selbe jedoch statt Auto alles mit Fahrer.

Die Klasse LinkFahrerAuto erzeugt eine Verlinkungstabelle, welcher Fahrer welches Auto hat(kleines Code-beispiel siehe unten)

Java:
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "ID_AUTO_FAHRER")
private int idAutoFahrer;

@OneToOne
@JoinColumn(name = "AUTO_ID")
private Auto auto  = new Auto();

@OneToOne
@JoinColumn(name = "FAHRER_ID")
private Fahrer fahrer = new Fahrer();

Probleme bekomme ich wenn ich versuche ein Auto was schon in der Datenbank vorhanden ist noch mal einzutragen. Hier greift ja mein UniqueConstraint. Was ich also mache ist eine Abfrage zu generieren die überprüft ob der Autotyp schon in der Tabelle vorhanden ist. Wenn ja dann soll der Autotyp nicht geschrieben werden.

Bsp.: in der Tabelle Auto ist "Ente" schon vorhanden. Ein zweiter Fahrer hat auch eine "Ente" also wird dieser Autotyp nicht in der Tabelle Auto abgelegt.


Mein eigentliches Problem liegt in der Verlinkungstabelle "TBL_AUTO_FAHRER". Nachdem der zweite Fahrer zwar in die Tabelle Fahrer eingetragen wurde aber sein Auto ("Ente") nicht, gibt es Probleme beim Schreiben in die Verlinkungstabelle.

Gibt es eine Möglichkeit diese elegant zu lösen?
 
LinkFahrerAuto kann nur existieren, wenn sie mit bereits bestehenden Auto bzw. Fahrer erzeugt wird. Mache also folgendes:
Java:
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "ID_AUTO_FAHRER")
private Integer idAutoFahrer;
 
@OneToOne
@JoinColumn(name = "AUTO_ID")
private Auto auto;
 
@OneToOne
@JoinColumn(name = "FAHRER_ID")
private Fahrer fahrer;

/**
  * Konstruktor, der die benötigten Member initialisiert.
  */
public LinkFahrerAuto(final Auto auto, final Fahrer fahrer) {
  this.auto = auto;
  this.fahrer = fahrer;
}

/**
  * Default Constructor für Hibernate
  */
protected LinkFahrerAuto(){
  // default constructor für Hibernate
}

Überlege auch, ob LinkFahrerAuto wirklich eine eigene Entität ist. Möglicherweise wäre hier eine ManyToMany-Beziehung besser.
 
Mein Problem war eigentlich ein anderes. Die Member habe ich nicht über den Konstruktor initializiert sondern über setter Methoden.

ich Versuch mal ein anderes Beispiel um mein Problem zu erläutern:
Teil der Klasse LinkFahrerAuto sieht wie folgt aus
Java:
@Entity
public class LinkFahrerAuto {

	@Id
	@GeneratedValue(strategy = GenerationType.TABLE)
	@Column(name = "ID_AUTO_FAHRER")
	private int idAutoFahrer;

	@ManyToOne (cascade=CascadeType.ALL)
	@JoinColumn(name = "AUTO_ID")
	private Auto auto = new Auto();

	@ManyToOne (cascade=CascadeType.ALL)
	@JoinColumn(name = "FAHRER_ID")
	private Fahrer fahrer = new Fahrer();

	public int getIdAutoFahrer() {
		return idAutoFahrer;
	}

	public void setIdAutoFahrer(int idAutoFahrer) {
		this.idAutoFahrer = idAutoFahrer;
	}

	public Auto getAuto() {
		return auto;
	}

	public void setAuto(Auto auto) {
		this.auto = auto;
	}

	public Fahrer getFahrer() {
		return fahrer;
	}

	public void setFahrer(Fahrer fahrer) {
		this.fahrer= fahrer;
	}

Die Klasse Auto sieht wie folgt aus:
Java:
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "nameAuto" }) })
public class Auto{

	@Id
	@GeneratedValue(strategy = GenerationType.TABLE)
	@Column(name = "ID_AUTO")
	private int idAuto;

	private String nameAuto;

	

	public int getIdAuto() {
		return idAuto;
	}

	public void setIdAuto(int idAuto) {
		this.idAuto = idAuto;
	}

public String getNameAuto() {
		return nameAuto;
	}

	public void setNameAuto(String nameAuto) {
		this.nameAuto = nameAuto;
	}

Die Klasse Fahrer spare ich mir jetzt, da sie der Klasse Auto ähnelt.
Wenn ich jetzt Werte eintragen lasse:
1. Zeile: Fahrer=Peter Auto = Ente
2. Zeile: Fahrer=Petra Auto = Ente
schmeißt er mit eine Exception aus, doppelter Schlüsselwert, da ja die Spalte Auto einen uniqueConstraint besitzt und zweimal Ente als Autoname nicht eingetragen werden kann.

Was ich will ist, dass die Tabelle Auto folgende Einträge hat:
ID_AUTO | NAME_AUTO
1 | Ente

die Tabelle Fahrer:
ID_FAHRER | NAME_FAHRER
1 | Peter
2 | Petra

Und die Tabelle LinkFahrerAuto
ID_AUTO_FAHRER | FAHRER_ID | AUTO_ID
1 | 1 | 1
2 | 2 | 1
 
schmeißt er mit eine Exception aus, doppelter Schlüsselwert, da ja die Spalte Auto einen uniqueConstraint besitzt und zweimal Ente als Autoname nicht eingetragen werden kann.
Das passiert aber nur, wenn du Petra und Peter zwei verschiedene Enten zuweist, also zweimal new Auto drinnen hast.
 
super, vielen Dank für den Tip, genau das war mein Problem

habe zu sehr im Datenbankshema gedacht....

ich habe es jetzt so gelöst, dass ich vorher in der Datenbank nachsehe, ob ein gleichartiges Object schon vorhanden ist, in diesen Fall den Autotyp miteinander vergleichen.

Sollte ein Object mit Autotyp Ente schon in der Datenbank vorhanden sein dann überschreibe ich das soebenen erzeugte Object welches auch Autotyp = Ente enthält durch das Object aus der Datenbank.
Das überschriebene Object gebe ich an LinkFahrerAuto weiter.

Jetzt gibt es auch keine UniqueConstraintException mehr.
 

Neue Themen


Zurück
Oben