inverse 与 cascade 是正交的关系,不管 inverse 设置为什么值, 只要 cascade 设置为 “save-update”或者 “all”,当操作 Brand 或 Product 时,相关对象的操作(如果有)也会发生,但关系的建立则要看 inverse的值或者是对哪方进行操作。比如以下的代码,在不同的配置下产生不同的效果:(Brand 与 Product 是一对多的关系)
一、只操作 Brand:
1. Brand b = new Brand();
2. b.setName("brand4");
3.
4. Product p = new Product();
5. p.setName("4p");
6. p.setBrand(b);
7.
8. b.addProduct(p);
session.save(b);
inverse="true",两者的关系由 Product 管理:
1. <set name="products" inverse="true" cascade="save-update">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
输出语句是:
Hibernate: insert into brand_t (f_name) values (?)
Hibernate: insert into product_t (f_name) values (?)
这样的product 的 f_brand_id 为空,即它们之间的关系没有建立起来。
inverse="false",两者的关系由 Brand 管理:
1. <set name="products" inverse="false" cascade="save-update">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
输出语句是:
Hibernate: insert into brand_t (f_name) values (?)
Hibernate: insert into product_t (f_name) values (?)
Hibernate: update product_t set f_brand_id=? where f_id=?
这样两者的关系就建立起来了。
二、看看操作 Product 的情况:
1. Brand b = new Brand();
2. b.setName("brand4");
3.
4. Product p = new Product();
5. p.setName("4p");
6. p.setBrand(b);
7.
8. session.save(p);
1. <many-to-one name="brand"
2. class="model.Brand"
3. cascade="none"
4. column="f_brand_id" />
这时保存会出现org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: model.Brand 的异常,原因是 Brand 还不是一个持久化的东西,如果设置为:
cascade="save-update" 或 "all" ,则同时保存Brand 和 Product,且两者的关系也建立起来。
这时有点不同的是如果加上 b.getProducts().add(p); 这段代码,inverse="false" 的情况下会额外产生一条语句(why?):
Hibernate: update product_t set f_brand_id=? where f_id=?
实际运用当中很多时候都是由多的一方维持两者的关联,一的一方则掌管着多的“生杀大权”。比如:
xml 代码
1. <set name="products" inverse="true" cascade="all">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
1. <many-to-one name="brand"
2. class="model.Brand"
3. cascade="none"
4. column="f_brand_id" />
大家使用的情况又是怎样的呢?
一、只操作 Brand:
1. Brand b = new Brand();
2. b.setName("brand4");
3.
4. Product p = new Product();
5. p.setName("4p");
6. p.setBrand(b);
7.
8. b.addProduct(p);
session.save(b);
inverse="true",两者的关系由 Product 管理:
1. <set name="products" inverse="true" cascade="save-update">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
输出语句是:
Hibernate: insert into brand_t (f_name) values (?)
Hibernate: insert into product_t (f_name) values (?)
这样的product 的 f_brand_id 为空,即它们之间的关系没有建立起来。
inverse="false",两者的关系由 Brand 管理:
1. <set name="products" inverse="false" cascade="save-update">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
输出语句是:
Hibernate: insert into brand_t (f_name) values (?)
Hibernate: insert into product_t (f_name) values (?)
Hibernate: update product_t set f_brand_id=? where f_id=?
这样两者的关系就建立起来了。
二、看看操作 Product 的情况:
1. Brand b = new Brand();
2. b.setName("brand4");
3.
4. Product p = new Product();
5. p.setName("4p");
6. p.setBrand(b);
7.
8. session.save(p);
1. <many-to-one name="brand"
2. class="model.Brand"
3. cascade="none"
4. column="f_brand_id" />
这时保存会出现org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: model.Brand 的异常,原因是 Brand 还不是一个持久化的东西,如果设置为:
cascade="save-update" 或 "all" ,则同时保存Brand 和 Product,且两者的关系也建立起来。
这时有点不同的是如果加上 b.getProducts().add(p); 这段代码,inverse="false" 的情况下会额外产生一条语句(why?):
Hibernate: update product_t set f_brand_id=? where f_id=?
实际运用当中很多时候都是由多的一方维持两者的关联,一的一方则掌管着多的“生杀大权”。比如:
xml 代码
1. <set name="products" inverse="true" cascade="all">
2. <key column="f_brand_id" />
3. <one-to-many class="model.Product"/>
4. set>
1. <many-to-one name="brand"
2. class="model.Brand"
3. cascade="none"
4. column="f_brand_id" />
大家使用的情况又是怎样的呢?