如何使用相同的自定义 ID 生成器统一多个实体的 @GenericGenerator 声明?
How to unify @GenericGenerator declaration for multiple entities using same custom id generator?
我的项目中有许多实体使用相同的自定义 IdentifierGenerator
使用 SpringDataJPA/Hibernate
生成 @Id
。
示例实体;
@Entity
@Table(name = "CHAIRS")
public class ChairEntity {
@Id
@GeneratedValue(generator = "myGenerator")
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = "myGenerator")
protected String id;
// rest of the entity
}
但我不想对每个实体的每个 id 字段重复 @GenericGenerator
declecation。有没有办法隐藏这个包含难看的硬编码完整 class 名称的注释?
post 脚本
我以前使用 @MappedSuperClass
和 BaseEntity
class 包含 id
字段,但由于某些技术原因我不得不放弃使用这样的超级 class。显然这是这个问题最简单的解决方案。
我想出的解决方案是一个 Java 技巧,我所有的实体都在 a.b.jpa.entity
下,我的生成器在 a.b.jpa.generator
下,因为 @GenericGenerator
可以使用直接在 class 上,我为 a.b.jpa.entity
包创建了一个 package-info.java
,包含以下内容;
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = MyGenerator.generatorName)
package a.b.jpa.entity;
import org.hibernate.annotations.GenericGenerator;
import a.b.jpa.generator.MyGenerator;
这用 @GenericGenerator
注释了 a.b.jpa.entity
下的所有 classes,这是我的问题的完美解决方案。本质上使其适用于所有实体。
生成器代码;
public class MyGenerator implements IdentifierGenerator {
public static final String generatorName = "myGenerator";
@Override
public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object object) throws HibernateException {
return GeneratorUtil.generate();
}
}
以及处于以下状态的实体;
@Entity
@Table(name = "CHAIRS")
public class ChairEntity {
@Id
@GeneratedValue(generator = MyGenerator.generatorName)
protected String id;
// rest of the entity
}
成功了,现在 @GenericGenerator
被定义在一个位置,向我的所有实体提供 MyGenerator
详细信息,如果他们中的任何一个想要使用它,他们只需利用 @GeneratedValue
.
您也可以使用 @MappedSuperclass
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(generator = "myGenerator")
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = "myGenerator")
protected String id;
// getters, setters here
}
然后,您的实体可以扩展它:
@Entity
@Table(name = "CHAIRS")
public class ChairEntity extends BaseEntity { ... }
我的项目中有许多实体使用相同的自定义 IdentifierGenerator
使用 SpringDataJPA/Hibernate
生成 @Id
。
示例实体;
@Entity
@Table(name = "CHAIRS")
public class ChairEntity {
@Id
@GeneratedValue(generator = "myGenerator")
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = "myGenerator")
protected String id;
// rest of the entity
}
但我不想对每个实体的每个 id 字段重复 @GenericGenerator
declecation。有没有办法隐藏这个包含难看的硬编码完整 class 名称的注释?
post 脚本
我以前使用 @MappedSuperClass
和 BaseEntity
class 包含 id
字段,但由于某些技术原因我不得不放弃使用这样的超级 class。显然这是这个问题最简单的解决方案。
我想出的解决方案是一个 Java 技巧,我所有的实体都在 a.b.jpa.entity
下,我的生成器在 a.b.jpa.generator
下,因为 @GenericGenerator
可以使用直接在 class 上,我为 a.b.jpa.entity
包创建了一个 package-info.java
,包含以下内容;
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = MyGenerator.generatorName)
package a.b.jpa.entity;
import org.hibernate.annotations.GenericGenerator;
import a.b.jpa.generator.MyGenerator;
这用 @GenericGenerator
注释了 a.b.jpa.entity
下的所有 classes,这是我的问题的完美解决方案。本质上使其适用于所有实体。
生成器代码;
public class MyGenerator implements IdentifierGenerator {
public static final String generatorName = "myGenerator";
@Override
public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object object) throws HibernateException {
return GeneratorUtil.generate();
}
}
以及处于以下状态的实体;
@Entity
@Table(name = "CHAIRS")
public class ChairEntity {
@Id
@GeneratedValue(generator = MyGenerator.generatorName)
protected String id;
// rest of the entity
}
成功了,现在 @GenericGenerator
被定义在一个位置,向我的所有实体提供 MyGenerator
详细信息,如果他们中的任何一个想要使用它,他们只需利用 @GeneratedValue
.
您也可以使用 @MappedSuperclass
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(generator = "myGenerator")
@GenericGenerator(strategy = "a.b.jpa.generator.MyGenerator", name = "myGenerator")
protected String id;
// getters, setters here
}
然后,您的实体可以扩展它:
@Entity
@Table(name = "CHAIRS")
public class ChairEntity extends BaseEntity { ... }