我的实体如下:
@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]));
};
}
答案 0 :(得分:0)
以下更改为我解决了此问题。
Predicate servicePredicate =
builder.equal(builder.function(Constants.FUNCTION_JSONB_EXTRACT_PATH_TEXT,
String.class, root.<String>get(Proxy.FIELD_NAME_SERVICES),
builder.literal(service)), String.valueOf(true));