多对多关系。
表格:
Product (productId, ...)
Category (categoryId, ...)
Product_Category(productId, categoryId)
我设置了关系,以便所有更新都将通过产品实体完成。
产品实体:
private Set<Category> categories = new HashSet<Category>();
public void AddCategory(Category category)
{
if(!this.categories.contains(category))
this.categories.add(category);
if(!category.getProducts().contains(this))
category.getProducts().add(this);
}
public void RemoveCategory(AMCategory category)
{
if(categories.contains(category))
categories.remove(category);
if(category.getProducts().contains(this))
category.getProducts().remove(this);
}
产品.hbm.xml
<set name="categories" table="product_category" cascade="save-update" lazy="true">
<key column="productId"/>
<many-to-many column="categoryId" class="Category"/>
</set>
类别实体:
private Set<Product> products = new HashSet<Product>();
/**
* @return the products
*/
public Set<Product> getProducts() {
return products;
}
类别.hbm.xml:
<set name="Products" table="product_category" cascade="none" inverse="true" lazy="true">
<key column="categoryId"/>
<many-to-many column="productId" class="Product"/>
</set>
现在我有一个循环,我可以在其中创建和保存产品实体,并将单个类别与每个实体相关联。
product_category 表为空,所以我猜我的映射有问题。
forloop
{
Product p = new Product();
// set all properties
Category c = DAO.GetCategory(someId);
p.AddCategory(c);
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(p);
session.getTransaction().commit();
}
我还尝试先保存新产品,然后加载新插入的产品,然后添加类别,然后保存,但结果相同,表product_category为空。
产品表已插入新产品。
我做错了什么? Product_category 和 Product 表中都应该有行,但 Product_category 为空。
更新
我的 HibernateUtil 类:
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
return configuration.buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
最佳答案
使用 inverse
属性映射关系的两侧时,您必须指定相反的方向 - cascade
是完全不同的东西。 Hibernate 需要知道使用关系的哪一侧来保存链接表中的记录(或者在一对多/多一双向映射的情况下的外键字段)。
关于java - 多对多映射不起作用,一侧设置为反向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2029301/