1单值的实体关联
共享的主键关联:
由主键关联而相关的两张表中的行共享相同的主键值。这种方法的主要困难在于,确保被关联的
实例在保存对象时分配了相同的主键值。
第一步:用xml映射主键关联
第二步:外标识符生成器
如果Address实例被保存,它就需要获取User对象的主键值。你无法启动一个常规的标示符生成器,
假设是数据库序列。用于Address的这个特殊的foreign标示符生成器,必须知道从哪里获取正确
的主键值。
创建Address和User之间的这个标示符绑定,起第一步是双向关联。把一个新的user属性添加
到Address属性:
这个映射让关联变成了双向,constrained="true"声明了把address的主键添加到user主键的外键约束。
现在可以给Address对象使用特殊的foreign标示符生成器了:
(当Address被保存时,从属性中提取主键值。user属性是对User对象的一个引用;因而,插入的主键值与
这个实例的主键值相同。)
需要双向才可以保存成功:
利用注解的共享主键:
JPA用@OneToOne注解支持一对一的实体关联。要映射User类中address的关联为共享主键关联,还需要@PrimaryKeyJoinColumn注解:
JPA规范没有包括处理共享主键生成问题的标准方法,这意味着在保存Address实例的标示符之前,你要负责正确的设置他。
hibernate的扩展注解:
保存:
一对一的外键关联:
不共享主键,而是两表可以有一个外键关系。一张表有着引用被关联表的主键的一个外键列。
(这里用的many-to-one,而不是我们共享主键里面的one-to-one,因为:你不在乎关联的目标端是什么,
因此可以像对待没有多端的対一关联对待他。通过unique来强制说明只存在一的对应关系)
反向属性引用:
插入:
通过注解映射外键:
JPA映射注解也支持基于外键列的实体之间的一对一关系。与前面的非实体类型的区别就是,@JoinColumn替代了
如果需要双向的:
用联接表映射:
表示从Shipment到Item关联的属性成为auction:
(可以在另一端使用相同的方法,吧在合格关联映射为双向。然而,可选的一对一关联大多数时候都是单向的。)
插入:
通过注解映射二级联接表:
插入:
通过注解映射二级联接表(可以连接多个字段):
2多值的实体关联
多值:是指实体引用的为一个集合。
一对多关联是涉及集合的一种最重要的实体关联。如果 简单的双向多对一活一对多能够完成任务时,目前为止我们并不鼓励使用更加
怪异的关联方式。多对多关联始终可以表示为对中间类的两个多对一关联。这个模型通常更容易于扩展,因此我们趋向于不在应用
中使用多对多关联。也要记住:如果不想的话,你不必映射实体的任何集合;你可以始终编写显示查询来替代通过迭代的直接访问。
一对多关联:
1、考虑bag
一般来说,对于一对多的关联,我们认为bag是它最好的方向集合:
因为bag不必维持起元素的索引(如list),或者检查重复的元素(如set),可以添加新元素给bag,而不触发加载。
但是,bag无法同时抓取两个集合(如Item中同时存在bids和imags两个一对多的bag集合)
bag允许重复,但是由于方向映射,hibernate也会忽略它。
配置文件:
插入:
单向和双向的列表:
利用联合表的可选一对多关联:
JPA实现:
多对多关联:
简单的多对多关联:
会生成一个中间表:
JPA实现:
idbag方式:
JPA实现:
带有索引的单向多对多映射:
JPA实现:
双向的多对多关联:
双向关联的一端必须映射为反向,因为你已经对(一个或多个)外键列命名了两次。给双向的多对多关联应用
相同的原则:联接表的每一行都由两个集合元素表示,关联的两端各一个元素。
配置:
插入1:
插入2:
插入3:
JPA实现:
共享的主键关联:
由主键关联而相关的两张表中的行共享相同的主键值。这种方法的主要困难在于,确保被关联的
实例在保存对象时分配了相同的主键值。
第一步:用xml映射主键关联
- <classname="User"
- ....
- <one-to-one name="address"class="Address"cascade="update">
- </one-to-one>
第二步:外标识符生成器
如果Address实例被保存,它就需要获取User对象的主键值。你无法启动一个常规的标示符生成器,
假设是数据库序列。用于Address的这个特殊的foreign标示符生成器,必须知道从哪里获取正确
的主键值。
创建Address和User之间的这个标示符绑定,起第一步是双向关联。把一个新的user属性添加
到Address属性:
- <classname="Address"
- ...
- <one-to-one name="user"class="User"constrained="true"/>
这个映射让关联变成了双向,constrained="true"声明了把address的主键添加到user主键的外键约束。
现在可以给Address对象使用特殊的foreign标示符生成器了:
- <classname="Address"table="ADDRESS">
- <id name="addressId"column="ADDRESS_ID"type="long">
- <generatorclass="foreign">
- <param name="property">user</param>
- </generator>
- </id>
- <property name="street"type="string"column="street"/>
- <property name="city"type="string"column="city"/>
- <one-to-one name="user"class="User"constrained="true"/>
- </class>
(当Address被保存时,从属性中提取主键值。user属性是对User对象的一个引用;因而,插入的主键值与
这个实例的主键值相同。)
需要双向才可以保存成功:
- User user =newUser();
- user.setUserName("test");
- Address address =newAddress("street","city");
- user.setAddress(address);
- //不添加报错:attempted to assign id from null one-to-one property: user
- address.setUser(user);
- Integer msgId = (Integer) session.save(user);
利用注解的共享主键:
JPA用@OneToOne注解支持一对一的实体关联。要映射User类中address的关联为共享主键关联,还需要@PrimaryKeyJoinColumn注解:
- @Entity
- publicclassUserimplementsSerializable {
- @Id
- @GeneratedValue
- privateInteger userId;
- @Column(name="USER_NAME",length=100)
- privateString userName;
- @OneToOne(cascade=CascadeType.PERSIST)
- @PrimaryKeyJoinColumn
- privateAddress address;
JPA规范没有包括处理共享主键生成问题的标准方法,这意味着在保存Address实例的标示符之前,你要负责正确的设置他。
hibernate的扩展注解:
- @Entity
- publicclassAddressimplementsSerializable {
- @Id
- @GeneratedValue(generator="userForeignGenerator")
- @org.hibernate.annotations.GenericGenerator(name="userForeignGenerator",
- strategy="foreign",
- parameters=@Parameter(name="property",value="user"))
- @Column(name="ADDRESS_ID")
- privateInteger addressId;
- privateString street;
- privateString city;
- @OneToOne
- privateUser user;
保存:
- User user =newUser("name");
- Address address =newAddress("street","city");
- user.setAddress(address);
- //不添加报错:attempted to assign id from null one-to-one property: user
- address.setUser(user);
- em.persist(user);
一对一的外键关联:
不共享主键,而是两表可以有一个外键关系。一张表有着引用被关联表的主键的一个外键列。
- <classname="User"table="USER"dynamic-insert="true"dynamic-update="true"
- mutable="false">
- <id name="userId"column="USER_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="userName"type="string"column="user_Name"/>
- <!-- 在User里面添加维护信息,也就是把User作为维护端 -->
- <many-to-one name="address"class="Address"
- column="ADDRESS_ID"unique="true"cascade="save-update"/>
(这里用的many-to-one,而不是我们共享主键里面的one-to-one,因为:你不在乎关联的目标端是什么,
因此可以像对待没有多端的対一关联对待他。通过unique来强制说明只存在一的对应关系)
反向属性引用:
- <classname="Address"table="ADDRESS">
- <id name="addressId"column="ADDRESS_ID"type="integer">
- <generatorclass="native">
- </generator>
- </id>
- <property name="street"type="string"column="street"/>
- <property name="city"type="string"column="city"/>
- <!-- property-ref="address"告诉hibernateAddress -->
- <!-- 基于外键的的唯一约束,一般不建议这么做,这个是不需要的 -->
- <one-to-one name="user"class="User"property-ref="address"/>
插入:
- Address address =newAddress("street","city");
- user.setAddress(address);
- //不需要
- address.setUser(user);
- Integer msgId = (Integer) session.save(user);
通过注解映射外键:
JPA映射注解也支持基于外键列的实体之间的一对一关系。与前面的非实体类型的区别就是,@JoinColumn替代了
- @PrimaryKeyJoinColumn.
- @Entity
- publicclassUserimplementsSerializable {
- @Id
- @GeneratedValue
- privateInteger userId;
- @Column(name="USER_NAME",length=100)
- privateString userName;
- @OneToOne(cascade=CascadeType.PERSIST)
- //加入一个外键关联字段
- @JoinColumn(name="ADDRESS_ID")
- privateAddress address
如果需要双向的:
- @Entity
- publicclassAddressimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="ADDRESS_ID")
- privateInteger addressId;
- privateString street;
- privateString city;
- //如果需要双向的
- //表示被User里面的address字段进行关联管理
- //mappedBy相当于xml的property-ref="address"(关联的一个简单的方向声明,就是在目标实体段指定了一种属性)
- //加上他,在数据库上是没有任何影响的,紧紧是告诉JPA容器一种关系
- @OneToOne(mappedBy="address")
- privateUser user;
用联接表映射:
表示从Shipment到Item关联的属性成为auction:
- <classname="Shipment"table="Shipment">
- <id name="shipmentId"column="SHIPMENT_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="money"type="double"column="MONEY"/>
- <!-- 因为必须用一个外键列 映射这个关联,因此在XML中你需要
- <many-to-one>映射元素。然而,外键列不在SHIPMENT表中,
- 而在ITEM_SHIPMENT连接表中。通过<join>映射元素把它移动到那里。 -->
- <!-- cascade="save-update":不添加报错object references an unsavedtransientinstance - save thetransientinstance before flushing: -->
- <join table="ITEM_SHIPMENT"optional="true">
- <key column="SHIPMENT_ID"/>
- <many-to-one name="auction"column="ITEM_ID"class="Item"
- not-null="true"unique="true"
- cascade="save-update"></many-to-one>
- </join>
- </class>
(可以在另一端使用相同的方法,吧在合格关联映射为双向。然而,可选的一对一关联大多数时候都是单向的。)
插入:
- Shipment shipment =newShipment(12D);
- Item item =newItem("hello");
- shipment.setAuction(item);
- session.persist(shipment);
通过注解映射二级联接表:
- @Entity
- publicclassShipmentimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="SHIPMENT_ID")
- privateInteger shipmentId;
- privateDouble money;
- @OneToOne(cascade=CascadeType.PERSIST)
- //和外键关联的区别就是那个是加入的字段@JoinColumn(name="ADDRESS_ID")
- //和hibernate的区别就是joinColumns替代了key,inverseJoinColumns替代了many-to-one
- //@JoinTable加入维护表,且本实体为维护端
- @JoinTable(name="ITEM_SHIPMENT",
- joinColumns=@JoinColumn(name="SHIPMENT_ID"),
- inverseJoinColumns=@JoinColumn(name="ITEM_ID"))
- privateItem auction;
插入:
- Shipment shipment =newShipment(12D);
- Item item =newItem("hello");
- shipment.setAuction(item);
- em.persist(shipment);
通过注解映射二级联接表(可以连接多个字段):
- @Entity
- //相当于前面的<key column="..."/>和@JoinTable中的joinColumn()。如果没指定名称,那么就会默认使用主键SHIPMENT_ID
- @SecondaryTable(name="ITEM_SHIPMENT")
- publicclassShipmentimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="SHIPMENT_ID")
- privateInteger shipmentId;
- privateDouble money;
- @ManyToOne(cascade=CascadeType.PERSIST)
- @JoinColumn(table="ITEM_SHIPMENT",name="ITEM_ID")
- privateItem auction;
2多值的实体关联
多值:是指实体引用的为一个集合。
一对多关联是涉及集合的一种最重要的实体关联。如果 简单的双向多对一活一对多能够完成任务时,目前为止我们并不鼓励使用更加
怪异的关联方式。多对多关联始终可以表示为对中间类的两个多对一关联。这个模型通常更容易于扩展,因此我们趋向于不在应用
中使用多对多关联。也要记住:如果不想的话,你不必映射实体的任何集合;你可以始终编写显示查询来替代通过迭代的直接访问。
一对多关联:
1、考虑bag
一般来说,对于一对多的关联,我们认为bag是它最好的方向集合:
因为bag不必维持起元素的索引(如list),或者检查重复的元素(如set),可以添加新元素给bag,而不触发加载。
但是,bag无法同时抓取两个集合(如Item中同时存在bids和imags两个一对多的bag集合)
bag允许重复,但是由于方向映射,hibernate也会忽略它。
配置文件:
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- <bag name="bids"inverse="true"cascade="save-update">
- <!-- 注意column="ITEM_ID_M"名称故意和Item主键不一致,这里是维护端生成的字段名称 -->
- <key column="ITEM_ID_M"></key>
- <one-to-manyclass="Bid"/>
- </bag>
- </class>
- <classname="Bid"table="BID">
- <id name="bidId"column="BID_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="bidMoeny"type="double"></property>
- <!-- 注意column="ITEM_ID_M"名称故意和Item主键不一致,这里是说明一的一端的表,需要生成的对应关联字段是什么
- KEY `FK100DD8434F24F` (`ITEM_ID_M`),
- CONSTRAINT `FK100DD8434F24F` FOREIGN KEY (`ITEM_ID_M`) REFERENCES `item` (`ITEM_ID`) -->
- <many-to-one name="item"column="ITEM_ID_M"
- class="Item"not-null="true"></many-to-one>
- </class>
插入:
- Item item =newItem("hello");
- Bid bid =newBid(12D);
- item.getBids().add(bid);
- //不添加这个报错:not-null property references a null or transient value
- bid.setItem(item);
- session.save(item);
单向和双向的列表:
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- <!-- 没有在集合中加入inverse="true,因为hibernate忽略反向集合的状态!
- 但是这一次,集合包含了正确的更新数据库所需要的信息:它的元素的位置。
- 如果只有每个Bid实例的状态被认为是同步的,集合又是方向的并且被忽略,
- 那么hibernate就没有值给BID_POSITOIN了-->
- lt;list name="bids"cascade="save-update">
- <key column="ITEM_ID"not-null="true"></key>
- <list-index column="BID_POSITOIN"></list-index>
- <one-to-manyclass="Bid"/>
- lt;/list>
- </class>
- <classname="Bid"table="BID">
- <id name="bidId"column="BID_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="bidMoeny"type="double"></property>
- <!-- 如果通过被索引的集合映射双向的一对多实体关联(映射和数组也是这样),
- 就必须转换为方向段。无法被索引的集合变成inverse="true"。集合变成了
- 负责状态同步,并且一的端Bid必须变成反向。然而,多对一的映射没有
- inverse="true",因此需要在<many-to-one>中模拟这一模拟这一属性:
- 设置insert="false"update="false"
- 这俩个属性一起使用,实际上使属性变成了只读。关联的这一端因此被任何写操作忽略,
- 当内存状态与数据库同步时,集合的状态就是相关的状态。你已经转换了关联的方向/非方向端,
- 如果从set或者bag转换为list,这个是必要的条件。
- -->
- <many-to-one name="item"column="ITEM_ID_M"
- class="Item"not-null="true"
- insert="false"update="false"></many-to-one>
- </class>
利用联合表的可选一对多关联:
- <classname="User"table="USER">
- <id name="userId"column="USER_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="userName"type="string"column="USER_NAME"/>
- <set name="items"table="ITEM_USER">
- <key column="USER_ID"></key>
- <many-to-manyclass="Item"column="ITEM_ID"unique="true"></many-to-many>
- </set>
- </class>
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- <join table="ITEM_USER"optional="true"
- inverse="true">
- <key column="ITEM_ID"unique="true"not-null="true"></key>
- <many-to-one name="user"column="USER_ID"></many-to-one>
- </join>
- </class>
JPA实现:
- @Entity
- publicclassUserimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="USER_ID")
- privateInteger userId;
- @Column(name="USER_NAME",length=100)
- privateString userName;
- @OneToMany(mappedBy="user")
- privateSet<Item> items =newHashSet<Item>();
- @Entity
- publicclassItemimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="ITEM_ID")
- privateInteger itemId;
- @Column(name="ITEM_NAME",length=100)
- privateString itemName;
- @ManyToOne
- @JoinTable(name="ITEM_USER",
- joinColumns=@JoinColumn(name="ITEM_ID"),
- inverseJoinColumns=@JoinColumn(name="USER_ID"))
- privateUser user;
多对多关联:
简单的多对多关联:
会生成一个中间表:
- <classname="Category"table="Category">
- <id name="categoryId"column="CATEGORY_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="name"type="string"column="name"/>
- <set name="items"table="CATEGORY_ITEM">
- <key column="CATEGORY_ID"></key>
- <many-to-manyclass="Item"column="ITEM_ID"></many-to-many>
- </set>
- </class>
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- </class>
JPA实现:
- @Entity
- publicclassItemimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="ITEM_ID")
- privateInteger itemId;
- @Column(name="ITEM_NAME",length=100)
- privateString itemName;
- @Entity
- publicclassCategoryimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="CATEGORY_ID")
- privateInteger categoryId;
- @Column(length=100)
- privateString name;
- @ManyToMany
- @JoinTable(name="CATEGORY_ITEM",
- joinColumns=@JoinColumn(name="CATEGORY_ID"),
- inverseJoinColumns=@JoinColumn(name="ITEM_ID"))
- privateSet<Item> items =newHashSet<Item>();
idbag方式:
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- </class>
- <classname="Category"table="Category">
- <id name="categoryId"column="CATEGORY_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="name"type="string"column="name"/>
- lt;idbag name="items"table="CATEGORY_ITEM">
- <collection-id type="integer"column="CATEGORY_ITEM_ID">
- <generatorclass="native"></generator>
- </collection-id>
- <key column="CATEGORY_ID"></key>
- <many-to-many column="ITEM_ID"class="Item"></many-to-many>
- lt;/idbag>
- </class>
JPA实现:
- @Id
- @GeneratedValue
- @Column(name="ITEM_ID")
- privateInteger itemId;
- @Column(name="ITEM_NAME")
- privateString itemName;
- @Id
- @GeneratedValue
- @Column(name="CATEGORY_ID")
- privateInteger categoryId;
- @Column(length=100)
- privateString name;
- @ManyToMany
- @CollectionId(columns=@Column(name="CATEGORY_ITEM_ID"),
- type=@Type(type="integer"),
- generator="native")
- @JoinTable(name="CATEGORY_ITEM",
- joinColumns=@JoinColumn(name="CATEGORY_ID"),
- inverseJoinColumns=@JoinColumn(name="ITEM_ID"))
- privateCollection<Item> items =newArrayList<Item>();
带有索引的单向多对多映射:
- <classname="Category"table="Category">
- <id name="categoryId"column="CATEGORY_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="name"type="string"column="name"/>
- lt;list name="items"table="CATEGORY_ITEM"cascade="save-update">
- <key column="CATEGORY_ID"></key>
- <list-index column="POSISTION"></list-index>
- <many-to-manyclass="Item"column="ITEM_ID"></many-to-many>
- lt;/list>
- </class>
JPA实现:
- @Entity
- publicclassCategoryimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="CATEGORY_ID")
- privateInteger categoryId;
- @Column(length=100)
- privateString name;
- @ManyToMany
- @IndexColumn(name="POSITION")
- @JoinTable(name="CATEGORY_ITEM",
- joinColumns=@JoinColumn(name="CATEGORY_ID"),
- inverseJoinColumns=@JoinColumn(name="ITEM_ID"))
- privateList<Item> items =newArrayList<Item>();
双向的多对多关联:
双向关联的一端必须映射为反向,因为你已经对(一个或多个)外键列命名了两次。给双向的多对多关联应用
相同的原则:联接表的每一行都由两个集合元素表示,关联的两端各一个元素。
配置:
- <classname="Item"table="ITEM">
- <id name="itemId"column="ITEM_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="itemName"type="string"column="ITEM_NAME"/>
- <set name="categories"table="CATEGORY_ITEM"cascade="save-update">
- <key column="ITEM_ID"></key>
- <many-to-many column="CATEGORY_ID"class="Category"></many-to-many>
- </set>
- </class>
- <classname="Category"table="Category">
- <id name="categoryId"column="CATEGORY_ID"type="integer">
- <generatorclass="native"/>
- </id>
- <property name="name"type="string"column="name"/>
- <set name="items"table="CATEGORY_ITEM"inverse="true"cascade="save-update">
- <key column="CATEGORY_ID"></key>
- <many-to-many column="ITEM_ID"class="Item"></many-to-many>
- </set>
- </class>
插入1:
- Item item =newItem("item");
- Category category1 =newCategory("category1");
- item.getCategories().add(category1);
- Category category2 =newCategory("category2");
- item.getCategories().add(category2);
- session.save(item);
- //Hibernate: insert into ITEM (ITEM_NAME) values (?)
- //Hibernate: insert into Category (name) values (?)
- //Hibernate: insert into Category (name) values (?)
- //Hibernate: insert into CATEGORY_ITEM (ITEM_ID, CATEGORY_ID) values (?, ?)
- //Hibernate: insert into CATEGORY_ITEM (ITEM_ID, CATEGORY_ID) values (?, ?)
插入2:
- Item item1 =newItem("item1");
- category.getItems().add(item1);
- Item item2 =newItem("item1");
- category.getItems().add(item2);
- session.save(category);
- //inverse="true"的一端,忽略对中间库的影响
- //Hibernate: insert into Category (name) values (?)
- //Hibernate: insert into ITEM (ITEM_NAME) values (?)
- //Hibernate: insert into ITEM (ITEM_NAME) values (?)
插入3:
- Category category =newCategory("category1");
- Item item1 =newItem("item1");
- category.getItems().add(item1);
- Item item2 =newItem("item1");
- category.getItems().add(item2);
- //必须存在,才会影响中间表,因为inverse="false"的一端,才会影响中间库的变化
- item1.getCategories().add(category);
- item2.getCategories().add(category);
- session.save(category);
- //Hibernate: insert into Category (name) values (?)
- //Hibernate: insert into ITEM (ITEM_NAME) values (?)
- //Hibernate: insert into ITEM (ITEM_NAME) values (?)
- //Hibernate: insert into CATEGORY_ITEM (ITEM_ID, CATEGORY_ID) values (?, ?)
- //Hibernate: insert into CATEGORY_ITEM (ITEM_ID, CATEGORY_ID) values (?, ?)
JPA实现:
- @Entity
- publicclassItemimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="ITEM_ID")
- privateInteger itemId;
- @Column(name="ITEM_NAME",length=100)
- privateString itemName;
- @ManyToMany
- @JoinTable(name="CATEGORY_ITEM",
- joinColumns=@JoinColumn(name="ITEM_ID"),
- inverseJoinColumns=@JoinColumn(name="CATEGORY_ID"))
- privateSet<Category> categories =newHashSet<Category>();
- @Entity
- publicclassCategoryimplementsSerializable {
- @Id
- @GeneratedValue
- @Column(name="CATEGORY_ID")
- privateInteger categoryId;
- @Column(length=100)
- privateString name;
- //被维护端(反相端),只需要简单的生命一下mappedBy,相当于inverse="true"
- @ManyToMany(mappedBy="categories")
- privateSet<Item> items =newHashSet<Item>();