【问题标题】:Spring JPA Specifications: searching for parameters in a parent classSpring JPA 规范:在父类中搜索参数
【发布时间】:2019-08-12 17:44:47
【问题描述】:

我似乎无法弄清楚如何使父类参数可用于规范查询。如果我使用RoleDAO 参数name 进行查询,那么我会得到一个结果,但如果我尝试通过数据库中存在的BaseDAOid 值进行搜索,则不会返回任何内容。

另一方面,如果我将 id 参数移动到 RoleDAO 中,则搜索工作正常。

实体看起来像这样:

@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@Table(name = "user_role", indexes = {
        @Index(name = "id_index", columnList = "id"),
        @Index(name = "name_index", columnList = "name"),
})
public class RoleDAO extends BaseDAO {

    @NotEmpty(message = "{error.not-empty}")
    @Column
    private String name;

}

BaseDAO:

@MappedSuperclass
@Data
public class BaseDAO implements Serializable {

    private static final long serialVersionUID = 1;

    @Id
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    @Column(name = "id", unique = true, nullable = false)
    private String id;

    @NotNull(message = "{error.not-null}")
    @Column(name = "created")
    private LocalDateTime created;

    @NotEmpty(message = "{error.not-empty}")
    @Size(max = 200, message = "{error.max}")
    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "modified")
    private LocalDateTime modified;

    @Size(max = 200, message = "{error.max}")
    @Column(name = "modified_by")
    private String modifiedBy;

    @PrePersist
    public void prePersist() {
        id = UUID.randomUUID().toString();
        created = LocalDateTime.now();
    }

    @PreUpdate
    public void preUpdate() {
        modified = LocalDateTime.now();
    }
}

规格:

public class Specifications<T> {

    public Specification<T> containsTextInAttributes(String text, List<String> attributes) {
        if (!text.contains("%")) {
            text = "%" + text + "%";
        }
        String finalText = text;

        return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream()
                .filter(a -> attributes.contains(a.getName()))
                .map(a -> builder.like(root.get(a.getName()), finalText))
                .toArray(Predicate[]::new));
    }
}

然后有一个带有方法的存储库:

List<RoleDAO> findAll(Specification<RoleDAO> spec);

以及如何在服务中调用它:

var roles = repository.findAll(
                Specification.where(new Specifications<RoleDAO>().containsTextInAttributes(searchTerm, Arrays.asList(ID, NAME)))
        );

【问题讨论】:

标签: java spring-data


【解决方案1】:

解决方法很简单:

public class Specifications<T> {

    public Specification<T> containsTextInAttributes(String text, List<String> attributes) {
        if (!text.contains("%")) {
            text = "%" + text + "%";
        }
        String finalText = text;

        return (root, query, builder) -> builder.or(root.getModel().getSingularAttributes().stream()
                .filter(a -> attributes.contains(a.getName()))
                .map(a -> builder.like(root.get(a.getName()), finalText))
                .toArray(Predicate[]::new));
    }
}

注意getSingularAttributes() 呼叫变化。

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 2018-06-18
    • 2023-01-31
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 2017-03-14
    相关资源
    最近更新 更多