我有一个从React UI调用的spring boot API,它使用spring boot存储库中的查询来获取一些数据。但是,当我在查询参数中引入Set <>时会收到错误消息,我不确定如何继续。
错误如下:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [WaterHardness(id=4, hardness=hard)] did not match expected type [java.util.Set (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [WaterHardness(id=4, hardness=hard)] did not match expected type [java.util.Set (n/a)]
根据我的研究(尚未发现使用ManyToMany Set<>
的完整示例),我认为我应该能够在查询语句中使用和IN
以及传入的{{ 1}}参数。
我有一个控制器方法,该方法从react应用程序中获取POST:
Set<>
调用中的参数被映射到FishDTO:
@PostMapping("/search")
@ResponseBody
public String searchFish(@RequestBody FishDto fishDto) {
String fishJson = "";
try {
List<Fish> fish = fishService.findBySearch(fishDto);
ObjectMapper mapper = new ObjectMapper();
fishJson = mapper.writeValueAsString(fish);
} catch (Exception e) {
//TODO Proper Handle of exceptions
log.info("Something Went Wrong!!!");
}
return (fishJson);
}
使用调试器运行时,似乎DTO已按预期填充。
控制器调用服务中的方法,该方法为存储库准备参数:
public class FishDto {
private int tankVolume;
private int tankLength;
private int tankDepth;
private int tankTemp;
private Set<WaterHardness> waterHardness;
}
最后,存储库使用查询进行呼叫:
public class FishService {
...
public List<Fish> findBySearch(FishDto fishDto) {
int tankVolume = fishDto.getTankVolume();
int tankLength = fishDto.getTankLength();
int tankDepth = fishDto.getTankDepth();
int tankTemp = fishDto.getTankTemp();
Set<WaterHardness> waterHardness = fishDto.getWaterHardness();
return Lists.newArrayList(fishrepo.findBySearch(tankVolume, tankLength, tankDepth, tankTemp, waterHardness));
}
...
}
哦,这是返回的实体模型:
public interface FishRepository extends JpaRepository<Fish, Long> {
@Query("SELECT f FROM Fish f"
+ " WHERE f.tankMinVolume <= :tankVolume"
+ " AND f.tankMinLength <= :tankLength"
+ " AND f.tankMinDepth <= :tankDepth"
+ " AND f.minWaterTemp <= :tankTemp"
+ " AND f.maxWaterTemp >= :tankTemp"
+ " AND f.waterHardness IN :waterHardness")
List<Fish> findBySearch(@Param("tankVolume") int tankVolume,
@Param("tankLength") int tankLength,
@Param("tankDepth") int tankDepth,
@Param("tankTemp") int tankTemp,
@Param("waterHardness") Set<WaterHardness> waterHardness);
}
除了从服务中的waterHardness获取id / string值列表并将它们作为参数传递然后在查询中使用联接之外,是否有一种巧妙的方法使它起作用?例如:
@Entity
@Table(name = "fish")
public class Fish {
@Id
@GeneratedValue
private Long id;
@NonNull //Check up on this!
private String commonName;
private String latinName;
private int fullGrownSize;
private int tankMinVolume;
private int tankMinLength;
private int tankMinDepth;
private int minWaterTemp;
private int maxWaterTemp;
private int minShoalSize;
@ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private Set<TankPlacement> tankPlacement;
@ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private Set<TankFlow> tankFlow;
@ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
private Set<WaterHardness> waterHardness;
@ManyToOne(cascade=CascadeType.PERSIST)
private Origin origin;
}
确实可以,但是感觉没有必要。
答案 0 :(得分:0)
问题是Set<WaterHardness>
。
错误说
参数值[水硬度(id = 4,硬度=硬)]不匹配 预期的类型[java.util.Set(n / a)]
您需要按以下方式检查IN运算符,
公共接口FishRepository扩展了JpaRepository {
@Query("SELECT f FROM Fish f"
+ " WHERE f.tankMinVolume <= :tankVolume"
+ " AND f.tankMinLength <= :tankLength"
+ " AND f.tankMinDepth <= :tankDepth"
+ " AND f.minWaterTemp <= :tankTemp"
+ " AND f.maxWaterTemp >= :tankTemp"
+ " AND f.waterHardness.id IN :waterHardness")
List<Fish> findBySearch(@Param("tankVolume") int tankVolume,
@Param("tankLength") int tankLength,
@Param("tankDepth") int tankDepth,
@Param("tankTemp") int tankTemp,
@Param("waterHardness") Set<Long> waterHardness);
}