CrudRepository – 如何通过映射键和值查找对象

huangapple 未分类评论51阅读模式
英文:

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个字段IDVAL(取决于"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函数。

  1. AttributeType
  2. 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有两个记录,即c1c2


<details>
<summary>英文:</summary>

I have problem with &quot;selecting&quot; values using CrudRepository.

For example:

I have `Client` class:
```&lt;!-- language: java --&gt;
@Entity
public class Client {

@Id
private Long id;

@ManyToMany
Map&lt;AttributeType, Attribute&gt; map = new HashMap&lt;&gt;();
}

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&lt;Client, Long&gt; {
  @Query(&quot;select cli from Client cli where KEY(cli.map) = :attributeType &quot;)
    List&lt;Client&gt; selectByAttributeType(@Param(&quot;attributeType &quot;) AttributeType attributeType );
}

But I have problem with "selecting clients which AttributeType equals x and that Attribute equals y".

I was trying to use:

@Query(&quot;select cli from Client cli \n&quot; +
            &quot;where KEY(cli.map) = :attributeType \n&quot; +
            &quot;and VALUE(cli.map).val = :val&quot;)
List&lt;Client&gt; selectByAttributeTypeAndParam(
@Param(&quot;attributeType&quot;) AttributeType attributeType, @Param(&quot;val&quot;) 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&lt;AttributeType, Attribute&gt; map1 = c1.getMap();
map1.put(at1, new AttributeString(&quot;123456789&quot;);
map1.put(at2, new AttributeBoolean(true);

Client c2 = new Client();
Map&lt;AttributeType, Attribute&gt; map2 = c2.getMap();
map2.put(at1, new AttributeString(&quot;111111111&quot;);
map2.put(at3, new AttributeBoolean(true);

So, i want CrudRepository function which take 2 parameters.

  1. AttributeType
  2. SomeValue (can be String or Boolean)

If this function looks like:

@Query(&quot;some query - no idea how to write it&quot;)
List&lt;Client&gt; selectByAttributeTypeAndParam(
@Param(&quot;attributeType&quot;) AttributeType attributeType, @Param(&quot;val&quot;) String val);

and if i run:

List&lt;Client&gt; someList = selectByAttributeTypeAndParam(at1, &quot;12345679&quot;);

I want that someList have 1 record which is c1.

And if i have equivalent function for Boolean search and i run:

List&lt;Client&gt; someList = selectByAttributeTypeAndParam(at2, true);

Than i want that someList have both c1 and c2 records.

huangapple
  • 本文由 发表于 2020年4月10日 19:06:51
  • 转载请务必保留本文链接:https://java.coder-hub.com/61139015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定