在 JPA @GeneratedValue列中手动指定主键的值
我有一个实体,它有一个主键/ id字段,如下所示:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
这很有效。我正在使用EclipseLink创建DDL-Schema,并且列是正确创建的,如下所示:
`id` bigint(20) NOT NULL AUTO_INCREMENT
但是,我有几个实体,我确实想自己指定PK(这是一个小应用程序,将数据从旧数据库传输到我们正在构建的新数据库)。如果我指定POJO的ID(使用)并保留它,EclipseLink不会保存它(即记录被保存,但id是由eclipseLink自动生成的)。setId(Long id)
有没有办法手动指定具有@GeneratedValue的列的值?
以下是关于这个问题的一些想法:
我试图通过根本不使用@GeneratedValue来解决此问题,而只是手动定义要AUTO_INCREMENTed列。然而,这迫使我总是手动提供ID,因为EclipseLink会验证主键(因此它可能不是空,零或负数)。异常消息显示我应该指定eclipselink.id_validation,但是这似乎没有任何区别(我注释了,但仍然得到了相同的消息)。@PrimaryKey(validation = IdValidation.NONE)
澄清:我使用EclipseLink(2.4.0)作为持久性提供程序,我无法摆脱它(项目的大部分内容取决于eclipselink特定的查询提示,注释和类)。
编辑(回应答案):
自定义排序:我试图实现我自己的排序。我尝试了DefaultSequence的子类化,但EclipseLink会告诉我。但是我已经检查过了:类在类路径上。Internal Exception: org.eclipse.persistence.platform.database.MySQLPlatform could not be found
所以我子类化了另一个类,NativeSequence:
public class MyNativeSequence extends NativeSequence {
public MyNativeSequence() {
super();
}
public MyNativeSequence(final String name) {
super(name);
}
@Override
public boolean shouldAlwaysOverrideExistingValue() {
return false;
}
@Override
public boolean shouldAlwaysOverrideExistingValue(final String seqName) {
return false;
}
}
但是,我得到的是以下内容:
javax.persistence.RollbackException: Exception [EclipseLink-7197] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone [de.dfv.datenbank.domain.Mitarbeiter[ id=null ]], primary key [null]. Set descriptors IdValidation or the "eclipselink.id-validation" property.
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
...
Caused by: Exception [EclipseLink-7197] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Null or zero primary key encountered in unit of work clone [de.dfv.datenbank.domain.Mitarbeiter[ id=null ]], primary key [null]. Set descriptors IdValidation or the "eclipselink.id-validation" property.
at org.eclipse.persistence.exceptions.ValidationException.nullPrimaryKeyInUnitOfWorkClone(ValidationException.java:1451)
...
(为清晰起见,缩短了堆栈跟踪)。这与我之前得到的信息相同。难道不应该子类 NativeSequence 吗?如果是这样,我不知道为Sequence或StandardSequence中的抽象方法实现什么。
还值得注意的是,只需对类进行子类化(而不覆盖任何方法)即可按预期方式工作。但是,将 false 换入根本不会生成单个值(我单步执行了程序,没有被调用一次)。shouldAlwaysOverrideExistingValue(...)
getGeneratedValue()
此外,当我在事务中插入8个特定类型的实体时,它会导致数据库中有11条记录(到底是什么?!
编辑 (2012-09-01):我仍然没有问题的解决方案,实现我自己的序列并没有解决它。我需要的是一种方法,能够不显式设置Id(因此将自动生成)并能够显式设置Id(因此它将用于在数据库中创建记录)。
我试图将列定义为auto_increment自己并省略@GeneratedValue,但是验证将启动,不允许我保存这样的实体。如果我指定一个值 != 0 和 != 零,mysql 将报告重复的主键。
我没有想法和选择可以尝试。任何?(开始赏金)