我有一个设置,许多业主可以拥有猫,每个主人可以拥有几只猫.鉴于此,我想编写一个规范来帮助我找到具有给定所有者名称的所有猫.
这是一个简单的类设置.
@Entity
public class Cat extends AbstractEntity {
@Column
private String name;
}
Run Code Online (Sandbox Code Playgroud)
*没有getters/setters的简洁.Id字段位于超类中.
@Entity
public class Owner extends AbstractEntity {
@Column
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "OWNER_2_CATS",
joinColumns = @JoinColumn(name = "OWNER_ID"),
inverseJoinColumns = @JoinColumn(name = "CAT_ID"))
@OrderColumn(name = "order_column")
private List<Cat> cats = Lists.newArrayList();
}
Run Code Online (Sandbox Code Playgroud)
*没有getters/setters的简洁.Id字段位于超类中.
这里有一个存储库,其中包含一个可以正常工作的查询和一个不起作用的规范.
public interface CatRepository extends AtomicsRepository<Cat, Long> {
// This query works.
@Query("SELECT c FROM Owner o INNER JOIN o.cats c WHERE o.name = ?")
List<Cat> findAllByOwner(String ownerName);
// But how do I accomplish this in a specification?
public static class Specs {
static Specification<Cat> hasOwnerName(final String ownerName) {
return (root, query, cb) -> {
// These next lines don't work! What do I put here?
Root<Owner> owner = query.from(Owner.class);
owner.join("cats");
return cb.equal(owner.get("name"), ownerName);
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
请帮我写规范.
我遇到的问题是,这种关系似乎需要与表达关系的方式相悖:所有者有一个cats列表,但是猫没有owners列表.
Rya*_*son 14
使用此规范的棘手问题在于您查询Cat与所有者没有直接关系.
一般的想法是:
我首选的方法是使用子查询来介绍所有者:
// Subquery using Cat membership in the Owner.cats relation
public static class Specs {
static Specification<Cat> hasOwnerName(final String ownerName) {
return (root, query, cb) -> {
query.distinct(true);
Root<Cat> cat = root;
Subquery<Owner> ownerSubQuery = query.subquery(Owner.class);
Root<Owner> owner = ownerSubQuery.from(Owner.class);
Expression<Collection<Cat>> ownerCats = owner.get("cats");
ownerSubQuery.select(owner);
ownerSubQuery.where(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
return cb.exists(ownerSubQuery);
};
}
}
Run Code Online (Sandbox Code Playgroud)
哪个Hibernate 4.3.x生成SQL查询,如:
select cat0_.id as id1_1_
from cat cat0_
where
exists (
select owner1_.id from owner owner1_ where
owner1_.name=?
and (cat0_.id in (
select cats2_.cat_id from owner_2_cats cats2_ where owner1_.id=cats2_.owner_id
))
)
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用笛卡尔积来介绍所有者:
// Cat membership in the Owner.cats relation using cartesian product
public static class Specs {
static Specification<Cat> hasOwnerName(final String ownerName) {
return (root, query, cb) -> {
query.distinct(true);
Root<Cat> cat = root;
Root<Owner> owner = query.from(Owner.class);
Expression<Collection<Cat>> ownerCats = owner.get("cats");
return cb.and(cb.equal(owner.get("name"), ownerName), cb.isMember(cat, ownerCats));
};
}
}
Run Code Online (Sandbox Code Playgroud)
哪个Hibernate 4.3.x生成SQL查询,如:
select cat0_.id as id1_1_
from cat cat0_
cross join owner owner1_
where
owner1_.name=?
and (cat0_.id in (
select cats2_.cat_id from owner_2_cats cats2_ where owner1_.id=cats2_.owner_id
))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6845 次 |
| 最近记录: |