以下是我的实体。
@Entity
@Table(name = "TRADEITEMS")
public class TradeItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "TRADEITEM_ID")
private Long id;
private String shopOwner;
private Boolean corrupted;
private String base;
private String type;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Mod> mod;
private String league;
...
}
@Entity
@Table(name = "MODS")
public class Mod {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Double miniValue;
private Double maxiValue;
private String modName;
...
}
@Repository
public class TradeItemDaoImp implements TradeItemDao{
@PersistenceContext
private EntityManager em;
@Override
public Optional<List<TradeItem>> search(TradeItemRequest request) {
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<TradeItem> cq = criteriaBuilder.createQuery(TradeItem.class);
Root<TradeItem> root = cq.from(TradeItem.class);
List<Predicate> predicates = new LinkedList<>();
predicates.add(criteriaBuilder.equal(root.get("league"), request.getLeague()));
if(request.getName() != null){
predicates.add(criteriaBuilder.like(root.get("name"), "%"+request.getName()+"%"));
}
if(request.getType() != null){
predicates.add(criteriaBuilder.equal(root.get("type"), request.getType()));
}
if(request.getBase() != null) {
predicates.add(criteriaBuilder.equal(root.get("base"), request.getBase()));
}
if(request.getIdentified() != null){
predicates.add(criteriaBuilder.equal(root.get("identified"), request.getIdentified()));
}
if(request.getCorrupted() != null){
predicates.add(criteriaBuilder.equal(root.get("corrupted"), request.getCorrupted()));
}
if(request.getMods().size() > 0) {
Join<TradeItem, Mod> mod = root.joinSet("mod");
for (ModRequest m : request.getMods()) {
predicates.add(
criteriaBuilder.and(
criteriaBuilder.equal(mod.get("modName"), m.getName()),
criteriaBuilder.ge(mod.get("miniValue"), m.getMinValue() == null ? 0 : m.getMinValue()),
criteriaBuilder.le(mod.get("maxiValue"), m.getMaxValue() == null ? 10000 : m.getMaxValue()))
);
}
}
cq.select(root)
.where(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<TradeItem> typedQuery = em.createQuery(cq);
return Optional.of(
typedQuery
.setFirstResult(0)
.setMaxResults(50)
.getResultList());
}
}
基本上我在这里要做的就是我为特定的Tradingforum开发了一个Webscraper。我有一个web应用程序,您可以通过表单搜索论坛项目。现在每个TradingItem包含一组mods(@OneToMany),它们具有不同的名称和值。
当我搜索只有一个或零个mod的项目时,它可以正常工作。但是只要我在搜索表单中添加两个或更多个mod,它就会返回一个空列表。
我是Criteria Api的新手,我的mod-predicates / logic显然有问题。
我正在使用hibernate 5.1.0&amp; MySQL的
我只需将Join移动到for循环中。
for (ModRequest m : request.getMods()) {
Join<TradeItem, Mod> mod = root.joinSet("mod");
predicates.add(
criteriaBuilder.and(
criteriaBuilder.equal(mod.get("modName"), m.getName()),
criteriaBuilder.ge(mod.get("miniValue"), m.getMinValue() == null ? 0 : m.getMinValue()),
criteriaBuilder.le(mod.get("maxiValue"), m.getMaxValue() == null ? 10000 : m.getMaxValue()))
);
}