如何在带有组合PK的表中插入带有JPA存储库的多条记录,并且其中一个自动递增?

时间:2019-09-20 03:05:15

标签: java hibernate spring-boot spring-data-jpa spring-data

我正在使用Spring Boot构建一个控制器来存储记录列表,但是将要存储记录的表具有一个组合的PK(两个字段),并且其中一个字段的字段是auto_incrementable,我的实体是定义如下:

TaskPK.java

@Embeddable
public class TaskPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="taskflow_template_task_id", unique=true, nullable=false)
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer taskflowTemplateTaskId;

    @Column(name="taskflow_template_id", insertable=false, updatable=false, unique=true, nullable=false)
    private Integer taskflowTemplateId;

// Getters, setters and constructors
}

在此PK中,taskflowTemplateTaskId是一个AI字段

Task.java

public class Task extends BaseEntity implements Serializable, Persistable<TaskPK> {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private TaskPK id = new TaskPK();

    @Column(name="task_id")
    private Integer taskId;

    @Column(name="display_order", nullable=false)
    private int displayOrder;

    //bi-directional many-to-one association to TaskflowTemplate
    @ManyToOne
    @JoinColumn(name="taskflow_template_id", nullable=false, insertable=false, updatable=false)
    private TaskflowTemplate taskflowTemplate;

    @Override
    public boolean isNew() {
        return (id.getTaskflowTemplateTaskId() == null || id.getTaskflowTemplateId() == null);
    }

任务实体具有关联的Spring数据JPA存储库,而无需任何自定义查询

最后,这是我用来存储数据的代码,是一个从控制器调用的简单函数

@Transactional
public void createTask(List<Task> tasks){
    taskRepository.saveAll(tasks)
}

我正在接收的数据用以下JSON表示:

[
  {
    "displayOrder": 1,
    "taskId": 1,
    "id": {
        "taskflowTemplateId" : "1"
     }
  },
  {
    "displayOrder": 2,
    "taskId": 2,
    "id": {
        "taskflowTemplateId" : "1"
     }
  },
  {
    "displayOrder": 3,
    "taskId": 3,
    "id": {
        "taskflowTemplateId" : "1"
     }
  }
]

运行此代码时,出现此异常

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.test.taskmaster.entity.Task#TaskPK(taskflowTemplateTaskId=null, taskflowTemplateId=1)]

因此,我猜测休眠状态不是正在生成字段taskflowTemplateTaskId,而是以null形式发送。当仅创建一条记录时,这会很好,因为在数据库中AI字段将null替换为null,但是当我尝试插入所有具有null taskflowTemplateTaskId的记录列表时,因为我希望生成该记录,就会发生此错误。

我尝试在循环中使用save和saveAndFlush均未成功,我也尝试了不同类型的GenerationType甚至使用@Generated(GenerationTime)。

1 个答案:

答案 0 :(得分:0)

这意味着您正在尝试使用对同一对象的引用在表中保存多行。

@Column(name="taskflow_template_task_id", unique=true, nullable=false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer taskflowTemplateTaskId;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="taskflow_template_task_id", unique = true, nullable = false)
private Integer taskflowTemplateTaskId;