CrudRepository - как найти объекты по ключу и значению карты - PullRequest
2 голосов
/ 10 апреля 2020

У меня проблема с «выбором» значений с помощью CrudRepository.

Например:

У меня есть Client класс:

@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;
}

«Атрибут» - это абстрактный объект, который имеет «подтипы» String и Boolean (AttributeBoolean, AttributeString), и оба имеют 2 поля ID и VAL (что является String val или Boolean val зависит от "className").

Итак, если я хочу выбрать список клиентов, имеющих "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?

// edit ... Чтобы лучше понять:

У нас такая ситуация:

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);

Итак, я хочу функцию CrudRepository, которая принять 2 параметра.

1) AttributeType 2) SomeValue (может быть String или Boolean)

Если эта функция выглядит следующим образом:

@Query("some query - no idea how to write it")
List<Client> selectByAttributeTypeAndParam(
@Param("attributeType") AttributeType attributeType, @Param("val") String val);

и если я запускаю:

List<Client> someList = selectByAttributeTypeAndParam(at1, "12345679");

Я хочу, чтобы у someList была 1 запись, равная c1.

И если у меня есть эквивалентная функция для логического поиска, и я запускаю:

List<Client> someList = selectByAttributeTypeAndParam(at2, true);

Чем я хочу, чтобы у someList были записи c1 и c2.

...