孙卫琴的《精通JPA与Hibernate》的读书笔记:区分持久化类的值类型和实体类型的属性

如果Address类没有OID,那它就是组件类。由于Address类没有OID,因此不能通过EntityManager或Session来单独保存、更新、删除或加载一个Address对象。例如,以下每行代码都会抛出IllegalArgumentException异常:

entityManager.find(Address.class,Long.valueOf(1)); 
entityManager.persist(address);
entityManager.remove(address); 

以上代码运行时抛出IllegalArgumentException异常,错误原因为“Unknown entity class: mypack.Address”。

为何称Address类是未知的实体类呢?这是因为Hibernate把持久化类的属性分为两种:值(Value)类型和实体(Entity)类型。

值类型和实体类型的最重要的区别是前者没有OID,不能被单独持久化,它的生命周期依赖于所属的持久化类的对象的生命周期,组件类型就是一种值类型;而实体类型有OID,可以被单独持久化。

假定Customer类有以下属性:

private String name;
private int age;
private Date birthday;

//Customer和Address类是组成关系
private Address homeAddress;
private Address comAddress;

//Customer和Company类是多对一关联关系
private Company currentCompany;

//Customer和Order类是一对多关联关系
private Set orders;

在以上属性中,name、age、birthday、homeAddress及comAddress都是值类型属性,而currentCompany是实体类型属性,orders集合中的Order对象也是实体类型属性。

当删除一个Customer持久化对象时,Hibernate会从数据库中删除所有值类型属性对应的数据,但是实体类型属性对应的数据有可能依然保留在数据库中,也有可能被删除,这取决于是否在设置了级联删除。假如对orders集合设置了级联删除,那么删除Customer对象时,也会删除orders集合中的所有Order对象。假如没有对currentCompany属性设置级联删除,那么删除一个Customer对象时,currentCompany 属性引用的Company对象依然存在。

Address类作为值类型没有OID,因此不能建立从其他持久化类到Address类的关联关系(注意关联是有方向性的)。假如在Customer类中按如下方式映射currentCompany属性和homeAddress属性:

@ManyToOne
@JoinColumn(name="COMPANY_ID")
Company currentCompany;

@OneToOne
Address homeAddress;

以上代码对currentCompany属性做了正确的映射,但对homeAddress属性的映射是不正确的。以上代码意味着在数据库中,CUSTOMERS表参照Address类所对应的表,而实际上Address类在数据库中根本没有对应的表。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java技术集锦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值