У меня есть API весенней загрузки, вызываемый из пользовательского интерфейса React, который извлекает некоторые данные с помощью запроса в хранилище весенней загрузки.Тем не менее, я получаю сообщение об ошибке, когда я ввожу использование 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
в операторе запроса вместе с переданным в Set<>
параметром.
У меня есть метод контроллера, который берет POST из приложения реагирования:
@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);
}
Параметры вызова сопоставлены с FishDTO:
public class FishDto {
private int tankVolume;
private int tankLength;
private int tankDepth;
private int tankTemp;
private Set<WaterHardness> waterHardness;
}
Выглядит так, как будтоDTO заполняется, как и ожидалось, при работе с отладчиком.
Контроллер вызывает метод в службе, который подготавливает параметры для хранилища:
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);
}
О, и вот модель сущностей, которая возвращается:
@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;
}
Есть ли удобный способ заставить это работать, помимо получения спискаid / строковое значение длям WaterHardness в службе и передачи их в качестве параметра, а затем с помощью объединений в запросе?Например:
@Query("SELECT f FROM Fish f"
+ " JOIN f.waterHardness wh"
+ " WHERE f.tankMinVolume <= :tankVolume"
+ " AND f.tankMinLength <= :tankLength"
+ " AND f.tankMinDepth <= :tankDepth"
+ " AND f.minWaterTemp <= :tankTemp"
+ " AND f.maxWaterTemp >= :tankTemp"
+ " AND wh.id IN :waterHardnessIds")
List<Fish> findBySearch(@Param("tankVolume") int tankVolume,
@Param("tankLength") int tankLength,
@Param("tankDepth") int tankDepth,
@Param("tankTemp") int tankTemp,
@Param("waterHardnessIds") List<Long> waterHardnessIds);
, который работает, но чувствует себя ненужным.