我有一个基本的留言板类型系统,我在基于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代码