Hibernate bringt von Haus aus schon einige Generatoren für die ID mit. Manchmal sind die Anforderungen an die ID aber spezieller und muß einen eigenen Generator für die Hibernate ID anlegen.
In der Java-Klasse, die mit Hibernate persistier werden soll, kann man wie folgt mit JPA annotieren:
@Id @Column (name="MY_ID", length=16) @GeneratedValue (generator="GenAccId" ) @GenericGenerator(name="GenAccId", strategy = "cc.raupach.MyNumberGenerator") private String myId;
Nun kann man die eigentliche Java-Klasse anlegen, die den ID-Generator enthält. Dazu implementier man das von Hibernate bereitgestellte Interface “IdentifierGenerator“:
public class MyNumberGenerator implements IdentifierGenerator
{
static String query ="SELECT MySpezialSequence.nextval as myid FROM dual";
public Serializable generate(SessionImplementor session, Object object) throws HibernateException
{
// hier wird eine eigene Session geöffnet und darin eine eigene Transaktion für Hibernate angelegt
// um z.B. in einer DB-Abfrage eine ID zu gewinnen.
Session sessionX=session.getFactory().openSession();
sessionX.beginTransaction();
BigDecimal seqNumber = (BigDecimal) sessionX.createSQLQuery (query).uniqueResult();
sessionX.getTransaction().commit();
String seqNumberStr = seqNumber.toString();
String id = "ABCD_" + seqNumberStr;
return id;
}
}
Der Generator erzeugt in diesem Fall eine numerische ID aus einer eigenen Sequence, die ein Prefix “ABCD_” hat. Man kann mit der Methode im Prinzip alles zurückgeben was man will – nur unique sollte es natürlich sein. Über den Parameter “object” hat man auch Zurgriff auf das zu persistierende Object und kann darauf zugreifen und die generierung der ID so z.B. von bestimmten Attributen des Objekts abhängig machen und steuern.