Beispiel: Entity Inheritance


Inhalt:

Strategie SINGLE_TABLE
Strategie TABLE_PER_CLASS
Strategie JOINED
Application Client
Ohne Annotations

Beispiel für eine Entity Bean die zwei Subklassen mit unterschiedlichen Feldern hat. Diese Vererbung wird mittels der drei im JavaEE5-Standard definierten Vererbungsstrategien abgebildet.
Hier gibt es nur einen sehr trivialen Application Client, der für jede der drei Strategien gleich abläuft: es wird eine Bean von jedem Subtyp erzeugt, diese Beans werden aus der DB geladen, am Schluss wird wieder alles gelöscht.
Hier gibt es das Projekt zum Download (dies ist ein EAR-Export, die Importanleitung findet man im Stateless-Beispiel): KuchenInheritance.ear

Aufbau des Beispieles

a) Entity Bean-Klasse sowie zwei Subklassen gemäß Strategie SINGLE_TABLE.
b) Entity Bean-Klasse sowie zwei Subklassen gemäß Strategie TABLE_PER_CLASS.
c) Entity Bean-Klasse sowie zwei Subklassen gemäß Strategie JOINED.
d) Application Client
Für alle drei Strategien sind die Beispiele identisch aufgebaut: es gibt eine (abstrakte) KuchenBaseBean mit den Attributen "id" und "name". Außerdem gibt es eine Subklasse KuchenKaeseBean für Beans mit der Spezialisierung "Käsekuchen" und dem zusätzlichen Attribut "mengeKaese", sowie eine Subklasse KuchenMohnBean für Beans mit der Spezialisierung "Mohnkuchen" und dem zusätzlichen Attribut "mengeMehl" und "mengeMohn" (ja, ich weiß: seeeehr sinnloses Beispiel ;-) ).
Im Code stecken die Beans in eigenen Packages die gemäß Vererbungsstrategie benannt sind, außerdem enthält der Klassenname die Strategie.


Strategie SINGLE_TABLE

Dies bedeutet: es wird nur eine einzige Tabelle in der Datenbank erzeugt, die so heißt wie die Basisklasse und alle Felder aller Subklassen enthält. Zur Unterscheidung der einzelnen Beans wird eine "Discriminator Column" eingeführt, die pro Datensatz eine Kennung des Typs enthält.

Basisklasse KuchenSingleTableBaseBean:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@NamedQuery (name="findAllKuchenSingleTable", query="select o from KuchenSingleTableBaseBean o")
public abstract class KuchenSingleTableBaseBean implements Serializable
{
  private Integer intId;
  private String strName;
  
  public KuchenSingleTableBaseBean()
  { 
  }
  
  @Column()
  @Id ()
  @GeneratedValue ()
  public Integer getId()
  {
    return this.intId;
  }

  public void setId(Integer int_Id)
  {
    this.intId = int_Id;
  }
  
  @Column()
  public String getName()
  {
    return this.strName;
  }

  public void setName(String str_Name)
  {
    this.strName = str_Name;
  }
} 
Die Strategie wird über die Annotation @Inheritance definiert, als Typ haben wir hier InheritanceType.SINGLE_TABLE gewählt. Hier könnten Name und Typ der Discriminator Column über eine Annotation @DiscriminatorColumnangegeben werden, ich belasse das hier beim Default (resultiert in einer Spalte "DTYPE" in der Datenbank).
Die Named Query dient dazu alle Kuchen inklusive aller Subtypen zu laden, also den gesamten Tabelleninhalt.

Subklasse KuchenSingleTableKaeseBean:
@Entity
@DiscriminatorValue(value="kaesekuchen")
@NamedQuery (name="findAllKaeseKuchenSingleTable", query="select o from KuchenSingleTableKaeseBean o")
public class KuchenSingleTableKaeseBean extends KuchenSingleTableBaseBean implements Serializable
{
  private Integer intMengeKaese = 0;

  @Column
  public Integer getMengeKaese()
  {
    return this.intMengeKaese;
  }

  public void setMengeKaese(Integer _intMengeKaese)
  {
    this.intMengeKaese = _intMengeKaese;
  }
}
Hier wird zur Erkennung von Instanzen dieser Klasse in der Datenbank ein Wert der Discriminator Column mittels der Annotation @DiscriminatorValue eingetragen: alle Käsekuchen sollen hier den Wert "kaesekuchen" stehen haben.
Die Named Query liefert NUR Käsekuchen zurück, alle anderen Typen werden nicht berücksichtigt.

Ähnlich sieht es für die Subklasse KuchenSingleTableMohnBean aus (hier nur den Anfang der Klasse):
@Entity
@DiscriminatorValue(value="mohnkuchen")
@NamedQuery (name="findAllMohnKuchenSingleTable", query="select o from KuchenSingleTableMohnBean o")
public class KuchenSingleTableMohnBean extends KuchenSingleTableBaseBean implements Serializable
{
  ... 
Auch hier wird ein Discriminator Value gesetzt, und es wird eine spezielle Named Query deklariert die nur Mohnkuchen zurückliefert.

Das Ergebnis in der Datenbank sieht so aus:
SINGLE_TABLE


Strategie TABLE_PER_CLASS

Dies bedeutet: es wird pro echter Bean-Klasse (abstrakte Klassen ausgenommen !) eine Tabelle in der Datenbank erzeugt, und alle Felder der Subklasse sowie aller Parentklassen enthält.
Limitierung dieses Beispiels: Der Primary Key kann hier nicht automatisch generiert werden (gibt Fehler beim Deploy), das heißt er muss an anderer Stelle generiert werden (entweder in der Session Bean vor dem Speichern oder, wie im Beispiel geschehen, im Client).

Basisklasse KuchenTablePerClassBaseBean:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@NamedQuery (name="findAllKuchenSingleTable", query="select o from KuchenTablePerClassBaseBean o")
public abstract class KuchenTablePerClassBaseBean implements Serializable
{
  private Integer intId;
  private String strName;
  
  public KuchenSingleTableBaseBean()
  { 
  }
  
  @Column()
  @Id ()
  public Integer getId()
  {
    return this.intId;
  }

  ...
} 
Der Rest des Codes ist identisch mit dem vorherigen Beispiel.

Die beiden Subklassen KuchenTablePerClassKaeseBean und KuchenTablePerClassMohnBean unterscheiden sich nicht von den Beans aus dem vorherigen Beispiel (abgesehen davon dass hier die Annotation @DiscriminatorValue natürlich nicht verwendet werden darf und die Named Query einen anderen Namen hat).

Das Ergebnis in der Datenbank sieht so aus:
TABLE_PER_CLASS
Für die abstrakte Basisklasse KuchenTablePerClassBaseBean wurde keine Tabelle erzeugt weil diese abstrakt ist.


Strategie JOINED

Dies bedeutet: es wird pro Bean-Klasse (einschließlich abstrakter Klassen) eine Tabelle in der Datenbank erzeugt, die alle Felder der jeweiligen Klasse enthält.

Basisklasse KuchenJoinedBaseBean:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@NamedQuery (name="findAllKuchenJoined", query="select o from KuchenJoinedBaseBean o")
public abstract class KuchenJoinedBaseBean implements Serializable
{
  ...
} 
Der Rest des Codes ist identisch mit dem Beispiel "SINGLE_TABLE" (einschließlich automatisch generierter ID).

Die beiden Subklassen KuchenJoinedKaeseBean und KuchenJoinedMohnBean unterscheiden sich nicht von den Beans aus dem vorherigen Beispiel (abgesehen davon dass hier die Annotation @DiscriminatorValue natürlich nicht verwendet werden darf und die Named Query einen anderen Namen hat).

Das Ergebnis in der Datenbank sieht so aus:
JOINED


Application Client

Der Client besteht aus drei Methoden die jeweils einen Kuchen von jedem Typ erzeugen, ihn speichern, danach die Liste aller Kuchen sowie die Listen der Mohn- und der Käsekuchen abrufen sowie die beiden Kuchen wieder löschen.
Im folgenden der Code für die Strategie "SINGLE_TABLE":
private static void testSingleTable(InitialContext _initialContext) throws NamingException
  {
    Object objKuchenWorker = _initialContext.lookup("java:comp/env/ejb/KuchenSingleTableWorker");
    KuchenSingleTableWorker kuchenWorker = (KuchenSingleTableWorker) PortableRemoteObject.narrow(objKuchenWorker, KuchenSingleTableWorker.class);
    
    KuchenSingleTableKaeseBean kaeseKuchen = new KuchenSingleTableKaeseBean();
    kaeseKuchen.setName("Käsekuchen 1");
    kaeseKuchen.setMengeKaese(100);
    
    kaeseKuchen = (KuchenSingleTableKaeseBean) kuchenWorker.saveKuchen(kaeseKuchen);
    
    KuchenSingleTableMohnBean mohnKuchen = new KuchenSingleTableMohnBean();
    mohnKuchen.setName("Mohnkuchen 1");
    mohnKuchen.setMengeMohn(50);
    mohnKuchen.setMengeMehl(300);
    
    mohnKuchen = (KuchenSingleTableMohnBean) kuchenWorker.saveKuchen(mohnKuchen); 
    
    //Alle Kuchen ausgeben:
    System.out.println ("================================");
    System.out.println ("Single Table");
    System.out.println ("==>Alle Kuchen holen:");
    List<KuchenSingleTableBaseBean> listKuchenBase = kuchenWorker.getKuchen();
    for (KuchenSingleTableBaseBean kuchenAktuell : listKuchenBase)
    {
      System.out.println ("   -" + kuchenAktuell.getName());
    }
    
    System.out.println ("==>Käsekuchen holen:");
    List<KuchenSingleTableKaeseBean> listKuchenKaese = kuchenWorker.getKaeseKuchen();
    for (KuchenSingleTableKaeseBean kuchenAktuell : listKuchenKaese)
    {
      System.out.println ("   -" + kuchenAktuell.getName());
    }
    
    System.out.println ("==>Mohnkuchen holen:");
    List<KuchenSingleTableMohnBean> listKuchenMohn = kuchenWorker.getMohnKuchen();
    for (KuchenSingleTableMohnBean kuchenAktuell : listKuchenMohn)
    {
      System.out.println ("   -" + kuchenAktuell.getName());
    }
    
    //Aufräumen:
    kuchenWorker.deleteKuchen(mohnKuchen);
    kuchenWorker.deleteKuchen(kaeseKuchen);
    System.out.println ("==>Alle Kuchen gelöscht !");
  } 
Der Code für die Strategie "JOINED" ist bis auf die geänderten Klassennamen identisch, nur im Beispiel "TABLE_PER_CLASS" muss die ID explizit gesetzt werden.


Ohne Annotations

"ejb-jar.xml" sieht so aus:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar id="ejb-jar_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                           http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
	<display-name>
	KuchenInheritanceEJB</display-name>
	
	<enterprise-beans>
		<session>
			<description>
				<![CDATA[Stateless Session Bean für das Arbeiten mit Kuchen gemäß Joined-Strategie]]>
			</description>
			<display-name>KuchenJoinedWorkerBean</display-name>
			<ejb-name>KuchenJoinedWorkerBean</ejb-name>
			<remote>de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedWorker</remote>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedWorkerBean</ejb-class>
			<session-type>Stateless</session-type>
			<persistence-context-ref>
				<persistence-context-ref-name>KuchenInheritancePersistenceUnitRef</persistence-context-ref-name>
				<persistence-unit-name>kuchenInheritancePersistenceUnit</persistence-unit-name>
				<injection-target>
					<injection-target-class>
						de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedWorkerBean
					</injection-target-class>
					<injection-target-name>entityManager</injection-target-name>
				</injection-target>
			</persistence-context-ref>
		</session>
		<session>
			<description>
				<![CDATA[Stateless Session Bean für das Arbeiten mit Kuchen gemäß SingleTable-Strategie]]>
			</description>
			<display-name>KuchenSingleTableWorkerBean</display-name>
			<ejb-name>KuchenSingleTableWorkerBean</ejb-name>
			<remote>de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableWorker</remote>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableWorkerBean</ejb-class>
			<session-type>Stateless</session-type>
			<persistence-context-ref>
				<persistence-context-ref-name>KuchenInheritancePersistenceUnitRef</persistence-context-ref-name>
				<persistence-unit-name>kuchenInheritancePersistenceUnit</persistence-unit-name>
				<injection-target>
					<injection-target-class>
						de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableWorkerBean
					</injection-target-class>
					<injection-target-name>entityManager</injection-target-name>
				</injection-target>
			</persistence-context-ref>
		</session>
		
		<session>
			<description>
				<![CDATA[Stateless Session Bean für das Arbeiten mit Kuchen TablePerClass-Strategie]]>
			</description>
			<display-name>KuchenTablePerClassWorkerBean</display-name>
			<ejb-name>KuchenTablePerClassWorkerBean</ejb-name>
			<remote>de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassWorker</remote>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassWorkerBean</ejb-class>
			<session-type>Stateless</session-type>
			<persistence-context-ref>
				<persistence-context-ref-name>KuchenInheritancePersistenceUnitRef</persistence-context-ref-name>
				<persistence-unit-name>kuchenInheritancePersistenceUnit</persistence-unit-name>
				<injection-target>
					<injection-target-class>
						de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassWorkerBean
					</injection-target-class>
					<injection-target-name>entityManager</injection-target-name>
				</injection-target>
			</persistence-context-ref>
		</session>
		
		<entity>
			<description>
				<![CDATA[Basis-Entity Bean für einen Kuchen gemäß JOINED-Strategie.]]>
			</description>
			<display-name>KuchenJoinedBaseBean</display-name>
			<ejb-name>KuchenJoinedBaseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedBaseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß JOINED-Strategie.]]>
			</description>
			<display-name>KuchenJoinedKaeseBean</display-name>
			<ejb-name>KuchenJoinedKaeseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedKaeseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß JOINED-Strategie.]]>
			</description>
			<display-name>KuchenJoinedMohnBean</display-name>
			<ejb-name>KuchenJoinedMohnBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedMohnBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		
		<entity>
			<description>
				<![CDATA[Basis-Entity Bean für einen Kuchen gemäß SINGLE_TABLE-Strategie.]]>
			</description>
			<display-name>KuchenSingleTableBaseBean</display-name>
			<ejb-name>KuchenSingleTableBaseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableBaseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß SINGLE_TABLE-Strategie.]]>
			</description>
			<display-name>KuchenSingleTableKaeseBean</display-name>
			<ejb-name>KuchenSingleTableKaeseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableKaeseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß SINGLE_TABLE-Strategie.]]>
			</description>
			<display-name>KuchenSingleTableMohnBean</display-name>
			<ejb-name>KuchenSingleTableMohnBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableMohnBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		
		<entity>
			<description>
				<![CDATA[Basis-Entity Bean für einen Kuchen gemäß TABLE_PER_CLASS-Strategie.]]>
			</description>
			<display-name>KuchenTablePerClassBaseBean</display-name>
			<ejb-name>KuchenTablePerClassBaseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassBaseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß TABLE_PER_CLASS-Strategie.]]>
			</description>
			<display-name>KuchenTablePerClassKaeseBean</display-name>
			<ejb-name>KuchenTablePerClassKaeseBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassKaeseBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
		<entity>
			<description>
				<![CDATA[Sub-Entity Bean für einen Käse-Kuchen gemäß TABLE_PER_CLASS-Strategie.]]>
			</description>
			<display-name>KuchenTablePerClassMohnBean</display-name>
			<ejb-name>KuchenTablePerClassMohnBean</ejb-name>
			<ejb-class>de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassMohnBean</ejb-class>
			<persistence-type>Container</persistence-type>
			<prim-key-class>java.lang.Integer</prim-key-class>
			<reentrant>false</reentrant>
		</entity>
	</enterprise-beans>
</ejb-jar> 
Es gibt keine Neuerungen im Vergleich zum KuchenZutatNM-Beispiel.

"orm.xml" enthält die Angaben über das Mapping:
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
	version="1.0">
	<named-query name="findAllKuchenJoined">
		<query>select o from KuchenJoinedBaseBean o</query>
	</named-query>
	<named-query name="findAllKaeseKuchenJoined">
		<query>select o from KuchenJoinedKaeseBean o</query>
	</named-query>
	<named-query name="findAllMohnKuchenJoined">
		<query>select o from KuchenJoinedMohnBean o</query>
	</named-query>
	
	<named-query name="findAllKuchenSingleTable">
		<query>select o from KuchenSingleTableBaseBean o</query>
	</named-query>
	<named-query name="findAllKaeseKuchenSingleTable">
		<query>select o from KuchenSingleTableKaeseBean o</query>
	</named-query>
	<named-query name="findAllMohnKuchenSingleTable">
		<query>select o from KuchenSingleTableMohnBean o</query>
	</named-query>
	
	<named-query name="findAllKuchenTablePerClass">
		<query>select o from KuchenTablePerClassBaseBean o</query>
	</named-query>
	<named-query name="findAllKaeseKuchenTablePerClass">
		<query>select o from KuchenTablePerClassKaeseBean o</query>
	</named-query>
	<named-query name="findAllMohnKuchenTablePerClass">
		<query>select o from KuchenTablePerClassMohnBean o</query>
	</named-query>
	
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedBaseBean" access="PROPERTY"
		metadata-complete="true">
		<inheritance strategy="JOINED"/>
		<attributes>
			<id name="id">
				<column name="ID" />
				<generated-value />
			</id>
			<basic name="name">
				<column name="NAME" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedKaeseBean" access="PROPERTY"
		metadata-complete="true">
		<attributes>
			<basic name="mengeKaese">
				<column name="MENGEKAESE" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.joined.KuchenJoinedMohnBean" access="PROPERTY"
		metadata-complete="true">
		<attributes>
			<basic name="mengeMohn">
				<column name="MENGEMOHN" />
			</basic>
			<basic name="mengeMehl">
				<column name="MENGEMEHL" />
			</basic>
		</attributes>
	</entity>
	
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableBaseBean" access="PROPERTY"
		metadata-complete="true">
		<inheritance strategy="SINGLE_TABLE"/>
		<attributes>
			<id name="id">
				<column name="ID" />
				<generated-value />
			</id>
			<basic name="name">
				<column name="NAME" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableKaeseBean" access="PROPERTY"
		metadata-complete="true">
		<discriminator-value>kaesekuchen</discriminator-value>
		<attributes>
			<basic name="mengeKaese">
				<column name="MENGEKAESE" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.singletable.KuchenSingleTableMohnBean" access="PROPERTY"
		metadata-complete="true">
		<discriminator-value>mohnkuchen</discriminator-value>
		<attributes>
			<basic name="mengeMohn">
				<column name="MENGEMOHN" />
			</basic>
			<basic name="mengeMehl">
				<column name="MENGEMEHL" />
			</basic>
		</attributes>
	</entity>
	
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassBaseBean" access="PROPERTY"
		metadata-complete="true">
		<inheritance strategy="TABLE_PER_CLASS"/>
		<attributes>
			<id name="id">
				<column name="ID" />
				<!-- Hier ist "generated-value" nicht möglich ! -->
				<!-- <generated-value /> -->
			</id>
			<basic name="name">
				<column name="NAME" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassKaeseBean" access="PROPERTY"
		metadata-complete="true">
		<attributes>
			<basic name="mengeKaese">
				<column name="MENGEKAESE" />
			</basic>
		</attributes>
	</entity>
	<entity class="de.fhw.swtvertiefung.knauf.kucheninheritance.tableperclass.KuchenTablePerClassMohnBean" access="PROPERTY"
		metadata-complete="true">
		<attributes>
			<basic name="mengeMohn">
				<column name="MENGEMOHN" />
			</basic>
			<basic name="mengeMehl">
				<column name="MENGEMEHL" />
			</basic>
		</attributes>
	</entity>

</entity-mappings>
Fett markiert sind hier neuen Elemente die die Inheritance Strategy steuern. Auch hier ist bei Verwendung von "TABLE_PER_CLASS" kein generierter Primary Key möglich.

Die modifizierte Version des Projekts gibt es hier:
KuchenInheritanceNoAnnotation.ear.
ACHTUNG 1: Dieses Projekt kann nicht neben dem obigen KuchenInheritance-Beispiel existieren !

ACHTUNG 2: Ein Re-Import der EAR-Datei klappt nur wenn in ejb-jar.xml das Element "persistence-context-ref" auskommentiert ist ! Ansonsten zeigt Eclipse eine Fehlermeldung, ohne sich allerdings über die Details auszulassen. Dieses Element muss nach dem Import wieder einkommentiert werden !



Stand 13.05.2007
Historie:
09.05.2007: Beispiel erstellt
13.05.2007: @Column-Annotations in den Kuchen...MohnBeans zugefügt.