Spring JpaRepository按Sensor ID和所属User ID查询返回NULL问题
问题解决:JPA自定义查询返回NULL但控制台SQL执行正常
问题根源
你编写的自定义查询使用了原生SQL语法,但未在@Query注解中添加nativeQuery=true参数。Spring Data JPA默认会将@Query中的语句当作JPQL(Java Persistence Query Language)解析,而JPQL是基于实体类而非数据库表名的查询语言,因此原本正确的原生SQL会被错误解析,最终导致查询结果为空。
解决方案
方案一:开启原生SQL支持
修改Repository中的查询方法,在@Query注解中指定nativeQuery=true,明确告知JPA这是原生SQL语句:
@Query(value = "SELECT * from sensors LEFT JOIN users_sensors us on sensors.sensor_id = us.sensor_id " + "WHERE sensors.sensor_id = :sensorId AND us.user_id = :userId", nativeQuery = true) Optional<Sensor> findBySensorIdAndUsersId(@Param("sensorId") Long sensorId, @Param("userId") String userId);
方案二:使用JPQL查询(推荐)
改用符合JPA规范的JPQL查询,无需依赖原生SQL,JPA会自动处理实体间的关联关系:
@Query("SELECT s FROM Sensor s JOIN s.users u WHERE s.sensorId = :sensorId AND u.id = :userId") Optional<Sensor> findBySensorIdAndUsersId(@Param("sensorId") Long sensorId, @Param("userId") String userId);
测试代码优化建议
测试类中使用static final修饰的Sensor实例可能导致不同测试方法之间的状态污染,建议改为在测试方法内创建局部变量:
public void shouldReturnUserSensor() { String userId = "user1"; Optional<User> user = userRepository.findById(userId); // 创建局部Sensor实例,避免跨测试状态污染 Sensor sensor = new Sensor(); sensor.setUsers(List.of(user.get())); sensor.setSensorType(0); Long newSensorId = sensorRepository.save(sensor).getSensorId(); Optional<Sensor> expectedSensor = sensorRepository.findBySensorIdAndUsersId(newSensorId, userId); }
内容的提问来源于stack exchange,提问作者Captain Jacky
相关产品推荐
相关产品推荐

