Hallo zusammen,
ich bin ganz neu in Hibernate und bekomme seit ein paar Stunden dieselbe Fehlermeldung, die so lautet:
"Initial SessionFactory creation failed.org.hibernate.MappingException:
Foreign key (id:GERICHTHATPLUS [id])) must have same number of columns as the referenced primary key (BESTELLUNGGERICHTTABLE [bnr,gnr])"
So, also es ist mir ganz klar, dass der Mapping nicht vollständig richtig ist. Aber wo der Fehler steckt, weiß ich einfach nicht, ich habe mein Gehirn lange gequält...
Ich habe auch gegoogelt, leider ohne Erfolg. Meine letzte Chance ist dieser Forum. Also hier die Details: ich muss ein Bestellsystem für eine Pizzeria erstellen. Das Mapping ist fertig, funktioniert 90% (habe ich auch getestet), nur diese Relation die mir jetzt die Fehlermeldung gibt, kann ich einfach nicht verbessern.
Folgende Tabellen habe ich in meiner Datenbank:
-
Gerichttable (Gnr, Name, Grundpreis, Art), wobei Gnr der PRIMARY KEY ist
-
Kundetable (Knr, Name, Anschrift, Telefon), Knr - PRIMARY KEY
-
Plustable (Pnr, Name, Einzelpreis, passtzu), Pnr - PRIMARY KEY
-
Kundebestellungtable (Bnr, datum, Knr), Bnr - PRIMARY KEY (kommt von "Bestellungsnummer"), Knr ist Fremdschlüssel aus Kundetable
-
Bestellunggerichttable (Id, Bnr, Gnr, Anzahl), Id - PRIMARY KEY, Fremschlüssel sind Bnr und Gnr
-
GerichtHatPlus_table (Id, Pnr) - PRIMARY KEY ist (Id, Pnr), Fremdschlüssel sind beide
Warum diese komplizierte Struktur? Es soll 2 Arten von Gerichten geben, Pizzas und Salate. Pizzas können (zusätzlich zu den Standardzutaten) noch Extras haben (Extra Käse, Extra Oliven usw.), Salate können Dressings haben (Senfdressing, Essigöldressing usw.). Also ein Kunde kann bei eine Pizza Extras hinzufügen, aber keine Dressings (analog für Salate).
Anmerkungen (ganz wichtig):
-
GerichtHatPlus_table ist ein join table zwischen Plustable und Bestellunggerichttable.
- Zwischen
Kundebestellungtable und
Gerichttable gibt es eine M:N Relation, welche ich mit einer extra Tabelle gelöst habe :
Bestellunggerichttable, die noch 2 zusätzliche Spalten hat (deswegen vielleicht auch alle meine Probleme, das weiß ich nicht wie man es in dem Mapping modelliert) - Id und Anzahl, wo Id der PRIMARY KEY ist; Bnr und Gnr sind hier Fremdschlüssel aus den anderen beiden Tabellen.
Zurück zu meinem Problem: ich gebe hier die Mappings und Teile der Java-Klassen für die folgenden Tabellen (weil sonst alles perfekt läuft, alle andere Mappings habe ich richtig gemacht): Plustable -
plus.hbm.xml und Bestellunggerichttable -
bestellunggericht.hbm.xml:
plus.hbm.xmlCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Plus" table="PLUSTABLE">
<id name="pnr" type="big_decimal">
<column name="PNR"/>
<generator class="identity"/>
</id>
<property name="name" type="string">
<column length="80" name="name"/>
</property>
<property name="einzelpreis" type="big_decimal">
<column length="20" name="einzelpreis" not-null="true"/>
</property>
<property name="passtzu" type="string">
<column length="10" name="passtzu" not-null="true"/>
</property>
<set name="bestellunggerichten" table="GERICHTHATPLUS">
<key column="pnr"/>
<many-to-many class="entity.Bestellunggericht" column="id"/>
</set>
</class>
</hibernate-mapping>
Plus.javaCode:
@Entity
@Table(name = "PLUSTABLE")
@NamedQueries({@NamedQuery(name = "Plus.findAll", query = "SELECT p FROM Plus p"), @NamedQuery(name = "Plus.findByPnr", query = "SELECT p FROM Plus p WHERE p.pnr = :pnr"), @NamedQuery(name = "Plus.findByName", query = "SELECT p FROM Plus p WHERE p.name = :name"), @NamedQuery(name = "Plus.findByEinzelpreis", query = "SELECT p FROM Plus p WHERE p.einzelpreis = :einzelpreis"), @NamedQuery(name = "Plus.findByPasstzu", query = "SELECT p FROM Plus p WHERE p.passtzu = :passtzu")})
public class Plus implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "PNR")
private BigDecimal pnr;
@Column(name = "NAME")
private String name;
@Column(name = "EINZELPREIS")
private BigDecimal einzelpreis;
@Column(name = "PASSTZU")
private String passtzu;
@ManyToMany(mappedBy = "plusCollection")
private Set<Bestellunggericht> bestellunggerichten;
...und alle get() und set() Methoden
bestellunggericht.hbm.xmlCode:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.Bestellunggericht" table="BESTELLUNGGERICHTTABLE">
<id name="id" type="integer">
<column name="id"/>
<generator class="identity"/>
</id>
<property name="anzahl" type="integer">
<column name="anzahl" not-null="true"/>
</property>
<set name="plusen" table="GERICHTHATPLUS">
<key column="id"/>
<many-to-many class="entity.Plus" column="pnr"/>
</set>
</class>
</hibernate-mapping>
Bestellunggericht.javaCode:
@Entity
@Table(name = "BESTELLUNGGERICHTTABLE")
@NamedQueries({@NamedQuery(name = "Bestellunggericht.findAll", query = "SELECT b FROM Bestellunggericht b"), @NamedQuery(name = "Bestellunggericht.findById", query = "SELECT b FROM Bestellunggericht b WHERE b.id = :id"), @NamedQuery(name = "Bestellunggericht.findByAnzahl", query = "SELECT b FROM Bestellunggericht b WHERE b.anzahl = :anzahl")})
public class Bestellunggericht implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "ID")
private BigDecimal id;
@Basic(optional = false)
@Column(name = "ANZAHL")
private BigInteger anzahl;
@JoinTable(name = "GERICHTHATPLUS", joinColumns = {@JoinColumn(name = "ID", referencedColumnName = "ID")}, inverseJoinColumns = {@JoinColumn(name = "PNR", referencedColumnName = "PNR")})
@ManyToMany
private Set<Plus> plusen;
@JoinColumn(name = "GNR", referencedColumnName = "GNR")
@ManyToOne
private Gericht gnr;
@JoinColumn(name = "BNR", referencedColumnName = "BNR")
@ManyToOne
private Kundebestellung bnr;
Nicht zu vergessen, die Entitäten habe ich automatisch generiert mit Hilfe von Hibernate JPA und dann, wo nötig, selber ein bisschen geändert.
Könnte mich bitte jemand helfen, diese Fehlermeldung loszuwerden?
Danke!