これを試しませんでしたが、HibernateのAPIによると、 IdentityGenerator 。
生成メソッドgetsと値を生成するオブジェクトであるため、idフィールドのタイプを確認し、主キーに適切な値を返すことができます。
public class DynamicGenerator implements IdentityGenerator
public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {
if (shouldUseAutoincrementStartegy(object)) { // basing on object detect if this should be autoincrement or not, for example inspect the type of id field by using reflection - if the type is Integer use IdentityGenerator, otherwise another generator
return new IdentityGenerator().generate(seession, object)
} else { // else if (shouldUseTextKey)
String textKey = generateKey(session, object); // generate key for your object
// you can of course connect to database here and execute statements if you need:
// Connection connection = session.connection();
// PreparedStatement ps = connection.prepareStatement("SELECT nextkey from text_keys_table");
// (...)
return textKey;
}
}
}
これを生成戦略として使用するだけです:
@MappedSuperclass
public abstract class BaseEntity<T> implements Serializable {
@Id
@GenericGenerator(name="seq_id", strategy="my.package.DynamicGenerator")
protected T id;
}
Hibernate 4の場合、 IdentityGenerator
インターフェイス。
上記はHibernateで受け入れられているため、「jpa準拠」プロバイダーの場合はより一般的な方法で作成できるはずです。 GeneratedValue のJPAAPIによると カスタムジェネレーターを提供できるアノテーション。これは、カスタムジェネレーターの名前を指定できることを意味し、jpaプロバイダーごとにこのジェネレーターを実装する必要があります。
これは、BaseEntityに次のアノテーションを付ける必要があることを意味します
@MappedSuperclass
public abstract class BaseEntity<T> implements Serializable {
@Id
@GeneratedValue(generator="my-custom-generator")
protected T id;
}
次に、使用するjpaプロバイダーごとに「my-custom-generator」という名前のカスタムジェネレーターを登録する必要があります。
Hibernateの場合、これは前に示したように@GenericGeneratorアノテーションによって確実に実行されます( @GenericGenerator(name ="my-custom-generator"、strategy ="my.package.DynamicGenerator"
を追加) BaseEntity
へ いずれかのid
のクラス フィールドまたはBaseEntity
クラスレベルで十分です。
EclipseLinkでは、GeneratedValueを介してこれを実行できることがわかりました。 a> 注釈とSessionCustomizerを介した登録:
properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER,
"my.custom.CustomIdGenerator");
public class CustomIdGenerator extends Sequence implements SessionCustomizer {
@Override
public Object getGeneratedValue(Accessor accessor,
AbstractSession writeSession, String seqName) {
return "Id"; // generate the id
}
@Override
public Vector getGeneratedVector(Accessor accessor,
AbstractSession writeSession, String seqName, int size) {
return null;
}
@Override
protected void onConnect() {
}
@Override
protected void onDisconnect() {
}
@Override
public boolean shouldAcquireValueAfterInsert() {
return false;
}
@Override
public boolean shouldOverrideExistingValue(String seqName,
Object existingValue) {
return ((String) existingValue).isEmpty();
}
@Override
public boolean shouldUseTransaction() {
return false;
}
@Override
public boolean shouldUsePreallocation() {
return false;
}
public void customize(Session session) throws Exception {
CustomIdGenerator sequence = new CustomIdGenerator ("my-custom-generator");
session.getLogin().addSequence(sequence);
}
}
各プロバイダーはIDジェネレーターを登録する方法を提供する必要があるため、すべてのプロバイダーをサポートする場合は、プロバイダーごとにカスタム生成戦略を実装して登録する必要があります。