Search code examples
jpajson-apicrnk

crnk subrelation filtering allowed?


We're using crnk for json-api both server-side as client-side implementation.
Does the server implementation for jpa bindings support subrelation filters?
We want to filter on all series which have events after a specific starttime.

We seperated the json-api and JPA entity classes. Please see below for both json-api as entity classes

e.g. The url I use (and is generated by crnk client code):

EpgShow?include[EpgShow]=titles&filter[EpgShow][titles.startTime][GE]=2018-05-04T12:30:22+02:00

The error we receive is:

{
    errors: [
        {
            status: "500",
            title: "INTERNAL_SERVER_ERROR",
            detail: "failed to resolve path [titles, startTime]"
        }
    ]
}

Class implementation:

@JsonApiResource(type = "EpgShow")
public class EpgSeriesDto {

    @JsonApiId
    private Integer serieId;

    @JsonApiRelation(opposite = "epgShow", lookUp = LookupIncludeBehavior.AUTOMATICALLY_WHEN_NULL, serialize = SerializeType.ONLY_ID, repositoryBehavior = RelationshipRepositoryBehavior.FORWARD_OWNER)
    private Set<EpgTitleDto> titles;
}

@JsonApiResource(type = "EpgTitle")
@Data
public class EpgTitleDto {
    @JsonApiId
    private Long id;

    @JsonApiRelation(opposite = "titles", lookUp = LookupIncludeBehavior.AUTOMATICALLY_WHEN_NULL, serialize = SerializeType.ONLY_ID)
    private EpgSeriesDto epgShow;
}

@Entity
public class Serie {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "serie_id", unique = true, nullable = false)
    private Integer serieId;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "epgShow")
    private Set<Event> titles = new HashSet<Event>(0);
}

@Entity
public class Event {

    @Column(name = "start_time")
    private ZonedDateTime startTime;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "serie_id")
    private Serie epgShow;
}

Solution

  • there are three different kinds of filters:

    • filtering of included relationships (but not the requested/main resources)
    • filtering of the request resource type based on an attribute located on a single-valued relationships.
    • filtering of the request resource type based on an attribute located on a multi-valued relationships.

    the former two are supported, not so far directly the last one. For the later it so far supports "computed" attributes where the value is derived from a Criteria API or QueryDSL expression which allows arbitrary complex SQL. Those in turn can return again a simple result that can be filtered and sorted. In this example, that could be a minStartTime and maxStartTime on the main resource.

    but if desired, it would also be possible to add support for filtering multi-valued relationships. One possiblity would be to make use of EXISTS subqueries. Or a more advanced one may support different strategies. PRs in that regards would be welcomed.