Java JPA:覆盖自动生成的ID
我在Employee类中有以下定义Java JPA:覆盖自动生成的ID,java,hibernate,jpa,Java,Hibernate,Jpa,我在Employee类中有以下定义 @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "employee_id") private Integer employeeId; 现在我想导入具有现有员工ID的现有员工。即使在保存之前设置了员工ID,也会忽略分配的ID并存储自动递增的ID。我们如何克服这一点 我对复合键有类似的问题,已经解释过了,您不能覆盖它。首先,JPA没有提供这样做的方法。第二个
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "employee_id")
private Integer employeeId;
现在我想导入具有现有员工ID的现有员工。即使在保存之前设置了员工ID,也会忽略分配的ID并存储自动递增的ID。我们如何克服这一点
我对复合键有类似的问题,已经解释过了,您不能覆盖它。首先,JPA没有提供这样做的方法。第二个问题是GenerationType.AUTO可以生成这样一个列类型,它不会通过SQL语句接受用户指定的值
手动执行数据导入,不要尝试将应用程序本身用作导入工具。在这种情况下,最好使用@MappedSuperclass
@MappedSuperclass
public AbstractEmployee {
// declare all properties, getters, setters except for the id
}
@Entity
@Table(name="EMPLOYEE")
public class Employee extends AbstractEmployee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "employee_id")
private Integer employeeId;
...
}
@Entity
@Table(name="EMPLOYEE")
public class EmployeeWithAssignedId extends AbstractEmployee {
@Id
@Column(name = "employee_id")
private Integer employeeId;
...
}
因此,当您想要手动分配ID时,请使用第二个类。我没有测试过这个,但我相信它应该适合你的情况。我不相信JPA中有任何规则规定两个类不能有相同的表名:)我编写了自己的生成器来解决这个问题
public class UseExistingIdOtherwiseGenerateUsingIdentity extends IdentityGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
Serializable id = session.getEntityPersister(null, object).getClassMetadata().getIdentifier(object, session);
return id != null ? id : super.generate(session, object);
}
}
并这样使用:(替换包名)
您必须重写getEmployeeId()方法并在此方法上使用注释
在这种情况下,JPA对类中的所有字段使用getter方法,您必须移动getter方法上的其他注释(手动导入以外的任何方式?我不能手动执行,因为还有一些预处理。在这种情况下,我必须编写插入代码:(@sidgate也许您可以禁用自动生成,进行导入,然后重新启用它?这是可能的,但这取决于列定义(或者GenerationType.AUTO在数据库中的实际材质化方式)id的禁用/启用很简单。请参考下面的答案。我可以通过拥有自己的生成器来解决此问题。您是否看到此实现存在任何问题?显然,一些JPA实现(例如DataNucleus JPA)可能会提供一种机制,仅当该字段为空时才允许自动生成,但JPA作为规范不允许。我的模型类是从Roo生成的。修改这些类会很麻烦。我实现了一个新的生成器,如下所述。请尝试在您的问题中提及这些内容,因为这是重要的信息这可能会改变人们的答案。如果
id
列的类型是UUID,则应将IdentityGenerator
更改为UUIDGenerator
。
@Id
@GenericGenerator(name = "UseExistingIdOtherwiseGenerateUsingIdentity", strategy = "{package}.UseExistingIdOtherwiseGenerateUsingIdentity")
@GeneratedValue(generator = "UseExistingIdOtherwiseGenerateUsingIdentity")
@Column(unique = true, nullable = false)
protected Integer id;