#java #spring-boot #spring-data-jpa #spring-data
Вопрос:
Поэтому я занимаюсь проектом, в котором у нас есть механика «тем», на самом деле очень похожая на механику переполнения стека. Поэтому я сохраняю каждую сущность (кулинарный рецепт) в переменной темы, которая содержит строку, разделенную запятыми. Теперь моя большая проблема здесь в том, что мне нужно найти темы, как и в нескольких темах. Я пробовал использовать @Query
@Query("select new com.fullstack.dtos.projections.LocalizedRecipe(t.id, t.created, t.createdBy, t.lastModified, t.lastModifiedBy, t.version, l.title, l.description) from tutorial t inner join t.localizations l where l.id.locale = :lang and t.topics in :topics")
Page<LocalizedRecipe> findAllByTopics(String lang, Set<String> topics, Pageable page);
Я даже изменил свою модель так, чтобы темы представляли собой @elementколлекцию строк, пытающихся использовать один и тот же запрос, но всегда возникают ошибки типа. Большую часть времени он бросает:
java.lang.IllegalArgumentException: Parameter value [Java] did not match expected type [java.util.Set (n/a)]
Мой вопрос здесь в том, как мне сделать так, чтобы это работало. Изменение моей модели не проблема, я просто не могу найти хороший способ сделать это.
Текущая модель:
public class RecipeDAO {
@Id
@GeneratedValue(generator = "uuid2", strategy = GenerationType.AUTO)
@Column(columnDefinition = "BINARY(16)", unique = true)
@GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
@CreatedDate
private LocalDateTime created;
@CreatedBy
private String createdBy;
@LastModifiedDate
private LocalDateTime lastModified;
@LastModifiedBy
private String lastModifiedBy;
@Version
private Integer version;
private Boolean visible;
private String topics;
@MapKey(name = "id.locale")
@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true)
private Map<String, Localization> localizations;
}
Моя конечная цель здесь-проверить, есть ли, скажем, 3 рецепта с темами «завтрак, обед, ужин». Я хочу иметь возможность находить темы с помощью [«обед», «ужин»], и он возвращает их, возвращает все, у кого есть ужин или обед в строке тем
В основном сопоставитель подстрок. Или альтернативой для достижения этого, как я уже сказал, изменение модели не является проблемой
РЕДАКТИРОВАТЬ: Я также попытался перейти в список и стать @ElementCollection, но появилась ошибка. Я не знаю, смогу ли я увидеть, пересекаются ли два списка.
Комментарии:
1. Во-первых, ваша текущая модель не ясна из вопроса. Пожалуйста, поделитесь этим.
2. Также, пожалуйста, поделитесь методом репозитория и тем, какой параметр вы передаете для фильтрации ? Это строка или список?
3. Я отредактировал, чтобы включить текущую модель.
4. Его набор, при необходимости может быть списком или даже массивом java/varargs. Моя проблема в том, как выполнить запрос. Я хочу посмотреть, есть ли в параметре объекта «темы» какие-либо строки в наборе.
5. Вы можете проверить thorben-janssen.com/hibernate-tips-query-elementcollection а также, как предлагали другие, использование имен методов также должно работать
Ответ №1:
Вы должны быть в состоянии сделать это с In
помощью ключевого слова следующим образом:
findByTopicsIn(Collection<String> topics)
Ответ №2:
- В репозитории вы можете использовать метод производного запроса, где каждый параметр ссылается на свойства соответствующей сущности, например
findByTopicsОрТопики(строка темы 1, строка темы 2);
соответствующий sql-запрос —
select * from RecipeDAO where topics="topic1" OR topics="topic2";
- Если количество тем больше, то использование коллекции тем в качестве параметра в методе является лучшим выбором, чем передача каждой темы в качестве отдельного параметра.
Предоставление коллекции тем, запрещенных к использованию в
List<RecipeDAO> findByTopicsIn(Collection<String> topics);
Соответствующий sql-запрос —
select * from RecipeDAO where topics in('topics1','topics2',...,'topicsn');
Комментарии:
1. Я в курсе, но я не знаю, сколько будет тем. Может быть 1 может быть 2 может быть 10
2. Затем вы можете использовать производный метод запроса, предоставив набор тем для использования в
List<RecipeDAO> findByTopicsIn(Collection<String> topics);
3. Сработает ли это в моем примере? Мне нужно было бы изменить темы на строку @ElementCollection правильно?