使用限制获取ManyToOne关系中的数据

时间:2013-01-27 20:55:38

标签: java hibernate orm

@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

其中一个解决方案是改变我的策略,但我浪费时间去发现这个,顺便说一下我对此一无所知,是吗?

1 个答案:

答案 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);