如何使用相同的自定义 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 脚本
我以前使用 @MappedSuperClassBaseEntity 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 { ... }