|
Die folgende Referenz ist im Buch "Hibernate – Das Praxisbuch für Entwickler" von Sebastian Hennebrüder enthalten.
A Annotation Reference – Teil 1
Dieses Kapitel bietet Ihnen eine vollständige übersicht über alle Annotations. Kurze Quellcodeausschnitte zeigen die Verwendung. Wenn es ein Beispiel zum Download gibt, so wird auf dieses verwiesen. Die Beispielcodes finden Sie ebenfalls unter "BuchUpdates".
Hinweis
Wenn ich programmiere, verwende ich den Quellcode von Hibernate als hilfreiche Unterstützung. Der Annotation-Quellcode zeigt Ihnen die möglichen Attribute und alle Vorgabewerte. Das ist fast so gut wie diese Referenz. In Eclipse kann man sich mit der Kombination Taste Ctrl (alias Strg) und einem Klick auf die Annotation den Quellcode anzeigen lassen. Beim ersten Mal müssen Sie festlegen, wo der Quellcode zu finden ist.
Der Quellcode für die EJB-Implementierung ist nicht so einfach zu finden. Verwenden Sie am besten den anonymen Subversion-Zugang zum JBoss Repository:
http://anonsvn.jboss.org/repos/hibernate/trunk/HibernateExt/ejb-api
Die Seite http://www.hibernate.org/6.html erklärt, wie man den Zugang konfiguriert. Den Hibernate-Quellcode können Sie den Hibernate-Webseiten entnehmen: http://www.hibernate.org.
1 Annotations für Entities und Tabellen
| @javax.persistence.Entity |
@javax.persistence.Entity( |
legt fest, dass eine Klasse eine gemappte Hibernate Entity ist. |
name="EntityName" |
optional, Name, der in Abfragen verwendet wird;
Vorgabe ist der Klassenname |
) |
|
@Entity
public class Tiger implements Serializable {
|
| @org.hibernate.annotations.Entity |
@org.hibernate.annotations.
Entity(
|
ist eine Erweiterung zur Annotation @javax.persistence.Entity und kann nur zusätzlich verwendet werden; sie erlaubt, detailliert Hibernate-spezifische Parameter für das Entity festzulegen. |
mutable = true,
|
Wenn das Entity nur gelesen, aber nicht geändert werden kann, sollte man mutable den Wert false zuweisen. |
dynamicInsert = true,
|
Update-Queries für Klassen werden gewöhnlich bei der Initialisierung erzeugt und aktualisieren alle Spalten der Datenbank, auch wenn sich nur ein Feld ändert. Das ist nur in genau einer Situation ein Problem:
Wenn Sie in einer Tabelle Spalten mit kurzen Werten und Spalten mit Blobs/Clobs mischen und häufig die kurzen Spalten ändern, würde der Update-Befehl unnötigerweise die Blob/Clob-Spalten beinhalten und die Geschwindigkeit verschlechtern.
Lösung a: Teilen Sie Ihre Tabelle auf.
Lösung b: Verwenden Sie dynamic-update.
Wenn Sie dynamic-update verwenden, erzeugt Hibernate dynamisch eine Update-Query, die nur die Spalten enthält, welche sich auch geändert haben. Es ist wichtig zu wissen, dass die Erzeugung der Query Zeit kostet, da keine existierende Query wieder verwendet werden kann. Verwenden Sie das also nicht bei "normalen" Tabellen. Weitere Hinweise finden Sie in Abschnitt 2.6, "Fortgeschrittene Möglichkeiten". |
dynamicUpdate = true,
|
Das Prinzip ist das gleiche wie bei dynamic-update. Der Unterschied ist, dass nur Spaltennamen in der Insert-Query verwendet werden, die nicht leer sind. |
selectBeforeUpdate = false,
|
Diese Einstellung wird die Performance deutlich verschlechtern und sollte daher vermieden werden.
Wenn select-before-update verwendet wird, prüft Hibernate vor jedem Update mit einer Abfrage, ob sich die Daten verändert haben. Ein sinnvolles Szenario wäre: Man möchte vermeiden, dass durch ein unnötiges Update ein Trigger auf der Datenbank aufgerufen wird. |
polymorphism = PolymorphismType.IMPLICIT,
|
Diese Einstellung legt fest, wie sich Hibernate bei Vererbungshierarchien verhält.
Beispiel: class Blume extends Pflanze. Die Query heißt select from Pflanze.
Implicit bedeutet, dass diese Abfrage, je nachdem, ob ein Datenbankeintrag eine Blume oder nur eine Pflanze ist, eine Instanz der jeweiligen Klasse zurückgibt.
Explicit würde bei dieser Abfrage, wenn es eine Instanz der Klasse Blume findet, eine Klasse Pflanze zurückgeben und die zusätzlichen Felder von Blume einfach ignorieren. |
persister = "customPersister",
|
Diese Einstellung muss äußerst selten geändert werden. Ein Persister ist verantwortlich für das Schreiben der Daten. Man könnte zum Beispiel einen Persister erstellen, der Daten in LDAP speichert.
Im Hibernate-Download finden Sie ein Beispiel im test-Verzeichnis. Suchen Sie nach der Klasse org.hibernate.test.legacy.CustomPersister. |
optimisticLock = OptimisticLockType.VERSION
|
Legt die Strategie für optimistic lokking fest. Ich empfehle, die Einstellung nur zu ändern, wenn es wirklich notwendig ist. Eine änderung bringt eine deutliche Performance-Einbuße.
ALL liest die Daten aus der Datenbank und prüft alle Spalten, ob sich diese geändert haben. DIRTY liest auch die Daten aus, validiert aber nur Spalten, die sich geändert haben. Damit kann man konkurrierende Updates auf dem gleichen Datensatz durchführen, ohne dass es zu einer Ausnahme kommt.
Mehr Informationen zu Optimistic-Locking erhalten Sie in Abschnitt 5.2.1, "Optimistisches Sperren". |
)
|
|
@Entity
@org.hibernate.annotations.Entity(mutable = true, dynamicInsert = true,
dynamicUpdate = true, selectBeforeUpdate = false,
polymorphism = PolymorphismType.IMPLICIT,
persister = "customPersister",
optimisticLock = OptimisticLockType.VERSION)
public class Tiger implements Serializable {
|
| @javax.persistence.Table |
@javax.persistence.Table(
|
optional, ermöglicht, den Tabellennamen festzulegen, auf den die Klasse gemappt ist. Der Vorgabewert ist der Klassen- bzw. Entity-Name. |
name = "tableName",
|
Name der Datenbanktabelle |
catalog = "catalogName",
|
optional, Name des Datenbankkatalogs (Kataloge werden nicht von allen Datenbanken unterstützt);
überschreibt den Vorgabewert aus der Hibernate-Konfiguration |
schema = "dbSchemaName",
|
optional, Name des Datenbankschemas (Schemas werden nicht von allen Datenbanken unterstützt);
überschreibt den Vorgabewert aus der Hibernate-Konfiguration |
uniqueConstraints = {
@UniqueConstraint(
columnNames = { "databaseColumn", "anotherColumn" }) }
|
optional, bewirkt, dass Hibernate beim Erzeugen von Tabellen einen unique key constraint erzeugt; |
)
|
|
| @org.hibernate.annotations.Table |
@org.hibernate.annotations.Table(
|
Hibernate-Erweiterung zu EJB 3, erstellt einen Index, wenn Hibernate Tabellen erzeugt. Kann mit den Annotations @javax.persistence.Table und @javax.persistence.SecondaryTable verwendet werden. |
appliesTo = "tableName", |
Name der Datenbanktabelle |
comment = "" |
Kommentar zur Tabelle |
foreignKey = @ForeignKey( name="" ) |
Namen des Foreign-Key-Constraints für Beziehungen |
fetch = FetchMode.JOIN |
legt fest, wie die Sekundärtabelle geladen wird |
inverse=false |
kein insert/update/delete für die Sekundärtabelle |
optional = true |
true = insert/update in Sekundärtabelle wenn mindestens ein Attribut ungleich null ist; false = immer insert/update |
sqlInsert = @SQLInsert(sql="") |
Benutzer definierter insert Befehl für Sekundärtabelle |
sqlUpdate=@SQLUpdate(sql="") |
Benutzer definierter update Befehl für Sekundärtabelle |
sqlDelete=@SQLDelete(sql="") |
Benutzer definierter delete Befehl für Sekundärtabelle |
indexes = { @Index(name = "forest_idx", columnNames = {"indexedColumn"}) }
|
ein Array von @Index |
)
|
|
| @org.hibernate.annotations.Index |
@org.hibernate.annotations.
Index(
|
Hibernate-Erweiterung zu EJB 3, definiert einen Index |
name = "forestidx",
|
Name des Index |
columnNames = {"colA","colB"}
|
Datenbankspalten, die im Index enthalten sind |
)
|
|
@Entity()
@javax.persistence.Table(name = "tableName",
uniqueConstraints = { @UniqueConstraint(columnNames = { "unique_column" }) })
@org.hibernate.annotations.Table(appliesTo = "tableName",
indexes = { @Index(name = "forestidx", columnNames = { "indexedcolumn" }) })
public class Garden implements Serializable {
|
| @javax.persistence.SecondaryTable |
@javax.persistence.
SecondaryTable(
|
ermöglicht, bestimmte Attribute einer Klasse auf eine zweite Tabelle zu mappen;
für jedes Attribut muss man festlegen, dass es in der SecondaryTable gespeichert werden soll: @Column(table="secondaryTable")
Beispiel im Java Package de.laliluna.other.diverse |
name = "tableName",
|
Pflichtangabe, definiert den Namen der Tabelle |
catalog = "catalogName",
|
optional, Name des Datenbankkatalogs (Kataloge werden nicht von allen Datenbanken unterstützt);
überschreibt den Vorgabewert aus der Hibernate-Konfiguration |
schema = "dbSchemaName",
|
optional, Name des Datenbankschemas (Schemas werden nicht von allen Datenbanken unterstützt);
überschreibt den Vorgabewert aus der Hibernate-Konfiguration |
pkJoinColumns = { @PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id", columnDefinition = "int4") }
|
ein Array von @PrimaryKeyJoinColumn, die festlegen, wie die primäre und die sekundäre Tabelle "gemappt" werden. |
)
|
|
| @javax.persistence.UniqueConstraint |
@javax.persistence.
UniqueConstraint(
|
definiert einen Unique-Key-Constraint, Hibernate verwendet diese Information beim Erzeugen von Tabellen. |
columnNames = { "databaseColumnName}", "anotherColumn" }
|
Pflichtfeld, legt die Tabellenspalten fest, die im Constraint enthalten sind |
)
|
|
| @org.hibernate.annotations.SQLInsert |
| benutzerdefinierter insert-Befehl |
sql="" |
SQL-Befehl |
callable=false |
true = SQL-Befehl verwendet eine Stored-Procedure |
check=ResultCheckStyle.NONE |
Prüfung der geänderten Zeilen durch Rückgabewert von SQL-Befehlen; NONE = keine Prüfung; COUNT = wie executeUpdate eines SQL-Statements; PARAM = nutzt OUT-Parameter einer Stored-Procedure |
| @org.hibernate.annotations.SQLUpdate |
| benutzerdefinierter update-Befehl; siehe @SQLInsert |
| @org.hibernate.annotations.SQLDelete |
| benutzerdefinierter delete-Befehl; siehe @SQLInsert |
| @org.hibernate.annotations.SQLDeleteAll |
| benutzerdefinierter delete-Befehl; siehe @SQLInsert |
| @org.hibernate.annotations Immutable |
| kein Speichern von Entity- oder Attribut-Änderungen |
2 Annotations für Primärschlüssel
Den Quellcode zu den Beispielen finden Sie im Projekt DeveloperGuideAnnotation im Java-Package de.laliluna.primarykey.
| @javax.persistence.Id |
@javax.persistence.Id
|
legt fest, dass ein Attribut zum Primärschlüssel gehört; die Annotation wird bei zusammengesetzten Ids vor alle Attribute geschrieben. |
| @javax.persistence.GeneratedValue |
@javax.persistence.
GeneratedValue(
|
beschreibt, dass die Id erzeugt wird; es gibt unterschiedliche Strategien, um Primärschlüssel erzeugen zu lassen. |
strategy=GenerationType.
SEQUENCE,
|
Vorgabe: GenerationType.AUTO (wählt abhängig von der Datenbank eine Strategie aus)
GenerationType.SEQUENCE verwendet eine Sequenz, Vorgabewert für den Sequenznamen ist hibernate_sequence, Oracle, PostgreSql und andere
GenerationType.TABLE speichert den letzten Wert in einer Datenbanktabelle (eignet sich für alle Datenbanken)
GenerationType.IDENTITY spezieller Spaltentyp; MS SQL und andere |
generator="generatorName"
|
optional: referenziert einen Generator; ein Generator erlaubt, präziser festzulegen, wie die Ids erzeugt werden.
Vorgabewert: Dieser hängt von der Strategie ab. Für eine Sequenz wird ein Generator verwenden, der eine Sequenz mit dem Namen hibernate_sequence benutzt. |
)
|
|
@Entity
public class Cheetah implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
|
@Entity
public class Tiger implements Serializable {
@Id
@TableGenerator(name = "puma_gen", table="primary_keys")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "puma_gen")
private Integer id;
|
| @javax.persistence.IdClass |
@javax.persistence.IdClass(
|
legt die Klasse fest, die einen zusammengesetzten Primärschlüssel speichert. |
value=SpottedTurtleId.class
|
Klassennamen der Primärschlüsselklasse |
)
|
|
@IdClass(SpottedTurtleId.class)
public class SpottedTurtle implements Serializable {
@Id
private String location;
@Id
private String favoriteSalad;
|
| @javax.persistence.EmbeddedId |
@javax.persistence.EmbeddedId
|
definiert die Klasse, welche den zusammengesetzten Primärschlüssel enthält; der Unterschied zu @IdClass ist, dass die Attribute nur in der Primärschlüsselklasse vorhanden sind. |
@Entity
public class BoxTurtle implements Serializable {
@EmbeddedId
private BoxTurtleId id;
|
| @javax.persistence.SequenceGenerator |
@javax.persistence.
SequenceGenerator(
|
definiert einen Id-Generator, der von der Annotation @GeneratedValue referenziert werden kann; der Generator verwendet eine Sequenz. |
name="generatorName",
|
Name des Generators, der in der Annotation @GeneratedValue verwendet werden kann |
sequenceName="dbSequenceName",
|
optional, Name der Sequenz in der Datenbank, Vorgabe: hibernate_sequence |
initialValue=1,
|
legt den Startwert der Sequenz fest, Vorgabewert: 1 |
allocationSize=50
|
Vorgabewert: 50. Der Sequenzgenerator ruft nicht für jeden neuen Datensatz eine Datenbanksequenz auf, sondern erhöht die Sequenz um die allocationSize und verteilt die Nummern. Erst wenn alle Nummern verteilt sind, wird die Sequenz wieder aufgerufen. Wenn man 50 Einträge in die Datenbank schreibt, spart man sich bei einer allocationSize von 50 daher 49 Abfragen der Sequenz. Das verbessert die Performance. Der Nachteil ist, dass die vergebenen Ids bei einem Neustart der Anwendung Lücken haben. |
|
|
Generatoren sollten laut EJB 3 Spec global sein, aber Hibernate hält sich mindestens bis zur Version 3.2 nicht an diese Festlegung. |
)
|
|
@Entity
@SequenceGenerator(name = "puma_seq", sequenceName = "puma_id_seq")
public class Puma implements Serializable {
|
| @javax.persistence.TableGenerator |
@javax.persistence.
TableGenerator(
|
definiert einen Id-Generator, der von der Annotation @GeneratedValue referenziert werden kann; der Generator speichert den letzten Wert in einer Datenbanktabelle. |
name="generatorName",
|
Name des Generators, der in der Annotation @GeneratedValue verwendet werden kann |
table="databaseTable",
|
Tabelle, in der der nächste zu vergebene Wert der Id gespeichert wird |
catalog="databaseCatalog",
|
Datenbankkatalog der Tabelle (wird nur von manchen Datenbanken unterstützt) |
schema="schemaName",
|
Datenbankschema der Tabelle (wird nur von manchen Datenbanken unterstützt) |
valueColumnName
|
Tabellenspalte, in der der nächste zu vergebene Wert der Id gespeichert wird |
pkColumnValue
|
Tabellenspalte, in der ein Schlüsselwert steht, der den nächsten zu vergebenen Wert identifiziert; Vorgabe: Name der Klasse |
initialValue
|
legt den Startwert der Id fest, Vorgabewert: 1 |
allocationSize
|
Vorgabewert: 50. Der Generator erhöht nicht für jeden neuen Datensatz den Wert der Id in der Tabelle, sondern erhöht die Sequenz um die allocationSize und verteilt die Nummern. Erst wenn alle Nummern verteilt sind, wird die Sequenz wieder aufgerufen. Wenn man 50 Einträge in die Datenbank schreibt, spart man sich bei einer allocation Size von 50 daher 49 Mal das Erhöhen des Wertes. Das verbessert die Performance. Der Nachteil ist, dass die vergebenen Ids bei einem Neustart der Anwendung Lücken haben.
Generatoren sollten laut EJB 3 Spec global sein, aber Hibernate hält sich mindestens bis zur Version 3.2 nicht an diese Festlegung. |
uniqueConstraints={
@UniqueConstraint(columnNames={
"col_A, col_B"})}
|
optional, erzeugt beim Erstellen der Tabelle einen Unique-Key-Constraint |
)
|
|
@Id
@TableGenerator(name = "puma_gen", table="primary_keys")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "puma_gen")
private Integer id;
|
| @org.hibernate.annotations.GenericGenerator |
@org.hibernate.annotations. GenericGenerator(
|
Hibernate-spezifischer Generator, der von der Annotation @GeneratedValue referenziert werden kann; der Generator verwendet eine der in XML-basiertem Mapping möglichen Strategien, die in Abschnitt 4.4, "Mapping von Primärschlüsseln", beschrieben worden sind |
name="generatorName",
|
Name des Generators, der in der Annotation @GeneratedValue verwendet werden kann |
strategy = "seqhilo",
|
legt die Strategie fest und kann eine der folgenden Werte haben: identity, sequence, seqhilo, guid, native, select, hilo, assigned, foreign, uuid, increment;
(Detailbeschreibung in Abschnitt 4.4, "Mapping von Primärschlüsseln") |
parameters = { @Parameter(name = "max_lo", value = "5") }
|
Array von @Parameter; wird verwendet, um die Id-Strategie zu konfigurieren |
)
|
|
@Id
@GenericGenerator(name = "aName", strategy = "seqhilo", parameters = {
@Parameter(name = "max_lo", value = "5") })
@GeneratedValue(generator = "aName")
private Integer id;
|
3 Annotations für Spalten
Tipp zur Verwendung von Vorgabewerten
Das Schöne an der EJB 3 Spec und damit auch an Annotations ist die kluge Verwendung von Vorgabewerten.
Häufig werden Sie gar keine Annotation benötigen, da die Vorgabewerte ausreichend sind. Alle Attribute werden automatisch "gemappt", solange Sie keine @Transient-Annotation setzen. Nur bei speziellen Typen, wie zum Beispiel date, enum, ist eine Annotation auf jeden Fall erforderlich.
| @javax.persistence.Column |
@javax.persistence.Column(
|
kann verwendet werden, um die Tabellenspalte genau festzulegen. |
name="full_described_field",
|
Name der Tabellenspalte |
unique=false,
|
Wenn der Wert auf true gesetzt wird, erzeugt Hibernate beim Erstellen der Spalte einen Unique-Key-Constraint. |
nullable=true,
|
Wenn der Wert auf false gesetzt wird, erzeugt Hibernate beim Erstellen der Spalte einen Not-Null-Constraint. |
insertable=true,
|
legt fest, dass die Spalte bei einem insert-Befehl berücksichtigt wird. |
updatable=true,
|
legt fest, dass die Spalte bei einem update-Befehl berücksichtigt wird. |
columnDefinition=
"varchar(255)",
|
ermöglicht, den SQL-Typen der Spalte festzulegen.
Vorgabewert: Der Wert wird anhand des Java-Typen und der Annotations aus dem Dialekt der Hibernate-Konfiguration ermittelt. |
table="tableName2",
|
Tabellenname einer sekundären Tabelle; wenn die Angabe fehlt, gehört die Spalte automatisch zur Primärtabelle; siehe @SecondaryTable |
length=255,
|
Länge der Tabellenspalte; gilt nur für den Java-Typ String
Vorgabewert: 255 |
precision=0,
|
Nachkommastellen, wenn das Attribut eine Zahl ist; der Vorgabewert wird aus dem Dialekt in der Hibernate-Konfiguration ermittelt. |
scale=0
|
Größe der Spalte, wenn das Attribut eine Zahl ist.
Der Vorgabewert wird aus dem Dialekt in der Hibernate-Konfiguration ermittelt. |
)
|
|
| @javax.persistence.Transient |
@javax.persistence.Transient
|
definiert, dass ein Attribut nicht "gemappt" ist |
@Transient
private String transientField;
|
| @javax.persistence.Basic |
@javax.persistence.Basic(
|
erlaubt, für ein einzelnes Attribut festzulegen, ob es LAZY geladen werden soll |
fetch=FetchType.EAGER,
|
Vorgabewert: EAGER; EAGER bedeutet, dass das Attribut sofort geladen wird, wenn das Objekt aus der Datenbank geholt wird. LAZY lädt ein Attribut erst, wenn auf das Feld zugegriffen wird. Das ist interessant für BLOB- und CLOB-Attribute. Eine Voraussetzung für LAZY Loading auf Attributebene ist Bytecode-Instrumentation (siehe Abschnitt 2.5, "Fortgeschrittene Möglichkeiten"). |
optional=true
|
Ein Hinweis für Hibernate, ob ein Attribut Null sein kann. |
)
|
|
| @javax.persistence.Lob |
@javax.persistence.Lob
|
definiert, dass ein Attribut ein Large object type ist; abhängig vom Java-Typen wird ein CLOB (character large object) oder ein BLOB (binary large object) verwendet;
Wichtige Hinweise insbesondere zu Oracle gibt Abschnitt 2.5.11, "Lob mit Oracle und PostgreSQL". |
| @javax.persistence.Temporal |
@javax.persistence.Temporal(
|
definiert präzise eine zeitbezogene Tabellenspalte (Datum, Uhrzeit oder Zeitstempel) |
value=TemporalType.DATE
|
mögliche Werte: DATE, TIME, TIMESTAMP, NONE |
)
|
|
@Temporal(value=TemporalType.DATE)
private Date dateField;
|
| @javax.persistence.Enumerated |
@javax.persistence.Enumerated(
|
beschreibt ein Attribut als Enum-Typen. |
value = EnumType.STRING
|
mögliche Werte sind: EnumType.STRING oder EnumType.ORDINAL
STRING bewirkt, dass Hibernate eine Tabellenspalte vom Typ char erzeugt, die den Enum-Typen als Zeichenfolge enthält: ForestType.JUNGLE = Spaltenwert JUNGLE.
ORDINAL bewirkt, dass Hibernate eine Tabellenspalte vom Typ Integer erzeugt. Für jeden Typ wird eine Zahl gespeichert. Bei diesem Ansatz können Sie neue Typen nur am Ende einfügen, da sonst die Zuordnung von Zahl zu Typ durcheinander gerät. |
)
|
|
public enum ForestType {JUNGLE, FOREST, NORDIC}
@Enumerated(EnumType.STRING)
private ForestType forestType;
|
| @javax.persistence.Version |
@javax.persistence.Version
|
definiert eine Versionsspalte, die im Rahmen von Optimistic Locking verwendet wird (siehe Abschnitt 2.5.1, "Byte Code Instrumentation").
Die Annotation kann Attributen mit einem der folgenden Java-Typen zugeordnet werden: int, Integer, short, Short, long, Long, java.util.Date.
Sie können nur eine Versionsspalte pro Klasse verwenden und sollten diese auch nicht selber setzen. Versionsspalten müssen ferner in der Primärtabelle stehen (siehe Annotation @SecondaryTable).
Ich empfehle Ihnen, Attribute vom Typ int oder long zu verwenden. Wenn Sie die Serverzeit ändern oder Ihr Server sehr schnell ist, kann es mit dem Typen java.util.Date Schwierigkeiten geben. |
@Version
private Long version;
|
| @javax.persistence.AttributeOverride |
@javax.persistence.
AttributeOverride(
|
überschreibt die Spaltendefinition aus einer Oberklasse oder einem Embedded Object. |
name = "color",
|
Attribut der Klasse |
column = @Column(name = "pullover_column")
|
Spaltendefinition; siehe @Column Annotation |
)
|
Beispiel: de.laliluna.component.simple.Sheep |
@Embedded
@AttributeOverride(name = "color", column = @Column(name = "pullover_column"))
private Pullover pullover;
|
| @javax.persistence.AttributeOverrides |
@javax.persistence.
AttributeOverrides(
|
überschreibt mehrere Spaltendefinitionen aus einer Oberklasse oder einem Embedded Object. |
value={@AttributeOverride(...), @AttributeOverride(...)}
|
Array von @AttributeOverride |
)
|
|
@AttributeOverrides({@AttributeOverride(name = "color",
column = @Column(name = "pullover_column"))})
|
| @org.hibernate.annotations.Formula |
@org.hibernate.annotations.
Formula(
|
wird verwendet, um durch die Datenbank eine Formel berechnen zu lassen; das Attribut kann nur gelesen und nicht geschrieben werden. |
value="10 * table_column + 5"
|
eine Formel |
)
|
|
@Formula("10 * id + 5")
public Integer formula;
|
4 Annotations für Beziehungen
| @javax.persistence.OneToOne |
@javax.persistence.OneToOne(
|
definiert eine 1:1-Beziehung.
Beispiel im Package de.laliluna.relation.one2one |
targetEntity = Invoice1.class,
|
definiert die andere Seite der Beziehung; die Angabe ist gewöhnlich nicht erforderlich, da die andere Seite der Beziehung von Hibernate aus dem Java-Typen erraten wird. |
cascade = {CascadeType.ALL},
|
Array von CascadeType – siehe Abschnitt 4.5.4, "Cascasding". |
fetch=FetchType.EAGER,
|
legt fest, ob die andere Seite der Beziehung erst beim Zugriff (LAZY) oder sofort geladen wird (EAGER); für 1:1-Beziehungen ist der Vorgabewert EAGER. |
optional=true,
|
Ist der Wert false, erzeugt Hibernate beim Erstellen der Tabelle einen Not-Null-Constraint. Wenn Cascading mit der Einstellung DELETE-ORPHAN konfiguriert ist, wird die andere Klasse gelöscht, wenn die Beziehung getrennt wird. |
mappedBy="otherSideProperty"
|
legt fest, dass in einer bidirektionalen Beziehung die andere Seite die Beziehung verwaltet. |
)
|
|
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
...... snip .........
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "invoice_id")
private Invoice1 invoice;
|
| @javax.persistence.OneToMany |
@javax.persistence.OneToMany(
|
definiert eine 1:n-Beziehung.
Beispiel im Package de.laliluna.relation.one2many |
targetEntity = Invoice1.class,
|
definiert die andere Seite der Beziehung; die Angabe ist gewöhnlich nicht erforderlich, da die andere Seite der Beziehung von Hibernate aus dem Java-Typen erraten wird. |
cascade = {CascadeType.ALL},
|
Array von CascadeType – siehe Abschnitt 4.5.4, "Cascasding" |
fetch=FetchType.LAZY,
|
legt fest, ob die andere Seite der Beziehung erst beim Zugriff (LAZY) oder sofort geladen wird (EAGER); für 1:n-Beziehungen ist der Vorgabewert LAZY. |
mappedBy="otherSideProperty"
|
legt fest, dass in einer bidirektionalen Beziehung die andere Seite die Beziehung verwaltet. |
)
|
|
@OneToMany
@JoinColumn(name="club_id", nullable=false)
private Set<JavaClubMember1> members = new HashSet<JavaClubMember1>();
|
| @javax.persistence.ManyToOne |
@javax.persistence.ManyToOne(
|
definiert eine n:1-Beziehung.
Beispiel im Package de.laliluna.relation.one2many |
targetEntity = Invoice1.class,
|
definiert die andere Seite der Beziehung; die Angabe ist gewöhnlich nicht erforderlich, da die andere Seite der Beziehung von Hibernate aus dem Java-Typen erraten wird. |
cascade = {CascadeType.ALL},
|
Array von CascadeType – siehe Abschnitt 4.5.4, "Cascasding" |
fetch=FetchType.EAGER,
|
legt fest, ob die andere Seite der Beziehung erst beim Zugriff (LAZY) oder sofort geladen wird (EAGER); für n:1-Beziehungen ist der Vorgabewert EAGER. |
optional=true,
|
Ist der Wert false, erzeugt Hibernate beim Erstellen der Tabelle einen Not-Null-Constraint. Wenn Cascading mit der Einstellung DELETE-ORPHAN konfiguriert ist, wird die andere Klasse gelöscht, wenn die Beziehung getrennt wird. |
)
|
|
@ManyToOne
@JoinColumn(name = "club_id", nullable = false)
private JavaClub3 club;
|
| @javax.persistence.ManyToMany |
@javax.persistence.ManyToMany(
|
definiert eine m:n-Beziehung.
Beispiel im Package de.laliluna.relation.many2many |
targetEntity = Invoice1.class,
|
definiert die andere Seite der Beziehung; die Angabe ist gewöhnlich nicht erforderlich, da die andere Seite der Beziehung von Hibernate aus dem generischen Java-Typen erraten wird. |
cascade = {CascadeType.ALL},
|
Array von CascadeType – siehe Abschnitt 4.5.4, "Cascasding" |
fetch=FetchType.EAGER,
|
legt fest, ob die andere Seite der Beziehung erst beim Zugriff (LAZY) oder sofort geladen wird (EAGER); für m:n-Beziehungen ist der Vorgabewert LAZY. |
mappedBy="otherSideProperty"
|
legt fest, dass in einer bidirektionalen Beziehung die andere Seite die Beziehung verwaltet. |
)
|
|
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "concert_visitor_2", joinColumns =
{ @JoinColumn(name = "concert_id") },
inverseJoinColumns = { @JoinColumn(name = "visitor_id") })
private List<Visitor2> visitors = new ArrayList<Visitor2>();
|
5 Annotations für Komponenten
| @javax.persistence.Embedded |
@javax.persistence.Embedded
|
legt fest, dass eine Klasse als Komponente eingebunden wird und in der gleichen Tabelle gespeichert wird.
Hinweis: In einer neueren EJB-Implementierung hat diese Annotation ein Array von @AttributeOverride. In Hibernate 3.3 stand diese Möglichkeit noch nicht zur Verfügung.
Beispiel im Java-Package de.laliluna.component.simple.Sheep |
@Embedded
@AttributeOverrides({@AttributeOverride(name = "color",
column = @Column(name = "pullover_column"))})
private Pullover pullover;
|
| @org.hibernate.annotations.CollectionOfElements |
@org.hibernate.annotations.
CollectionOfElements(
|
Hibernate-Erweiterung, um eine Map, ein Set oder eine List von Objekten als Komponente zu speichern. |
targetElement=WinterAddress.
class,
|
definiert die Klasse der Komponente; die Angabe ist gewöhnlich nicht erforderlich, da die andere Seite der Beziehung von Hibernate aus dem generischen Java-Typen erraten wird. |
fetch=FetchType.EAGER
|
legt fest, ob die Komponente erst beim Zugriff (LAZY) oder sofort geladen wird (EAGER); Vorgabewert ist LAZY. |
)
|
Beispiel im Java-Package de.laliluna.component.collection1, de.laliluna.component.collection2 |
@CollectionOfElements
@JoinColumn(name = "hedgehog_id")
@IndexColumn(name = "list_index")
private List<WinterAddress> addresses = new ArrayList<WinterAddress>();
|
| @javax.persistence.Embeddable |
@javax.persistence.Embeddable
|
legt fest, dass eine Klasse als Komponente eingebunden werden kann.
Beispiel im Java-Package de.laliluna.component.simple.Sheep |
| @org.hibernate.annotations.Parent |
@org.hibernate.annotations.
Parent
|
kann in einer Komponente verwendet werden, wenn ein Attribut die Oberklasse referenziert.
Beispiel im Java-Package de.laliluna.component.collection2.PizzaClient |
import org.hibernate.annotations.Parent;
@Embeddable
public class DeliveryAddress implements Serializable {
@Parent
private PizzaClient client;
|
|