`
woshixushigang
  • 浏览: 575825 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

hibernate一对多关系采用外键映射时使用inverse的几种情况

阅读更多

hibernate关系的维护比较头疼,遂总结下做个备份。

什么时候维护关系:当关联双方对象有一方的属性发生变化时。

举例:一个用户有多个账户,类User和类Account是一对多的双向关联关系。

User类:

public class User {

private Long oid;

private String uid;

private String name;

//关联属性

private Set accts = new HashSet();

......

}

Account类:

public class Account {

private Long oid;

private String acctNo;

private double bal;

//关联属性

private User owner;

......

}

mq_user:

mysql> desc mq_user;

+-----------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-----------+--------------+------+-----+---------+----------------+

| OID | bigint(20) | NO | PRI | NULL | auto_increment |

| USER_ID | varchar(255) | NO | UNI | NULL | |

| USER_NAME | varchar(255) | NO | | NULL | |

+-----------+--------------+------+-----+---------+----------------+

mq_acct2

mysql> desc mq_acct2;

+--------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+--------+--------------+------+-----+---------+----------------+

| OID | bigint(20) | NO | PRI | NULL | auto_increment |

| ACCTNO | varchar(255) | NO | UNI | NULL | |

| BAL | double | NO | | NULL | |

| FID | bigint(20) | YES | MUL | NULL | |

+--------+--------------+------+-----+---------+----------------+

映射文件:

User.hbm.xml:

<set name = "accts" inverse = "false" >

<key column="FID" />

<one-to-many class="Account" />

</set>

 

Account.hbm.xml:

<many-to-one name = "owner"

class = "User"

column = "FID"/>

 

 

如果:Session s = HbnUtil.getSession();

s.beginTransaction();

Account acct1 = new Account("a01", 5000.0);

User user = new User("u01","jack");

user.getAccts().add(acct1);

s.save(user);

s.save(acct1);

s.getTransaction().commit();

结果:Hibernate:

insert

into

mq_user

(USER_ID, USER_NAME)

values

(?, ?)

Hibernate:

insert

into

mq_acct2

(ACCTNO, BAL, FID)

values

(?, ?, ?)

Hibernate:

update

mq_acct2

set

FID=?

where

OID=?

 

说明:一对多双向关联中默认多的一方inverse=”false”,也就是说由多的一方维护关系。

这里把一的一方的inverse也改为false,并且在代码中不写acct1.setOwner(user)是为了测试一的一方是如何维护关系的。

在执行了insert into 语句以后,紧接着执行的update语句就是一的一方在维护关系。

从执行的过程还可以看出,维护关系的动作实际上是update而不是insert操作。

总结:1,多的一方总是维护且必须维护关系(many-to-one中没有inverse属性),一的一方可以选择维护或不维护。

---------------------------------------------------------------------

如果:Session s = HbnUtil.getSession();

s.beginTransaction();

Account acct1 = new Account("a01", 5000.0);

User user = new User("u01","jack");

user.getAccts().add(acct1);

s.save(user);

s.getTransaction().commit();

结果:Hibernate:

insert

into

mq_user

(USER_ID, USER_NAME)

values

(?, ?)

Hibernate:

update

mq_user

set

USER_ID=?,

USER_NAME=?

where

OID=?

Hibernate:

update

mq_acct2

set

FID=?

where

OID=?

org.hibernate.TransientObjectException:

 

说明:去掉了对acct1的保存。抛异常。

inverse是关系维护而不是级联操作(通过配置cascade属性可以让user被保存时级联acct1一起被保存),关系维护只会update

总结:2,关系维护只做update,不搞级联,所以要注意维护的数据是否已经在数据库中。

除非做了级联create或者数据库中有被维护的数据,否则是要抛异常滴。

---------------------------------------------------------------------

如果:Account acct1 = new Account("a01", 5000.0);

User user = new User("u01","jack");

user.getAccts().add(acct1);

s.save(user);

s.save(acct1);

user.setName("aaaaa");

结果:Hibernate:

insert

into

mq_user

(USER_ID, USER_NAME)

values

(?, ?)

Hibernate:

insert

into

mq_acct2

(ACCTNO, BAL, FID)

values

(?, ?, ?)

Hibernate:

update

mq_user

set

USER_ID=?,

USER_NAME=?

where

OID=?

Hibernate:

update

mq_acct2

set

FID=?

where

OID=?

说明:因为user是一个持久化对象(session保存过),所以在user属性发生改变时,session会监测user属性是否改变并在改变后自动执行update mq_user。但不管acct1属性是否改变,也不管username改变是否影响到了他和acct1的关系,都会再维护一次。

---------------------------------------------------------------------

如果:Account acct1 = new Account("a01", 5000.0);

User user = new User("u01","jack");

user.getAccts().add(acct1);

s.save(user);

s.save(acct1);

acct1.setBal(999);

结果:

Hibernate:

insert

into

mq_user

(USER_ID, USER_NAME)

values

(?, ?)

Hibernate:

insert

into

mq_acct2

(ACCTNO, BAL, FID)

values

(?, ?, ?)

Hibernate:

update

mq_acct2

set

ACCTNO=?,

BAL=?,

FID=?

where

OID=?

Hibernate:

update

mq_acct2

set

FID=?

where

OID=?

说明:因为acct1是持久化对象,所以session在发现acct1bal发生改变后会自动执行

update mq_acct2语句。随后负责维护关系的user一方会再维护一次关系。

------------------------------------------------------------------------------------

<!--[endif]-->

如果:Account acct1 = new Account("a01", 5000.0);

User user = new User("u01","jack");

user.getAccts().add(acct1);

acct1.setOwner(user);

s.save(user);

s.save(acct1);

acct1.setBal(999);

结果:Hibernate:

insert

into

mq_user

(USER_ID, USER_NAME)

values

(?, ?)

Hibernate:

insert

into

mq_acct2

(ACCTNO, BAL, FID)

values

(?, ?, ?)

Hibernate:

update

mq_acct2

set

ACCTNO=?,

BAL=?,

FID=?

where

OID=?

Hibernate:

update

mq_acct2

set

FID=?

where

OID=?

说明:如果双方是双向关联又各自都维护关系,那么当需要维护时会各自维护一次。

总结:3,实际运行时的对象如果不知道对方对象的存在(没有关联)就不会维护关系。

4,只要任意一方属性变了就维护,不管这个变更是否影响到了关系。

分享到:
评论

相关推荐

    Hibernate映射一对多关联关系

    总结来说,使用Hibernate映射一对多关联关系涉及到实体类的设计、数据库关系模型的构建以及映射文件的编写等多个方面。正确地实现这些步骤可以帮助我们高效地管理和操作数据,提高应用程序的性能和可维护性。

    hibernate外键实现一对一单向关联关系源码

    以上就是关于Hibernate外键实现一对一单向关联关系的详细说明。这个知识点涉及到数据库设计、ORM框架的使用,以及Java编程实践,对于理解和使用Hibernate进行数据库操作具有重要意义。在实践中,应结合具体业务场景...

    Hibernate关联映射-one to one单向外键关联

    本话题主要探讨的是Hibernate中的一种关联映射方式——一对一(One-to-One)单向外键关联。这种关联模式通常用于两个实体之间存在唯一对应的关系,例如一个用户对应一个唯一的账户。 在Hibernate中,一对一关联可以...

    Hibernate一对多主键关联映射源代码

    在Java的持久化框架Hibernate中,一对多关系(OneToMany)是一种常见的对象关系映射(ORM)映射方式,它模拟了数据库中一个表的一条记录与另一表的多条记录之间的关联。本教程通过源代码的形式,讲解如何在Hibernate...

    Hibernate使用 Map实现多对多映射

    在Java的持久化框架Hibernate中,多对多映射是一种常见的关系映射方式,用于处理两个实体类之间一对多或多对一的关系。在这个例子中,我们看到的是`Team`(团队)与`Member`(成员)之间的多对多关系,通过`Map`数据...

    hibernate的多种映射关系

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...

    Hibernate关系映射

    "多对一"关系映射是Hibernate支持的四种基本关联类型之一,包括一对一、一对多、多对一和多对多。本篇将深入探讨“多对一”关系映射的概念、配置以及在实际web系统中的应用。 **一、“多对一”关系映射概念** 在...

    Hibernate一对多单向关联映射

    在Java的持久化框架Hibernate中,一对多关系是常见的实体关联类型,它反映了数据库中一个表的记录可以对应多个另一个表的记录的情况。本篇主要探讨的是如何在Hibernate中实现一对多的单向关联映射。 一、概念理解 ...

    hibernate一对多案例

    本案例主要探讨的是Hibernate中的一对多关系映射,这是一种常见的对象关系映射(ORM)配置,用于表示一个实体与多个其他实体之间的关联。 在传统的数据库设计中,一对多关系是指一个表(父表)中的记录可以与另一个...

    Hibernate一对多映射

    在Java的持久化框架Hibernate中,一对多映射(One-to-Many Mapping)是一种常见的关系映射类型,它反映了数据库中的表与表之间的关联。在这个小实例中,我们将深入理解如何在Hibernate中设置和使用一对多关系,以及...

    hibernate一对多关系

    在数据库设计中,一对多关系是非常常见的一种关系类型,比如一个部门可以有多个员工,一个学生可以选修多门课程等。在Hibernate中,这种关系通过在映射文件或者注解中设置来实现。 首先,我们需要理解一个实体类...

    Hibernate教程11_关系映射之一对多单向关联

    本教程主要探讨的是Hibernate中的一种重要关系映射类型:一对多单向关联。在关系型数据库中,一对多关联是最常见的关系类型,一个实体可以与多个其他实体相关联。在Hibernate中,这种关系可以通过配置XML映射文件或...

    Hibernate映射关系一对多

    通过上述讲解,我们了解了如何在Hibernate中配置和使用一对多映射关系,包括XML映射、注解映射、懒加载、级联操作以及实际应用中的注意事项。希望这些知识能帮助你更好地理解和运用Hibernate进行数据持久化。

    Hibernate的多对一和一对多操作实例

    ### Hibernate的多对一和一对多操作实例:深入解析与应用 #### 1. 多对一和一对多概念解析 在关系型数据库设计中,多对一和一对多是两种非常基础且重要的关联关系类型。多对一指的是多个实体(如订单)与一个实体...

    hibernate双向一对多关联映射(XML)

    在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系数据库模型与对象模型之间的映射方式。这种映射允许在一个实体类中存在多个另一个实体类的实例,而在另一个实体类中也可能存在对第一个实体类的...

    hibernate单向多对多映射(XML版)

    通过这样的配置,Hibernate就能理解`Student`和`Course`之间的多对多关系,并在操作时自动处理关联表的插入、更新和删除。在实际应用中,我们可以通过`Session`接口来添加、删除和查询这种关系。 总结起来,...

    Hibernate(一对多表操作)

    在实际项目中,我们经常需要处理复杂的数据关系,其中一对一、一对多、多对一和多对多是最常见的关联关系。本篇主要讨论的是Hibernate中的一对多关系映射,以及如何在实际操作中进行配置和使用。 一对多关系指的是...

    Hibernate 相关映射关系

    本篇将详细探讨Hibernate中的映射关系,主要包括实体之间的一对一、一对多、多对一和多对多四种关系映射。 1. **一对一映射(One-to-One)** 在一对一映射中,两个实体之间存在唯一的关联。这可以通过`@OneToOne`...

    hibernate一对多映射

    在Java持久化框架Hibernate中,一对多映射(One-to-Many Mapping)是数据库关系模型中常见的关联类型,它表示一个实体(如一个用户)可以与多个其他实体(如订单)相关联。在这个实例中,我们将深入探讨如何在...

Global site tag (gtag.js) - Google Analytics