我有两个实体Customer
和Product
,关系为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);`
代码的作用是,它选择表Customer
和Products
中的所有列,并仅将这些表中的ids
插入customer_products
表。有没有办法从上表中只选择ids
?
答案 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
约束。没有办法直接处理Customer
或Product
,只能在没有其他数据的情况下获取其ID。这只是ORM的一部分。
但是,您可以使用native SQL query从数据库中选择单个数据。 This guy也提供了一个很好的SQLQuery用法示例。
<强> 修改 强>
重新阅读你的问题之后,我意识到你说的是id被插入到customer_product
表中。所以我的第一段并不正确。它只是插入ID,因为您只是向客户添加产品,而这是您的交叉参考表。
然而,解决方案是一样的。如果只想从customer
或product
中选择ID,则需要使用SQL查询。如果您想直接从customer_product
中选择ID(这有点奇怪),您需要使用SQL查询或创建CustomerProduct
对象(这会更奇怪)。 / p>