【发布时间】:2020-04-08 01:40:31
【问题描述】:
我正在开发 Springboot 应用程序。
问题陈述:
我正在使用 sequence 来生成 id。
当我第一次点击控制器时,没有异常,数据成功保存到数据库中。
但是当我第二次点击控制器时,我得到了:
**duplicate key violates unique constraint, Detail:
Key(id)=(100) already exits.** <br/>
但是 id = 100 之前已经插入了 10 条记录。
我有以下 POJO:
package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "student_tbl", schema = "user")
public class Student {
@Id
private Integer id;
private String name;
private String className;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
学生资料库
package com.example.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface StudentRepository extends JpaRepository<Student, Integer> {
@Query(value = "select nextval('user.student_id')", nativeQuery = true)
Integer createId();
}
坚持学生
package com.example.demo;
import java.util.List;
import java.util.stream.IntStream;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersistStudent {
@Autowired
private StudentRepository studentRepository;
@PersistenceContext
EntityManager entityManager;
@Transactional
public void persistStudent(List<Student> students) {
try {
IntStream.range(0, students.size()).forEach(index -> {
if (students.size() == index || index % 100 == 0) {
entityManager.flush();
entityManager.clear();
}
entityManager.persist(students.get(index));
});
} catch (Exception e) {
System.out.println("Exception:: " + e);
}
}
}
控制器
package com.example.demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class StudentContoller {
@Autowired
private PersistStudent persistStudent;
@Autowired
private StudentRepository studentRepo;
@GetMapping(value = "/save")
public void saveStudent() {
List<Student> students = new ArrayList<Student>();
Student stu = new Student();
stu.setClassName("VII");
stu.setName("John Doe");
stu.setId(studentRepo.createId());
students.add(stu);
persistStudent.persistStudent(students);
}
}
请帮忙。
【问题讨论】:
-
如果只有 JPA 提供了一种基于序列自动生成 ID 的方法。哦等等...docs.jboss.org/hibernate/orm/current/userguide/html_single/…
-
请显示该表的DDL和该表的pk序列的DDL。
-
@JBNizet:其实分配id是有逻辑的,即if(id !=null){generate id from sequence},否则根本不生成id。
-
这是一个糟糕的主意:现在每次序列生成一个之前选择的 ID 而不从序列中获取它时,你都会得到一个异常。这可能正是这里发生的事情,以及您问这个问题的原因:您生成了一个 ID 却没有从序列中获取它。所以当然如果序列生成相同的 ID,你会得到一个异常。
-
但是序列怎么会生成已经生成的id。该序列将始终生成一个新的 id。例如,如果最后生成的 id 是 101,那么 next 将是 102。我看不到这里发生的错误。
标签: java spring postgresql spring-boot jpa