有些场景下,有些关系不足以拆分出一个实体,可是若是新建一个对象管理会让代码更清晰,这种场景下用到了内嵌对象。html
一个Teacher
,三个属性,id
、firstName
、lastName
。java
咱们能够直接这么写,也能够建一个内嵌的Name
对象,虽然在一个实体中差异不大,可是若是之后有用到name
的场景,能够直接使用该内嵌对象。app
如下代码省略set
、get
方法:编码
@Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private Name name; }
@Embeddable public class Name { private String firstName; private String lastName; }
启动程序,生成的表结构以下:spa
因此,映射时直接将内嵌对象中的字段添加到该实体中,而后映射到数据表。hibernate
其实说白了就是许多的实体中都有这几个属性,可是根据逻辑关系或复杂度来讲不足以单独创建一个实体,因此使用内嵌对象。设计
就像项目中的不肯定度与测量范围同样,虽然属性很多,不足以单独抽出一个实体,可是又有不少实体去用。code
根据内嵌的原理,咱们能够推断,使用内嵌对象的实体与内嵌对象是一对一的关系时,确定是能够映射的?那若是映射一个List
呢?由于实际业务场景是不许确度,以前都是一对一使用的该内嵌对象,而后需求变更,须要一对多实现。orm
抱着怀疑的态度,咱们尝试一下。htm
@Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private List<Name> names = new ArrayList<>(); }
运行程序,果真报错,应该是咱们映射的方式有问题,去查查官方文档。
官方文档天然是万能的:Collection Mapping - Hibernate
Using annotations you can map Collections, Lists, Maps and Sets of associated entities using @OneToMany and @ManyToMany. For collections of a basic or embeddable type use @ElementCollection.
使用注解映射`Collection`、`List`、`Map`、`Set`,实体使用`@OneToMany`与`@ManyToMany`,基本类型或内嵌类型使用`@ElementCollection`。
@Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @ElementCollection private List<Name> names = new ArrayList<>(); }
运行程序,查看生成的表结构:
teacher
表:
teacher_names
表:
看着彷佛没什么问题,可是设计表会发现teacher_names
是有猫腻的。
内嵌对象集合映射的表没有主键!固然,若是仅仅从teacher
这方面看,这么设计是很合理的。可是并不能知足咱们的需求。
StackOverflow
回答的很是好。
内嵌对象没有id
,若是需求复杂,仍是用实体吧!内嵌对象只适用于该对象十分简单的状况。
因此,如今的需求变成了原内嵌对象不能动,好多实体用到了,而后又须要将内嵌对象变为实体。原问题就是由于内嵌对象没有id
形成的,填个id
就行了。
@Entity public class SuperName { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private Name name; @ManyToOne private Teacher teacher; }
@Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @OneToMany(mappedBy = "teacher") private List<SuperName> superNames = new ArrayList<>(); }
再看表结构,没毛病!
用一个新的注解或编码方式时,首要任务是新建一个项目,而后去各类尝试学会它的应用场景,看别人的博客永远没有本身尝试一遍理会的透彻。
只要没有被官方弃用的东西,都有其存在的价值,只是应用场景不一样而已,永远没有无用的东西,仅仅是由于咱们还没发现。