2

我的项目中有许多实体使用相同的自定义IdentifierGenerator生成@Id使用SpringDataJPA/Hibernate.

一个示例实体;

@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
}

但我不想@GenericGenerator为每个实体的每个 id 字段重复声明。有没有办法隐藏这个包含丑陋的硬编码完整类名的注释?

post scriptum
我以前使用包含@MappedSuperClass的,但由于一些技术原因,我不得不放弃使用这样的超类。显然,这是解决这个问题的最简单方法。BaseEntityid

4

2 回答 2

3

我想出的解决方案是一个Java技巧,我所有的实体都在a.b.jpa.entity,我的生成器在a.b.jpa.generator,因为@GenericGenerator可以直接在类上使用,所以我创建了一个包含以下内容的package-info.javafor包;a.b.jpa.entity

@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;

这用 注释所有类a.b.jpa.entity@GenericGenerator这是我的问题的完美解决方案。本质上使其可用于所有实体。

生成器的代码;

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.

于 2017-12-22T01:34:51.423 回答
2

你也可以使用@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 { ... }
于 2017-12-22T01:46:05.130 回答