#java #hibernate #jpa #blaze-persistence
Вопрос:
В Blaze Persistence есть ли способ использовать необязательный параметр в подзапросе?
В моем текущем случае использования, допустим, у меня есть темы, пользователи и третья таблица, вызываемая topic_last_seen
для записи даты, когда каждый пользователь в последний раз читал каждую тему. Я хотел бы создать представление сущности для Topic
сущности, которое также сопоставляет эту дату для каждой темы с текущим пользователем, указанным в качестве «необязательного параметра». Это примерно то, что я пытался сделать:
@EntityView(Topic.class) public interface TopicView { @IdMapping Long getId(); String getSummary(); @MappingParameter("currentUserId") Long getCurrentUserId(); @MappingSubquery(LastSeenDateSubqueryProvider.class) Date getLastSeenDate(); class LastSeenDateSubqueryProvider implements SubqueryProvider { @Override public lt;Tgt; T createSubquery(SubqueryInitiatorlt;Tgt; subqueryBuilder) { return subqueryBuilder.from(TopicLastSeen.class, "lastSeen") .select("dateSeen") .where("lastSeen.user.id").eqExpression("EMBEDDING_VIEW(currentUserId)") .where("lastSeen.topic.id").eqExpression("EMBEDDING_VIEW(id)") .end(); } } }
К сожалению, это приводит к исключению:
java.lang.IllegalArgumentException: Attribute 'currentUserId' not found on type 'Topic'
Есть ли вообще какой-либо способ использовать необязательный параметр в подобном подзапросе? Или есть другой способ отобразить эту информацию? На данный момент изменение схемы БД не является вариантом.
Ответ №1:
Похоже, я понял это возможное решение методом проб и ошибок. Похоже, что «необязательные параметры» из EntityViewSetting
можно использовать как обычные параметры в JPQL:
return subqueryBuilder.from(TopicLastSeen.class, "lastSeen") .select("dateSeen") .where("lastSeen.user.id").eqExpression(":currentUserId") .where("lastSeen.topic.id").eqExpression("EMBEDDING_VIEW(id)") .end();
К сожалению, однако, при сопоставлении этого подзапроса параметр currentUserId больше не является «необязательным». Когда он не установлен, я получаю другое исключение:
org.hibernate.QueryException: Named parameter not bound : currentUserId
Комментарии:
1. Это правда, что параметр больше не является необязательным, но приятно то,
EntityViewSetting.addOptionalParameter
что он не завершается ошибкой, если параметр не существует в запросе, поэтому, если у вас нет значения, вы можете установить его равным нулю или что-то в этом роде 🙂2. @ChristianBeikov Это именно то, что я сейчас делаю. Я только что обнаружил Упорство Блейза и не был уверен, что это правильный путь. Спасибо за ваши отзывы, а также за вашу работу над Blaze Persistence!
3. Всегда пожалуйста 🙂