0

In Blaze Persistence, is there a way to use an optional parameter in a subquery?

In my current use case, let's say I have topics, users, and a third table called topic_last_seen to record the date at which each user has last read each topic. I would like to create an entity view for the Topic entity which also maps that date for each topic with the current user given as an "optional parameter". This is roughly what I've been trying:

@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 <T> T createSubquery(SubqueryInitiator<T> 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();
        }
    }
}

Unfortunately, this results in an exception:

java.lang.IllegalArgumentException: Attribute 'currentUserId' not found on type 'Topic'

Is there any way to use an optional parameter in a subquery like this at all? Or is there a different way to map this information? Changing the DB schema is not an option at this point.

cg.
  • 3,648
  • 2
  • 26
  • 30

1 Answers1

0

Looks like I figured this out a possible suolution by trial and error. It seems that the "optional parameters" from EntityViewSetting can be used like regular parameters in JPQL:

return subqueryBuilder.from(TopicLastSeen.class, "lastSeen")
        .select("dateSeen")
        .where("lastSeen.user.id").eqExpression(":currentUserId")
        .where("lastSeen.topic.id").eqExpression("EMBEDDING_VIEW(id)")
        .end();

Unfortunately though, with this subquery mapping the currentUserId parameter is no longer "optional". When it is not set I get another exception:

org.hibernate.QueryException: Named parameter not bound : currentUserId 
cg.
  • 3,648
  • 2
  • 26
  • 30
  • 1
    It's true that the parameter is no longer optional, but the nice thing about `EntityViewSetting.addOptionalParameter` is that it doesn't fail if the parameter does not exist in the query, so if you don't have a value, you can set it to null or something like that :) – Christian Beikov Nov 08 '21 at 11:39
  • @ChristianBeikov That is exactly what I'm doing now. I only just discovered Blaze Persistence and wasn't sure if this was the way to go. Thanks for your feedback and also for your work on Blaze Persistence! – cg. Nov 08 '21 at 14:05