Spring Data JDBC报错:无法设置id属性,无setter/持久化构造器
Spring Data JDBC问题排查与解决方案
一、Ingredient类id属性无法赋值的问题排查
可能原因及解决步骤:
实体类主键注解缺失或配置错误
Spring Data JDBC需要明确标记主键字段,确保你的Ingredient类给id字段添加了@Id注解:import org.springframework.data.annotation.Id; public class Ingredient { @Id private String id; // 若用自增主键,建议用Integer而非int,允许null // 其他字段、构造方法、getter/setter }如果是数据库自增主键,还需要确保H2表结构中id列设置为自增:
CREATE TABLE ingredient ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, type VARCHAR(50) NOT NULL );Repository接口泛型类型不匹配
确认你的Repository接口泛型第二个参数与id字段类型完全一致:import org.springframework.data.repository.CrudRepository; // 若id是String,泛型第二个参数为String;若是Integer则为Integer public interface IngredientRepository extends CrudRepository<Ingredient, String> { }预加载数据时的id赋值逻辑错误
- 若使用手动指定id(如String类型的业务主键),在
ApplicationRunner中保存数据时必须明确赋值:@Bean ApplicationRunner dataLoader(IngredientRepository repo) { return args -> { repo.save(new Ingredient("FLTO", "Flour Tortilla", Type.WRAP)); repo.save(new Ingredient("GRBF", "Ground Beef", Type.PROTEIN)); }; } - 若使用自增主键,保存时不要手动设置id,让数据库自动生成,实体类id字段需用包装类型(如Integer)并允许为null。
- 若使用手动指定id(如String类型的业务主键),在
二、ApplicationRunner与data.sql的取舍建议
不需要强制删除data.sql,但建议统一数据初始化方式,避免冲突:
- 如果你更倾向于用Java代码实现灵活的初始化逻辑(比如条件插入、依赖Repository方法、复杂数据处理),直接删除
data.sql即可,避免重复插入数据导致主键冲突。 - 若保留
data.sql,需配置spring.sql.init.mode控制执行时机(比如仅在嵌入式数据库初始化时执行),同时确保其数据与ApplicationRunner的插入逻辑不重复。例如在application.properties中添加:spring.sql.init.mode=embedded
内容的提问来源于stack exchange,提问作者Raghav Kavimandan
相关产品推荐
相关产品推荐

