Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA:覆盖自动生成的ID_Java_Hibernate_Jpa - Fatal编程技术网

Java JPA:覆盖自动生成的ID

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没有提供这样做的方法。第二个

我在Employee类中有以下定义

@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;