hibernate 共享的主键关联(多个表共享一个主键)

共享的主键关联: 
由主键关联而相关的两张表中的行共享相同的主键值。这种方法的主要困难在于,确保被关联的 
实例在保存对象时分配了相同的主键值。 
第一步:用xml映射主键关联 
  1. <class name="User"   
  2. ....  
  3. <one-to-one name="address" class="Address" cascade="update">  
  4. </one-to-one>  

第二步:外标识符生成器 
如果Address实例被保存,它就需要获取User对象的主键值。你无法启动一个常规的标示符生成器, 
假设是数据库序列。用于Address的这个特殊的foreign标示符生成器,必须知道从哪里获取正确 
的主键值。 
创建Address和User之间的这个标示符绑定,起第一步是双向关联。把一个新的user属性添加 
到Address属性: 
  1. <class name="Address"  
  2. ...  
  3. <one-to-one name="user" class="User" constrained="true"/>  

这个映射让关联变成了双向,constrained="true"声明了把address的主键添加到user主键的外键约束。 
现在可以给Address对象使用特殊的foreign标示符生成器了: 
  1. <class name="Address" table="ADDRESS">  
  2.     <id name="addressId" column="ADDRESS_ID" type="long">  
  3.         <generator class="foreign">  
  4.             <param name="property">user</param>  
  5.         </generator>  
  6.     </id>  
  7.     <property name="street" type="string" column="street"/>  
  8.     <property name="city" type="string" column="city"/>  
  9.     <one-to-one name="user" class="User" constrained="true"/>  
  10. </class>  

(当Address被保存时,从属性中提取主键值。user属性是对User对象的一个引用;因而,插入的主键值与 
这个实例的主键值相同。) 
需要双向才可以保存成功: 
  1. User user = new User();  
  2. user.setUserName("test");  
  3.   
  4. Address address = new Address("street""city");  
  5.   
  6. user.setAddress(address);  
  7. //不添加报错:attempted to assign id from null one-to-one property: user  
  8. address.setUser(user);  
  9.   
  10. Integer msgId = (Integer) session.save(user);  
  11.   





利用注解的共享主键: 
JPA用@OneToOne注解支持一对一的实体关联。要映射User类中address的关联为共享主键关联,还需要@PrimaryKeyJoinColumn注解: 
  1. @Entity  
  2. public class User implements Serializable {  
  3.     @Id  
  4.     @GeneratedValue  
  5.     private Integer userId;  
  6.     @Column(name="USER_NAME",length=100)  
  7.     private String userName;  
  8.     @OneToOne(cascade=CascadeType.PERSIST)  
  9.     @PrimaryKeyJoinColumn  
  10.     private Address address;   

JPA规范没有包括处理共享主键生成问题的标准方法,这意味着在保存Address实例的标示符之前,你要负责正确的设置他。 
hibernate的扩展注解: 
  1. @Entity  
  2. public class Address implements Serializable {  
  3.     @Id  
  4.     @GeneratedValue(generator="userForeignGenerator")  
  5.     @org.hibernate.annotations.GenericGenerator(name="userForeignGenerator",  
  6.             strategy="foreign",  
  7.             parameters=@Parameter(name="property",value="user"))  
  8.     @Column(name="ADDRESS_ID")        
  9.     private Integer addressId;  
  10.     private String street;  
  11.     private String city;  
  12.     @OneToOne  
  13.     private User user;    

保存: 
  1. User user = new User("name");  
  2.         Address address = new Address("street""city");  
  3.         user.setAddress(address);  
  4.         //不添加报错:attempted to assign id from null one-to-one property: user  
  5.         address.setUser(user);  
  6.           
  7.         em.persist(user);   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值