簡體   English   中英

在列表或設置為傳遞參數的JPA- / CrudRepository中的自定義@Query中使用SQL-IN子句?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM