@OneToMany和@ManyToOne双向关系有两个表,如下所示:
@Entity
public class Asset {
private int id;
private int count;
@OneToMany
private Set<Dealing> dealings;
...
}
@Entity
public class Dealing {
private int id;
...
@ManyToOne
@JoinColumn(name = "customer_id", nullable = false, updatable = false)
private Customer customer;
@ManyToOne
@JoinColumn(name = "product_id", nullable = false, updatable = false)
private Product product;
@ManyToOne(cascade = CascadeType.ALL)
private Asset asset;
}
所有内容听起来都不错,但是当我想使用像这样的限制搜索数据时,
session.createCriteria(Asset.class).add(Restrictions.eq("dealings.customer.id", customerId)).add(Restrictions.eq("dealing.product.id", productId)).list();
在这个级别我得到了这个错误,
could not resolve property: dealings.customer of: com.project.foo.model.Asset
其中一个解决方案是改变我的策略,但我浪费时间去发现这个,顺便说一下我对此一无所知,是吗?
答案 0 :(得分:1)
首先,您没有双向OneToMany关联,而是两个不相关的单向关联。在双向OneToMany关联中,必须使用mappedBy
属性将One侧标记为Many侧的反转:
@OneToMany(mappedBy = "asset")
private Set<Dealing> dealings;
其次,对这样的静态查询使用标准API是过度的,导致代码比必要的更难阅读。我只是使用更容易阅读的HQL。标准应该用于动态查询,恕我直言,但不适用于静态查询:
select asset from Asset asset
inner join asset.dealings dealing
where dealing.customer.id = :customerId
and dealing.product.id = :productId
无论您使用的是HQL还是Criteria,都无法使用asset.dealings.customer
,因为asset.dealings
是一个集合。集合没有customer属性。为了能够从Dealing实体引用属性,您需要一个连接,如上面的HQL查询所示。对于Criteria来说也是如此:
Criteria criteria = session.createCriteria(Asset.class, "asset");
criteria.createAlias("asset.dealings", "dealing"); // that's an inner join
criteria.add(Restrictions.eq("dealing.customer.id", customerId);
criteria.add(Restrictions.eq("dealing.product.id", productId);