是否可以删除应用于子类中@MappedSuperclass 中的@Id 列的@GeneratedValue 字段注释?

Is it possible to remove an @GeneratedValue field annotation applied to an @Id column in @MappedSuperclass in a subclass?

我有一个抽象基础 class 标记为 @MappedSuperclass,其 ID 属性 设置了 @Id @GeneratedValue

我还有一个 @Entity 派生自它需要设置自己的 ID 而不是依赖生成。

我有大量派生实体依赖于 @MappedSuperclass 中设置的 ID,我不想在每个实体中都设置 ID。

我怎样才能避免仅针对这个派生实体的 @GeneratedValue?我希望手动设置 ID 以覆盖生成,但事实并非如此。

id 列的 DDL (HSQL):

id bigint generated by default as identity (start with 1)

根据 http://hsqldb.org/doc/guide/ch02.html#N104B3 id 生成应该只在为 id 列指定空值时发生。

下面是一些示例代码:

@MappedSuperclass
class Parent {
    @Id @GeneratedValue
    private Long id;
}

@Entity
class Child extends Parent
    @PrePersist
    public void prePersist() {
        LOG.info("PrePersist with id #{}", this.id);
    }
}

Child t = new Child();
t.setId(123);

LOG.debug("Creating: Child #{}", t.getId());
childRepository.save(t); // Spring Data JPA Repositories
LOG.debug("Created: Child #{}", t.getId());

// Outputs:
// Creating: Child #123
// PrePersist with id #123 
// Created: Child #1

编辑:

事实证明,默认的@GeneratedValue 策略不允许指定id。数据库将始终生成它们。结果我需要写一个自定义 ID 生成器...

public class CustomIdGenerator extends SequenceStyleGenerator {

    @Override
    public Serializable generate(SessionImplementor session, Object object)
        throws HibernateException {
        Serializable id = session.getEntityPersister(null, object)
            .getClassMetadata().getIdentifier(object, session);
        return id != null ? id : super.generate(session, object);
    }

}

...然后将parent的ID字段注释如下...

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "CustomIdGenerator")
@GenericGenerator(name = "CustomIdGenerator", strategy = "com.foo.CustomIdGenerator")
private Long id;

这会导致序列 table 或本机序列用于 ID 生成,但遵从实体上设置的 ID。

编辑:工作答案:好的,现在我知道没有办法以纯 JPA 方式执行此操作,但如果您使用的是 Hibernate,您可能会尝试按原样编写自定义 SequenceGenerator described here。基本上,它只会在未设置 id 时生成一个值(调用 super.generate())。