hibernate.hbm.xml 中对多对多双向关联的 中inverse镜像的使用

来源:互联网 发布:mac select 会员申请 编辑:程序博客网 时间:2024/05/21 10:59

1.3.5.  双向关联

接下来我们将映射双向关联(bi-directional association)- 在Java里让person和event可以从关联的任何一端访问另一端。当然,数据库schema没有改变,我们仍然需要多对多的阶数。一个关系型数据库要比网络编程语言 更加灵活,所以它并不需要任何像导航方向(navigation direction)的东西 - 数据可以用任何可能的方式进行查看和获取。

首先,把一个参与者(person)的集合加入Event类中:

private Set participants = new HashSet();public Set getParticipants() {    return participants;}public void setParticipants(Set participants) {    this.participants = participants;}

Event.hbm.xml里面也映射这个关联。

<set name="participants" table="PERSON_EVENT" inverse="true">    <key column="EVENT_ID"/>    <many-to-many column="PERSON_ID" class="events.Person"/></set>

如你所见,两个映射文件里都有普通的set映射。注意在两个映射文件中,互换了keymany-to-many的字段名。这里最重要的是Event映射文件里增加了set元素的inverse="true"属性。

这意味着在需要的时候,Hibernate能在关联的另一端 - Person类得到两个实体间关联的信息。这将会极大地帮助你理解双向关联是如何在两个实体间被创建的。  




  使双向连起来

首先请记住,Hibernate并不影响通常的Java语义。 在单向关联的例子中,我们是怎样在PersonEvent之间创建联系的?我们把Event实例添加到Person实例内的event引用集合里。因此很显然,如果我们要让这个关联可以双向地工作,我们需要在另外一端做同样的事情 - 把Person实例加入Event类内的Person引用集合。这“在关联的两端设置联系”是完全必要的而且你都得这么做。

许多开发人员防御式地编程,创建管理关联的方法来保证正确的设置了关联的两端,比如在Person里:

protected Set getEvents() {    return events;}protected void setEvents(Set events) {    this.events = events;}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);}

注意现在对于集合的get和set方法的访问级别是protected - 这允许在位于同一个包(package)中的类以及继承自这个类的子类可以访问这些方法,但禁止其他任何人的直接访问,避免了集合内容的混乱。你应尽可能地在另一端也把集合的访问级别设成protected。

inverse映射属性究竟表示什么呢?对于你和Java来说,一个双向关联仅仅是在两端简单地正确设置引用。然而,Hibernate并没有足够的信息去正确地执行INSERTUPDATE语句(以避免违反数据库约束),所以它需要一些帮助来正确的处理双向关联。把关联的一端设置为inverse将告诉Hibernate忽略关联的这一端,把这端看成是另外一端的一个镜象(mirror)。这就是所需的全部信息,Hibernate利用这些信息来处理把一个有向导航模型转移到数据库schema时的所有问题。你只需要记住这个直观的规则:所有的双向关联需要有一端被设置为inverse。在一对多关联中它必须是代表多(many)的那端。而在多对多(many-to-many)关联中,你可以任意选取一端,因为两端之间并没有差别。

0 0
原创粉丝点击