Spring Boot中JpaRepository无法保存实体至SQL Server,无错误日志
针对你遇到的JPA保存数据到SQL Server无反应、无错误日志的问题,以下是逐一排查和解决的方向:
1. 修正Flyway配置错误
你的pom.xml中Flyway Maven插件配置的URL是MySQL协议,但实际使用的是SQL Server,这会导致Flyway无法正确连接目标数据库执行迁移,甚至可能导致目标表未创建:
<!-- 原错误配置 --> <url>jdbc:mysql://localhost:1460/bon_dsv</url> <!-- 修改为SQL Server URL --> <url>jdbc:sqlserver://localhost:1460;databaseName=bon_dsv;sendStringParametersAsUnicode=false</url>
同时确保src/main/resources/db/migrations/sql下的迁移脚本是针对SQL Server编写的,且表t1209Clt已正确创建。
2. 调整日志级别,开启SQL执行日志
当前日志只输出info和trace,但trace级别默认可能未开启,导致看不到SQL执行细节。修改application.yml添加日志配置:
logging: level: org.springframework.data.jpa: DEBUG org.hibernate.SQL: DEBUG org.hibernate.type.descriptor.sql.BasicBinder: TRACE
这样可以看到Hibernate生成的SQL语句和参数绑定情况,确认是否真的执行了插入操作。
3. 检查MapStruct映射是否正确
确认ClienteMapper的requestToModel方法是否正确将IncluirClienteRequestDTO的字段映射到Cliente实体,特别是主键id字段——如果id为空,SQL Server可能因为主键非空约束导致插入失败,但未开启日志则看不到错误。可以在salvarCliente方法中添加日志打印映射后的实体:
private Cliente salvarCliente(IncluirClienteRequestDTO request) { Cliente cliente = mapper.requestToModel(request); log.debug("映射后的Cliente实体:{}", cliente); // 添加这行日志 return repository.save(cliente); }
4. 修正Maven编译器插件的Java版本冲突
你的pom.xml中java.version配置为17,但maven-compiler-plugin的source和target设置为1.8,这会导致编译后的字节码与运行环境不兼容,可能引发隐性问题:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <!-- 修改为与java.version一致的17 --> <source>17</source> <target>17</target> <!-- 其他配置保持不变 --> </configuration> </plugin>
5. 捕获隐性异常,确认事务行为
虽然ClienteService加了@Transactional,但可以显式捕获可能的隐性异常,确认事务是否正常提交:
@Override public boolean incluirCliente(IncluirClienteRequestDTO request) { log.info("Incluindo cliente na base de dados..."); log.trace("Incluir cliente: {}", request); try { Cliente saved = salvarCliente(request); log.info("Cliente已保存,ID:{}", saved.getId()); return true; } catch (Exception e) { log.error("保存Cliente失败", e); return false; } }
6. 排除H2数据库干扰
你的依赖中包含H2数据库,虽然配置了SQL Server,但Spring Boot可能在某些情况下自动切换到H2。可以移除H2依赖:
<!-- 移除H2依赖 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.220</version> <scope>runtime</scope> </dependency>
7. 检查JPA save方法的行为
如果request中的id已经存在于数据库中,repository.save(cliente)会执行更新操作而非插入,导致你以为数据没保存。可以在保存前查询该ID是否存在:
private Cliente salvarCliente(IncluirClienteRequestDTO request) { Cliente cliente = mapper.requestToModel(request); if(repository.existsById(cliente.getId())) { log.warn("Cliente ID {}已存在,将执行更新操作", cliente.getId()); } return repository.save(cliente); }
内容的提问来源于stack exchange,提问作者Henrique Bon

