没有尝试这个,但根据 Hibernate 的 api,创建自定义实现应该不会变得复杂身份生成器.
它是生成方法 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,您应该实现IdentifierGenerator界面。
正如 Hibernate 所接受的那样,对于任何“jpa 兼容”提供者来说,应该仍然可以以更通用的方式创建它。根据JPA api中生成值您可以提供自定义生成器的注释。这意味着您可以提供自定义生成器的名称,并且应该为每个 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"
to BaseEntity
任一个班级id
场或BaseEntity
班级水平应该足够)。
在 EclipseLink 中,我发现您可以通过以下方式执行此操作生成值注解并通过 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 生成器的方法,因此如果您想支持所有提供程序,则需要为每个提供程序实现并注册自定义生成策略。