Spring Boot数据未按numb列存入PostgreSQL问题解决
解决方案
1. 修正实体类注解问题
你的User实体存在两个核心问题,直接影响数据存储逻辑:
- timestamp字段注解错误:数据库中该字段由
DEFAULT规则自动生成,不需要JPA参与值的生成,需移除@GeneratedValue并设置字段禁止应用层插入/更新。 - 缺少无参构造函数:JPA要求实体必须有无参构造函数,否则会导致ORM映射异常。
修改后的实体类代码:
import javax.persistence.*; @Entity @Table(name="mydb") public class User { @Id @Column(name = "numb", nullable = false, length = 15) private String numb; @Column(name = "on_off", nullable = false, length = 6) private String on_off; @Column(name = "timestamp", nullable = false, insertable = false, updatable = false) private String timestamp; // 必须添加无参构造函数 public User() {} public User(String numb, String on_off) { this.numb = numb; this.on_off = on_off; } // getter和setter方法 public String getNumb() { return numb; } public void setNumb(String numb) { this.numb = numb; } public String getOn_Off() { return on_off; } public void setOn_Off(String on_off) { this.on_off = on_off; } public String getTimestamp() { return timestamp; } }
2. 调整数据保存逻辑(按需选择)
JPA默认的save()方法会先执行SELECT语句检查主键是否存在,再决定执行INSERT或UPDATE。如果你的业务场景是仅插入新数据,可以通过以下方式跳过前置查询:
方式一:使用EntityManager.persist()
在Service中注入EntityManager,直接调用持久化方法(仅适用于主键不存在的全新实体):
@Autowired private EntityManager entityManager; @Override @Async("asyncExecutor") public CompletableFuture<User> createUser(User user) { System.out.println(Thread.currentThread().getId()+"-----------------------------------"+System.currentTimeMillis()+"-------------inside services"); entityManager.persist(user); entityManager.flush(); // 立即触发SQL执行 return CompletableFuture.completedFuture(user); }
方式二:自定义原生SQL插入方法
在UserRepository中定义原生插入方法,直接绕过JPA的默认逻辑:
public interface UserRepository extends JpaRepository<User, String> { @Modifying @Query(value = "INSERT INTO mydb(numb, on_off) VALUES (:numb, :onOff)", nativeQuery = true) void insertUser(@Param("numb") String numb, @Param("onOff") String onOff); }
然后在Service中调用该方法:
@Override @Async("asyncExecutor") public CompletableFuture<Void> createUser(User user) { System.out.println(Thread.currentThread().getId()+"-----------------------------------"+System.currentTimeMillis()+"-------------inside services"); userRepository.insertUser(user.getNumb(), user.getOn_Off()); return CompletableFuture.completedFuture(null); }
3. 验证效果
修改完成后,执行插入操作时,数据会以numb作为主键正确存入表中,timestamp字段由数据库自动生成。同时检查UserRepository是否正确继承JpaRepository<User, String>(泛型第二个参数为主键类型String)。
内容的提问来源于stack exchange,提问作者Deepak Mathur
相关产品推荐
相关产品推荐

