英文:
CrudRepository - how to find objects by map key and value
问题
我在使用CrudRepository选择值方面遇到了问题。
例如:
我有一个`Client`类:
```java
@Entity
public class Client {
@Id
private Long id;
@ManyToMany
Map<AttributeType, Attribute> map = new HashMap<>();
}
和一个AttributeType
类:
@Entity
public class AttributeType {
@Id
private Long id;
@Column(unique = true)
private String name;
}
"Attribute"是抽象实体,它具有String和Boolean的"子类型"(AttributeBoolean,AttributeString),两者都有2个字段ID
和VAL
(取决于"className"是String还是Boolean的情况)。
因此,如果我想要选择具有映射中的"AttributeType"的客户列表,我可以使用:
public interface ClientRepository extends CrudRepository<Client, Long> {
@Query("select cli from Client cli where KEY(cli.map) = :attributeType ")
List<Client> selectByAttributeType(@Param("attributeType") AttributeType attributeType );
}
但是,我在"选择AttributeType等于x且Attribute等于y的客户"方面遇到问题。
我尝试使用:
@Query("select cli from Client cli \n" +
"where KEY(cli.map) = :attributeType \n" +
"and VALUE(cli.map).val = :val")
List<Client> selectByAttributeTypeAndParam(
@Param("attributeType") AttributeType attributeType, @Param("val") String val);
但是它抛出异常:"Caused by: java.lang.IllegalArgumentException: Parameter value [xxxxxxxx] did not match expected type [java.lang.Boolean (n/a)]"。
因此,问题是:
你有任何想法,如何选择每个满足以下条件的客户:
AttributeType = x
映射中(对于该AttributeType)的值 = y?
//编辑...
为了更好地理解:
我们有以下情况:
AttributeType at1 =... //不重要是什么
AttributeType at2 =... //不重要是什么
AttributeType at3 =... //不重要是什么
Client c1 = new Client();
Map<AttributeType, Attribute> map1 = c1.getMap();
map1.put(at1, new AttributeString("123456789"));
map1.put(at2, new AttributeBoolean(true));
Client c2 = new Client();
Map<AttributeType, Attribute> map2 = c2.getMap();
map2.put(at1, new AttributeString("111111111"));
map2.put(at3, new AttributeBoolean(true));
因此,我希望有一个接受两个参数的CrudRepository函数。
- AttributeType
- SomeValue(可以是String或Boolean)
如果这个函数看起来像:
@Query("一些查询 - 不知道如何编写")
List<Client> selectByAttributeTypeAndParam(
@Param("attributeType") AttributeType attributeType, @Param("val") String val);
并且我运行:
List<Client> someList = selectByAttributeTypeAndParam(at1, "12345679");
我希望someList
有一个记录,即c1
。
并且如果我有布尔搜索的等效函数,并且我运行:
List<Client> someList = selectByAttributeTypeAndParam(at2, true);
那么我希望someList
有两个记录,即c1
和c2
。
<details>
<summary>英文:</summary>
I have problem with "selecting" values using CrudRepository.
For example:
I have `Client` class:
```<!-- language: java -->
@Entity
public class Client {
@Id
private Long id;
@ManyToMany
Map<AttributeType, Attribute> map = new HashMap<>();
}
and AttributeType
class:
@Entity
public class AttributeType {
@Id
private Long id;
@Column(unique = true)
private String name;
}
"Attribute" is abstract entity which have "subtypes" of String and Boolean (AttributeBoolean, AttributeString), and both have 2 fields ID
, and VAL
(which is String val or Boolean val depends on "className").
So, if I want to select client list which have "AttributeType" in map I can use:
public interface ClientRepository extends CrudRepository<Client, Long> {
@Query("select cli from Client cli where KEY(cli.map) = :attributeType ")
List<Client> selectByAttributeType(@Param("attributeType ") AttributeType attributeType );
}
But I have problem with "selecting clients which AttributeType equals x and that Attribute equals y".
I was trying to use:
@Query("select cli from Client cli \n" +
"where KEY(cli.map) = :attributeType \n" +
"and VALUE(cli.map).val = :val")
List<Client> selectByAttributeTypeAndParam(
@Param("attributeType") AttributeType attributeType, @Param("val") String val);
But it throws exception: Caused by: java.lang.IllegalArgumentException: Parameter value [xxxxxxxx] did not match expected type [java.lang.Boolean (n/a)]
.
So, the question is:
Do you have any idea, how can I select Every Client where:
AttributeType = x
and value from map (for that AttributeType) = y ?
//edit...
To better understund:
We have situation like this:
AttributeType at1 =... //does not matter what is it
AttributeType at2 =... //does not matter what is it
AttributeType at3 =... //does not matter what is it
Client c1 = new Client();
Map<AttributeType, Attribute> map1 = c1.getMap();
map1.put(at1, new AttributeString("123456789");
map1.put(at2, new AttributeBoolean(true);
Client c2 = new Client();
Map<AttributeType, Attribute> map2 = c2.getMap();
map2.put(at1, new AttributeString("111111111");
map2.put(at3, new AttributeBoolean(true);
So, i want CrudRepository function which take 2 parameters.
- AttributeType
- SomeValue (can be String or Boolean)
If this function looks like:
@Query("some query - no idea how to write it")
List<Client> selectByAttributeTypeAndParam(
@Param("attributeType") AttributeType attributeType, @Param("val") String val);
and if i run:
List<Client> someList = selectByAttributeTypeAndParam(at1, "12345679");
I want that someList
have 1 record which is c1
.
And if i have equivalent function for Boolean search and i run:
List<Client> someList = selectByAttributeTypeAndParam(at2, true);
Than i want that someList
have both c1
and c2
records.
专注分享java语言的经验与见解,让所有开发者获益!
评论