Hibernate speichert NUR Basisklasse!

  • Themenstarter Themenstarter Konstantin Denerz
  • Beginndatum Beginndatum
K

Konstantin Denerz

Hallo,

Ich habe ein O/R Mapping(Hibernate) für ein System geschrieben und bin dabei auf ein Problem gestossen.

Kurze Beschreibung:
- Ich habe ein Basisklasse Klasse1 und eine die von dieser erbt Klasse2.
- Dann hat meine Klasse1 ein Attribut vom Typ Klasse3.
- Es gibt noch eine Klasse 4, die von der Klasse 3 Erbt
- Jede Klasse hat eine eigene Tabelle in der Datenbank(Oracle).

Nach dem Mapping habe ich versucht ein Objekt vom Typ Klasse2 mit dem Attribut vom Typ Klasse4 (Da es von Klasse 3 erbt) zu speichern. Dabei werden die Attribute von Klasse1(Geschäftsobjekt) und Klasse2(Geschäftsobjekt) sowie Klasse3(Wertobjekt) in die Tabellen geschrieben, aber nicht von Klasse 4.

Hat jemand eine Idee wie ich es realisieren könnte?

Beschreibung:
(Code)
Java:
//Geschäftsojekt z.B. Person
class Klasse1{
//Liste von Obj. des Typs Klasse3 z.B. Auto
private List<Klasse3> meineAttribute; //
}

//Geschäftsobjekt
class Klasse2 extends Klasse1{
}

//Wertobjekt z.B. Auto
class Klasse3{
}

//Wertobjekt z.B. Audi
class Klasse4 extends Klasse3{
// die Attribute in dieser Klasse werden nicht gespeichert!
}

class Applikationsklasse{
  public static void main(String[] args){
    //Hier erstelle ich mein Objekt, das ich speichern will
    Klasse2 klasse2 =new Klasse2();
    //Hier setze ich die Attribute von klasse2
    //.....

    Klasse4 klasse4 =new Klasse4();
    //....hier setzte ich die Attribute von klasse4
 
   List<Klasse3> meineAttribute =new List<Klasse3>();
   meineAttribute.add(klasse4);

   klasse2.setMeineAttribute(meineAttribute);

//...hier Steht mein Hibernate Code 
 session.Save(klasse2); //Speichern des Objektes    

}

}

(Mapping 1: klasse1.hbm.xml)
XML:
<class name="Klasse1">
<proper...../>
       <list name="meineAttribute">
  	 <key column="id"></key>
  	 <list-index column="lfd_nr"></list-index>
  	 <composite-element class="Klasse3">
  	  <proper...../>
  	  </composite-element>
  	</list>
       <joined-subclass name="Klasse2">
		<key column="id"></key>
		<proper...../>
                <proper...../>
	</joined-subclass>
</class>


(Mapping 2: klasse3.hbm.xml)
XML:
<class name="Klasse3">
<proper...../>
       <joined-subclass name="Klasse4">
		<key column="id"></key>
		<proper...../>
                <proper...../>
	</joined-subclass>
</class>

Gruß Konstantin
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

also vielleicht ist es etwas schwer zu verstehen.
Ich mache ein Beispiel:
Es gibt eine Klasse Person (Person1 == Klasse1). Diese Klasse hat ein Attribut Rolle (Rolle == Klasse3). Eine Person kann viele Rollen haben. Ausprägungen von Rollen sind Student(Student == Klasse4), Dozent, Mitarbeiter usw.

Um einen Studenten im dem System abzubilden, braucht man ein Objekt Person2 mit der Rolle Student. Will man einen Dozenten abbilden, dann reicht Person1 mit der Rolle Dozent.
(Soweit hoffentlich klar. :-) )

Jetzt habe ich ein Mapping für Person1 geschrieben:
XML:
<class name="Person1">
<prop..../>
<list name="rollen" table="rolle">
  	 <key column="id"></key>
  	 <list-index column="lfd_nr"></list-index>
  	  <composite-element class="Rolle">
  	   <prop.../>
  	  </composite-element>
</list>
<joined-subclass name="Person2">
		<key column="id"></key>
		<property name="geburtsdatum" type="java.util.Date"></property>
		<property name="geburtsort" type="java.lang.String"></property>
		<property name="staatsangehoerigkeit" type="java.lang.String" column="staat"></property>
</joined-subclass>
</class>

und ein weiteres Mapping für Rollen:

XML:
<class name="Rollen">
<prop..../>
<joined-subclass name="Student">
		<key column="id"></key>
		<prop..../>
                <prop..../>
</joined-subclass>
</class>

Speichere ich jetzt ein Objekt vom Typ Person2 mit der Rolle Student, dann müssten jetzt Attribute in die Tabellen Person1,Person2,Rolle UND Student geschrieben werden. Leider werden nur Person1, Person2 und Rolle gefüllt.

Das Modell könnt ihr euch im Anhang anschauen.


Gruß Konstantin
 
Zuletzt bearbeitet von einem Moderator:
Liegt es vielleicht daran, dass ich die Rolle zuerst speichern muss, bevor ich das Personenobjekt speichere?
Beispiel:
Java:
session.save(meineRolle);
session.save(person2);

Gruß Konstantin
 
Hallo,

also ich habe es so hinbekommen:

Zuerst die 4 Klassen(Person1,Person2,Rolle,Student):

Java:
import java.util.List;


public class Person1 {
	private long id;
	private String nachname;
	private String vorname;
	private List rolle;
	
	public List getRolle() {
		return rolle;
	}
	public void setRolle(List rolle) {
		this.rolle = rolle;
	}
	public Person1(String nachname, String vorname) {
		super();
		this.nachname = nachname;
		this.vorname = vorname;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getNachname() {
		return nachname;
	}
	public void setNachname(String nachname) {
		this.nachname = nachname;
	}
	public String getVorname() {
		return vorname;
	}
	public void setVorname(String vorname) {
		this.vorname = vorname;
	}
}


public class Person2 extends Person1{
	private String geburtsort;

	
	public Person2(String nachname, String vorname, String geburtsort) {
		super(nachname, vorname);
		this.geburtsort = geburtsort;
	}

	public Person2(String nachname, String vorname) {
		super(nachname, vorname);
		// TODO Auto-generated constructor stub
	}

	public String getGeburtsort() {
		return geburtsort;
	}

	public void setGeburtsort(String geburtsort) {
		this.geburtsort = geburtsort;
	}
}


public class Rolle {
	private long id;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
	
}

public class Student extends Rolle {

	private String matrikelnummer;

	public Student(String matrikelnummer) {
		super();
		this.matrikelnummer = matrikelnummer;
	}

	public String getMatrikelnummer() {
		return matrikelnummer;
	}

	public void setMatrikelnummer(String matrikelnummer) {
		this.matrikelnummer = matrikelnummer;
	}

}

dann das Mapping(Person1.hbm.xml):
XML:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

  <class name="Person1">
  		<id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
         <list name="rolle" cascade="all">
            <key column="parent_id"/>
            <index column="idx"/>
            <one-to-many class="Rolle"/>
        </list>
        <property name="nachname" type="java.lang.String"></property>
        <property name="vorname" type="java.lang.String"></property>
        <joined-subclass name="Person2">
    		<key column="id"></key>
    		<property name="geburtsort" type="java.lang.String"></property>
 		 </joined-subclass>
  </class>
  <class name="Rolle">
  		<id name="id" unsaved-value="0">
            <generator class="increment"/>
        </id>
        
         <joined-subclass name="Student">
    		<key column="id"></key>
    		<property name="matrikelnummer" type="java.lang.String"></property>
 		  </joined-subclass>
  </class>
</hibernate-mapping>


und dann die Methode mit der ich überprüfe, ob das Mapping erfolgreich ist:
Java:
import java.security.acl.Group;
import java.util.ArrayList;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;






public class Main {
	public static void main(String[] args){
		  Configuration configuration = new Configuration()
			.setProperty("hibernate.connection.driver_class", "...")
			.setProperty("hibernate.connection.password", "...")
			.setProperty("hibernate.connection.url", "...")
			.setProperty("hibernate.connection.username", "...")
			.setProperty("hibernate.dialect", "org.hibernate.dialect....")
			.setProperty("hibernate.show_sql","true")
			.addClass(Person1.class);
			SchemaExport schemaExport =new SchemaExport(configuration);
			schemaExport.drop(true, true);
			schemaExport.create(true, true);
			SessionFactory sessionFactory=configuration.buildSessionFactory();
			
			Person2 neuerStudent =new Person2("denerz","konstantin","novosibirsk");
			
			ArrayList list =new ArrayList();
			list.add(new Student("5565"));
			list.add(new Student("5566"));
			neuerStudent.setRolle(list);
	      
	      Session session =null;
			Transaction transaction= null;
	      try {
	    	  session = sessionFactory.openSession();
	           transaction = session.beginTransaction();
	           session.save(neuerStudent);
	           transaction.commit();
	      } catch (Exception e) { 
	           if (transaction != null) {
	             transaction.rollback();
	             
	           }
	           System.out.println(e.getMessage());
	      }  finally { 
	           session.close();
	      }
	}
}


Gruß Konstantin
 
Zuletzt bearbeitet von einem Moderator:
Ich befasse mich auch gerade mit Hibernate und habe heute ein Kapitel im Buch "Java Persistence with Hibernate" zufällig über Vererbung und Mapping gelesen (kann das Buch nur empfehlen, is aber Englisch).

Es gibt in Hibernate vier Mappingstrategien bezüglich Vererbung
  1. table per concrete class (with implicit polymorphism)
  2. table per concrete class (with unions)
  3. table per class hierarchy
  4. table per subclass

Google doch einfach mal nach diesen Strategien
 
Zurück