我有一个标记为@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);
}
}
...然后按如下方式注释父ID的ID字段......
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "CustomIdGenerator")
@GenericGenerator(name = "CustomIdGenerator", strategy = "com.foo.CustomIdGenerator")
private Long id;
这会导致序列表或本机序列用于ID生成,但是会延迟到实体上设置的ID。
答案 0 :(得分:1)
编辑:工作回答:好的,现在我看到没有办法以纯JPA方式执行此操作,但如果您正在使用Hibernate,您可能会尝试编写自定义SequenceGenerator
,因为它是{{ 3}}。基本上,只有在未设置id时,它才会生成一个值(调用super.generate()
)。