2、到底在哪用inverse="ture"?
“set的inverse属性决定是否把对set的改动反映到数据库中去。inverse=false————反映;inverse=true————不反映”inverse属性默认为false
inverse属性默认是false的,就是说关系的两端都来维护关系。这个意思就是说,如有一个Student, Teacher和TeacherStudent表,Student和Teacher是多对多对多关系,这个关系由TeacherStudent这个表来表 现。那么什么时候插入或删除TeacherStudent表中的记录来维护关系呢?在用hibernate时,我们不会显示的对 TeacherStudent表做操作。对TeacherStudent的操作是hibernate帮我们做的。hibernate就是看hbm文件中指 定的是"谁"维护关系,那个在插入或删除"谁"时,就会处发对关系表的操作。前提是"谁"这个对象已经知道这个关系了,就是说关系另一头的对象已经set 或是add到"谁"这个对象里来了。前面说过inverse默认是false,就是关系的两端都维护关系,对其中任一个操作都会处发对表系表的操作。当在 关系的一头,如Student中的bag或set中用了inverse="true"时,那就代表关系是由另一关维护的(Teacher)。就是说当这插 入Student时,不会操作TeacherStudent表,即使Student已经知道了关系。只有当Teacher插入或删除时才会处发对关系表的 操作。所以,当关系的两头都用inverse="true"是不对的,就会导致任何操作都不处发对关系表的操作。当两端都是inverse= "false"或是default值是,在代码对关系显示的维护也是不对的,会导致在关系表中插入两次关系。
在一对多关系中inverse就更有意义了。在多对多中,在哪端inverse="true"效果差不多(在效率上)。但是在一对多中,如果要一方维护关 系,就会使在插入或是删除"一"方时去update"多"方的每一个与这个"一"的对象有关系的对象。而如果让"多"方面维护关系时就不会有update 操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。当然这时也要遍历"多"方的每一个对象显示的操作修关系的变化体现到DB中。不管 怎样说,还是让"多"方维护关系更直观一些。
(1)对one-to-many而言,改变set,会让hibernate执行一系列的update语句, 不会delete/insert数据
(2)对many-to-many而言,改变set,只修改关系表的数据,不会影响many-to-many的另一方。
(3)虽然one-to-many和many-to-many的数据库操作不一样,但目的都是一个:维护数据的一致性。 (转)
我自己的理解,上代码:
Person类
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.hibernate.tutorial.domain.Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="age"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="PERSON_EVENT" >
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="org.hibernate.tutorial.domain.Event"/>
</set>
<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
<key column="PERSON_ID" />
<element type="string" column="EMAIL_ADDR"/>
</set>
</class>
</hibernate-mapping>
---------------------------------------------------------------------------
package org.hibernate.tutorial.domain;
import java.util.HashSet;
import java.util.Set;
public class Person {
private Long id;
private int age;
private String firstname;
private String lastname;
private Set events = new HashSet();
private Set emailAddresses = new HashSet();
public Person() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
public Set getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set emailAddresses) {
this.emailAddresses = emailAddresses;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
Event类
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.hibernate.tutorial.domain.Event" table="EVENTS" >
<id name="id" type="java.lang.Long">
<column name="EVENT_ID" />
<generator class="identity" />
</id>
<property name="title" type="java.lang.String">
<column name="TITLE" length="2000">
</column>
</property>
<property name="date" type="java.util.Date">
<column name="DATE" />
</property>
<set name="participants" table="PERSON_EVENT" inverse="true">
<key column="EVENT_ID"/>
<many-to-many column="PERSON_ID" class="org.hibernate.tutorial.domain.Person"/>
</set>
</class>
</hibernate-mapping>
package org.hibernate.tutorial.domain;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Event {
private Long id;
private String title;
private Date date;
private Set participants = new HashSet();
public Event() {
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Set getParticipants() {
return participants;
}
public void setParticipants(Set participants) {
this.participants = participants;
}
}
Person和Event 是many-to-many关系,以上两张表是由PERSON_EVENT做关联。 Event 映射文件设置了inverse="true",那么所有对表PERSON_EVENT表的新增删除更新都有由Person对象来完成。而 Event 对象上任何操作都无效(删除时候会报错)。