是否可以删除应用于子类中@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()
)。
我有一个抽象基础 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()
)。