Я использую Hibernate OGM для MongoDB и сопоставляю простой объект ShopItem с Map:
@NamedQueries({
@NamedQuery(name = ShopItem.GET_BY_NAME,
query = "select items from ShopItem items where
items.name=:name"),
@NamedQuery(name = ShopItem.GET_BY_OPTION,
query = "select items from ShopItem items
join items.options map
where ( KEY(map) = :optionKey and map = :optionValue )")
})
@Entity
public class ShopItem {
public static final String GET_BY_NAME = "ShopItem.getByName";
public static final String GET_BY_OPTION = "ShopItem.getByOption";
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
private String name;
@ElementCollection(fetch = FetchType.EAGER)
private Map<String, String> options = new HashMap<>();
//...etc
}
Это совпало хорошо. И я попытался написать именованные запросы JPQL для моего ShopItemRepository. Я искал NamedQuery по полю «имя», и он отлично работает. Но мне нужно искать по обоим полям «ключ» и «значение», и я не могу написать для этого правильный JPQL. Например, у меня есть объект в БД:
{
"_id":"df111b8a-b831-4200-95b3-f80576cd7273",
"name":"Example",
"description":"My description",
"options":
{
"weight":"60 kg",
"age":"22"
}
}
И я хочу найти все объекты, где параметры имеют ключ «возраст» и имеют значение «22».
Я пытаюсь написать:
select items from ShopItem items join items.options map where ( KEY(map) = :optionKey and map = :optionValue )
or
select items from ShopItem items join items.options map where ( KEY(map) = :optionKey and :optionValue in (VALUE(map))
or
select items from ShopItem items where ( KEY(items.options) = :optionKey and items.options = :optionValue )
or
select items from ShopItem items where ( KEY(items.options) = :optionKey and :optionValue in (VALUE(items.options))
И есть эта ошибка
org/hibernate/hql/ast/origin/hql/resolve/GeneratedHQLResolver.g: node from line 1:85 no viable alternative at input '('
can't look backwards more than one token in this stream
Мой код в репо:
List<ShopItem> result = entityManager.createNamedQuery(ShopItem.GET_BY_OPTION, ShopItem.class)
.setParameter("optionKey", key)
.setParameter("optionValue", value)
.getResultList();
Можете ли вы помочь мне написать правильный запрос JPQL? А если это невозможно, то подскажите, как это сделать другим способом.
Я не могу использовать Spring Data JPA.