在多对多表中插入之前,hibernate会选择多列

时间:2012-04-06 22:05:58

标签: java hibernate

我有两个实体CustomerProduct,关系为many-to-many

`

@ManyToMany(cascade = CascadeType.MERGE, fetch=FetchType.LAZY)
    @JoinTable(
            name = "customer_products",
            joinColumns={@JoinColumn(name="customer_id")},
            inverseJoinColumns = {@JoinColumn(name="product_id")}) 
    @CollectionId(
            columns = @Column(name="id"),
            type = @Type(type="long"),
            generator = "native"
    )
    public Collection<Product> getProducts() {
        return products;
    }
    public void addProduct(Product product){
        this.products.add(product);
    }
    public void setProducts(Collection<Product> products) {
        this.products = products;
    }

`

我想添加客户产品

`

    Customer customer = (Customer)session.load(Customer.class, new Long(1));
    Product product = (Product) session.load(Product.class, new Long(1));
    customer.addProduct(product);
    session.persist(customer);`

代码的作用是,它选择表CustomerProducts中的所有列,并仅将这些表中的ids插入customer_products表。有没有办法从上表中只选择ids

2 个答案:

答案 0 :(得分:1)

可以从列中检索单独的实体数据,而无需使用JPA / Hibernate实例化整个实体对象。

这与一对一完美配合,但不确定多对多关系:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> q = cb.createQuery(Object[].class);
Root<Customer> c = q.from(Customer.class);
q.select(cb.array(c.get("id"), c.get("products").get("id")));

List<Object[]> results = em.createQuery(q).getResultList();
for (Object[] result : results) {
  System.out.println("Customer id: " + result[0] + ", Product id: " + result[1]);
}

值得一试,可能会让你走上正轨。 Look for more information on JPQL and CriteriaBuilder queries.

顺便说一句,如果你能提供理由,为什么你需要这样做,那么我们可以从新的角度提供替代解决方案,因为现在我们无法理解为什么需要这样做。

答案 1 :(得分:0)

它只是在表中插入id,因为这是您在实体上设置的所有内容,并且您对其他列没有任何not null约束。没有办法直接处理CustomerProduct,只能在没有其他数据的情况下获取其ID。这只是ORM的一部分。

但是,您可以使用native SQL query从数据库中选择单个数据。 This guy也提供了一个很好的SQLQuery用法示例。

<强> 修改

重新阅读你的问题之后,我意识到你说的是id被插入到customer_product表中。所以我的第一段并不正确。它只是插入ID,因为您只是向客户添加产品,而这是您的交叉参考表。

然而,解决方案是一样的。如果只想从customerproduct中选择ID,则需要使用SQL查询。如果您想直接从customer_product中选择ID(这有点奇怪),您需要使用SQL查询或创建CustomerProduct对象(这会更奇怪)。 / p>