ptomli
ptomli

Reputation: 11818

Create a Predicate to match an entity with an entry in a Map property

I'm trying to create a javax.persistence.criteria.Predicate to match entities which contain a certain key/value entry in a Map<String,String> property. This is in the context of Spring Data JPA and a JpaSpecificationExecutor<MyEntity> repository.

class MyEntity {
  @ElementCollection(fetch = FetchType.EAGER)
  ...
  Map<String, String> metadata = new HashMap<>();
}

static Specification<MyEntity> hasMetadata(String name, String value) {
  return (entity, criteriaQuery, criteriaBuilder) -> {
    Path<Map<String,String>> metadata = entity.get("metadata");

    // fixme: insert magic
    //
    // not quite right: cb.isMember(cb.literal(value), metadata) 

    return ...
  };
}

There is a slightly related question CriteriaBuilder and isMember of list on entity (Hibernate), but I haven't been able to glean much info from there.

A solution would be nice, but also a pointer to documentation where this is specified too. My Google-fu is failing me.

Upvotes: 3

Views: 3246

Answers (1)

ptomli
ptomli

Reputation: 11818

I found an very similar question here jpa criteriabuilder join maps, which offered up something that seems to work now

static Specification<MyEntity> hasMetadata(String name, String value) {
  return (entity, criteriaQuery, criteriaBuilder) -> {
    MapJoin<MyEntity, String, String> join = entity.joinMap("metadata");
    return criteriaBuilder.and(
      criteriaBuilder.equal(join.key(), name),
      criteriaBuilder.equal(join.value(), value)
    );
  };
}

Upvotes: 2

Related Questions