mrblah
mrblah

Reputation: 103477

many-to-many mapping not working, one side is set to inverse

A many-to-many relationship.

The tables:

Product (productId, ...)
Category (categoryId, ...)
Product_Category(productId, categoryId)

I setup the relationship so all updates will be done via the Product entity.

Product Entity:

 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);       
    }

Product.hbm.xml

  <set name="categories" table="product_category" cascade="save-update" lazy="true">
    <key column="productId"/>
    <many-to-many column="categoryId" class="Category"/>
</set>

The Category entity:

private Set<Product> products = new HashSet<Product>();

 /**
     * @return the products
     */
    public Set<Product> getProducts() {
        return products;
    }

Category.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>  

Now I have a loop where I am creating and saving Product entities, and also associating a single category to each.

The product_category table is empty, so I guess I have an issue with my mappings.

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();

}

I also tried first saving the new product, then loading the newly inserted product, and then adding the category and then saving, but same result, the table product_category is empty.

The product table has inserted the new products.

What have I done wrong? There should be rows in both the product_category and product tables, but the product_category is empty.

Update

My HibernateUtil class:

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;
    }


}

Upvotes: 1

Views: 1076

Answers (1)

David M
David M

Reputation: 72840

You must specify the inverse direction when mapping both sides of a relationship using the inverse attribute - cascade is something quite different. Hibernate needs to know which side of the relationship to use to persist the record in the link table (or the foreign key field in the case of a one-many/many-one mapped both ways).

Upvotes: 1

Related Questions