JPA CriteriaQuery,查询多个字段未按预期返回结果

时间:2015-01-08 16:44:44

标签: java sql hibernate jpa dao

我有一个基本的留言板类型系统,我在基于Spring的webapp中开发。我使用的是spring 4.1.3和hibernate 4.3.7。我试图建立一个普遍的"搜索栏以查找在许多字段之一中包含指定值的帖子。对于初学者,这是我的帖子域对象:

@Entity
public class Post implements Serializable {

@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(
        name = "POST_KEYWORD",
        joinColumns = {@JoinColumn(name = "POST_ID", referencedColumnName = "POST_ID")},
        inverseJoinColumns = {@JoinColumn(name = "KEYWORD_ID", referencedColumnName = "ID")}
)
private Set<Keyword> keywords = new HashSet<>();

作者,类别和关键字对象都非常无聊,基本上都是这样的:

@Entity
public class Keyword implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "keyword_id_seq")
@SequenceGenerator(name = "keyword_id_seq", sequenceName = "keyword_id_seq", allocationSize = 1)
private Long id;

@Column(name = "KEYWORD_VALUE")
private String value;
private int count = 1;

}

作者和类别类没有int计数,只是id和value字段。

这是我的PostDao:

public List<Post> universalFind(String value, int maxResults) {
        // create a new string that is built for case insensitive "like" sql searches
    String upperValue = "%" + value.toUpperCase() + "%";

    final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

     // build the criteria query and get the path for the category value
    CriteriaQuery<Post> postQuery = criteriaBuilder.createQuery(Post.class).distinct(true);
    Root<Post> postRoot = postQuery.from(Post.class);

    List<Predicate> predicates = new ArrayList<>();

    // find titles containing the value
    Predicate titlePredicate = criteriaBuilder.like(criteriaBuilder.upper(postRoot.get(Post_.title)), upperValue);
    predicates.add(titlePredicate);        


    // find keywords containing the value
    SetJoin<Post, Keyword> postKeywords = postRoot.join(Post_.keywords);
    Path<String> keywordPath = postKeywords.get(Keyword_.value);
    Predicate keywordPredicate = criteriaBuilder.like(criteriaBuilder.upper(keywordPath), upperValue);
    predicates.add(keywordPredicate);

    select.where(criteriaBuilder.or(predicates.toArray(new Predicate[]{})));

    TypedQuery typedQuery = entityManager.createQuery(select);
    List<Post> resultList = typedQuery.getResultList();
    return resultList;
}

当所有数据都填充在Post对象中时,这一切都按预期工作。如果我有两个帖子&#34;测试&#34;在标题中,我搜索&#34; test&#34;,我将收到两个帖子。但是,如果我从其中一个帖子中删除了所有关键字,则该帖子将不再显示在搜索结果中。我可以使用pgadmin来验证它是否在数据库中。

如果我在我的DAO中为关键字注释了SetJoin部分,那么没有关键字的帖子会突然出现在我的搜索中。

是否有某种方法可以阻止这种情况,以便我可以在没有关键字的情况下发布帖子,如果搜索字词与其他任何一个字段匹配,它仍会显示在结果中?

编辑:我把它减少到我可能的最低限度的Frankenstein代码

0 个答案:

没有答案