[英]Using SQL-IN-clause in custom @Query in JPA-/CrudRepository with the list or set as passed parameter?
嗨,Spring和Hibernate专家!
有人可以说在将Arraylist或一组字符串作为参数传递时,是否可以在CrudRepository的自定义@Query中使用SQL IN子句?
我对Spring相对较新,并且不太清楚为什么会出现以下Spring错误:
“ java.lang.IllegalArgumentException:参数值[d9a873ed-3f15-4af5-ab1b-9486017e5611]与预期的类型[IoTlite.model.Device(n / a)]不匹配”
在这篇文章( JPQL IN子句:Java-Arrays(或Lists,Sets ...)? )中,我们对该主题进行了非常详细的讨论,但是我无法提出建议的解决方案以使其适用于自定义@Query。
作为Spring Boot Restful应用程序的一部分,我的演示存储库如下:
@Repository
public interface DeviceRepository extends JpaRepository<Device, Long> {
@Query("SELECT d FROM Device d WHERE d IN (:uuid)")
List<Device> fetchUuids(@Param("uuid") Set<String> uuid);
}
模型类如下:
@Entity
@SequenceGenerator(sequenceName = "device_seq", name = "device_seq_gen", allocationSize = 1)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Device implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "device_seq_gen")
@JsonIgnore
private Integer id;
@Column(unique=true, length=36)
@NotNull
private String uuid = UUID.randomUUID().toString();
@Column(name="name")
private String name;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String description;
@OneToMany(
mappedBy="device",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Sensor> sensors = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@JsonIgnore
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeviceUuid() {
return uuid;
}
public void setDeviceUuid(String deviceUuid) {
this.uuid = deviceUuid;
}
public List<Sensor> getSensors() {
return sensors;
}
public void addSensor(Sensor sensor){
sensor.setDevice(this);
sensors.add(sensor);
}
}
这里是服务的相关部分,它使用字符串的设置列表作为参数调用fetchUuids-custom-method(该服务自然由相关的restcontroller调用):
@Service
public class DeviceService implements IDeviceService {
@Autowired
private DeviceRepository deviceRepository;
...
@Override
public List<Device> listDevices(Set<String> clientIds) {
return deviceRepository.fetchUuids(clientIds);
}
...
}
快速解决
自定义查询中有WHERE d IN (:uuid)
。 您无法将d
匹配为d
,后者是Device
实体的别名,带有:uuid
参数,该参数是字符串的集合。
WHERE d.uuid IN (:uuid)
将修复查询-它将字符串与字符串匹配。
你应该怎么做
将方法命名为fetchUuids
并返回Device
实例列表是相当误导的。 也不必编写自定义查询来执行此操作。 您可以从存储库方法名称约定中受益,并让Spring Data Jpa框架为您生成查询:
List<Device> findByUuidIn(Set<String> uuids);
是的,可以在JPA查询参数中使用collection。 您的查询是错误的,应该是这样的:
@Query("SELECT d FROM Device d WHERE d.uuid IN :uuid")
你可以这样写
@Query(value = "select name from teams where name in :names", nativeQuery = true)
List<String> getNames(@Param("names") String[] names);
并在服务中调用该函数并传递String数组作为参数。
String[] names = {"testing team","development team"};
List<String> teamtest = teamRepository.getNames(names);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.