У меня есть сущность следующим образом:
@Entity
@Getter
@Setter
@NoArgsConstructor
@TypeDefs({
@TypeDef(name = "jsonb", typeClass = JsonbType.class)
})
public class Entity extends BasePersistableEntity<String> implements Serializable {
public static final String FIELD_NAME_SERVICES = "services";
public static final String FIELD_NAME_ORG_ID = "orgId";
@Column
public String orgId;
@Column
@Type(type = "jsonb")
public Map<String, String> services;
}
Я хочу написать запрос для извлечения всех сущностей из базы данных Postgres, которые принадлежат orgId
и имеют service
в карта его услуг.
Например, что-то вроде
select * from Entity where entity.ordId='abc' and 'xyz' in entity.services.keyset();
В настоящее время я написал решение следующим образом:
@Override
public List<Entity> getEntitiesWithOrgIdAndService(String orgId, String service) {
return entityRepository.findEntityByOrgId(orgId).stream()
.filter(entity -> entity.services.containsKey(service)).collect(Collectors.toList());
}
Вместо этого я хотел бы отфильтровать его, пока получить его из БД. Как я могу использовать для этого спецификации JPA?
Что-то вроде следующего:
@Override
public List<Proxy> getEntitiesWithOrgIdAndService(String orgId, String service) {
return proxyRepository.findAll(getSpecificationForEntity(orgId, service));
}
private Specification<Proxy> getSpecificationForProxyForEntity(String orgId, String service) {
return (Specification<Proxy>) (root, query, builder) -> {
List<Predicate> predicates = new ArrayList<>();
Predicate orgIdPredicate =
builder.equal(root.get(Entity.FIELD_NAME_ORG_ID), orgId);
// FIX NEEDED
/* Predicate servicePredicate =
builder.equal(builder.function("jsonb_extract_path_text",
String.class, root.<String>get(Entity.FIELD_NAME_SERVICES), service); */
Predicate orgIdServicePredicate = builder.and(orgIdPredicate, servicePredicate);
predicates.add(orgIdServicePredicate);
return builder.and(predicates.toArray(new Predicate[0]));
};
}