Hibernate annotation@OneToOne共享主键关联

http://javne.iteye.com/blog/407123

文章表article表,文章内容表:article_data表

article_data表的主键同时也是外键对应的值是article表的主键

SQL:

Sql代码   收藏代码
  1. CREATE TABLE `article` (                                 
  2.            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,         
  3.            `title` varchar(145) NOT NULL,                         
  4.            `sub_title` varchar(145) NOT NULL,                     
  5.            `add_time` datetime NOT NULL,                          
  6.            PRIMARY KEY (`id`)                                     
  7.          ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8  
  8.   
  9.   
  10. CREATE TABLE `article_data` (                                                              
  11.                 `article_id` int(10) unsigned NOT NULL DEFAULT '0',                                      
  12.                 `content` varchar(2045) NOT NULL DEFAULT '',                                             
  13.                 PRIMARY KEY (`article_id`),                                                              
  14.                 CONSTRAINT `FK_article_data_1` FOREIGN KEY (`article_id`) REFERENCES `article` (`id`)    
  15.               ) ENGINE=InnoDB DEFAULT CHARSET=utf8       

 下面是两个domain类:

IdEntity类:

Java代码   收藏代码
  1. @MappedSuperclass  
  2. public class IdEntity<T extends java.io.Serializable> implements Serializable {  
  3.     private T id;  
  4.     @Id  
  5.     @GeneratedValue(strategy=GenerationType.IDENTITY)  
  6.     public T getId() {  
  7.         return id;  
  8.     }  
  9.   
  10.     public void setId(T id) {  
  11.         this.id = id;  
  12.     }  
  13.     /** 
  14.      * 指示其他某个对象是否与此对象“相等” 
  15.      */  
  16.     @Override  
  17.     public boolean equals(Object obj) {  
  18.         // 自身比较  
  19.         if (obj == this) {  
  20.             return true;  
  21.         }  
  22.         // 类型相同  
  23.         if (obj.getClass() == this.getClass()) {  
  24.             // 当前类反射方法组  
  25.             Method[] thisMethodGroup = this.getClass().getMethods();  
  26.               
  27.             try {  
  28.                 // 遍历反射方法组并提取当前类属性的getter方法  
  29.                 for (Method method : thisMethodGroup) {  
  30.                     // 过滤与当前类属性无关的get方法  
  31.                     if (method.getName().startsWith("get")  
  32.                         && !method.getName().equals("getClass")) {  
  33.                         // 将当前类属性的getter方法与比较类属性的getter方法值作比较  
  34.                         Method currentMethod = obj.getClass().getMethod(method.getName());  
  35.                         // 执行方法以获取返回值比较(关键点:注意参数不相同)  
  36.                         Object objReturnValue = currentMethod.invoke(obj);  
  37.                         Object thisReturnValue = method.invoke(this);  
  38.                         // 空值报异  
  39.                         if (objReturnValue == null) {  
  40.                             System.err.println("异常信息:类" + obj.getClass().getName()   
  41.                                 + "中的" + currentMethod.getName() + "方法为null值!无法进行对象比较!");  
  42.                         }  
  43.                         if (thisReturnValue == null) {  
  44.                             System.err.println("异常信息:类" + this.getClass().getName()   
  45.                                 + "中的" + method.getName() + "方法为null值!无法进行对象比较!");  
  46.                         }  
  47.                         // 返回值不相等则返回逻辑假  
  48.                         if (!objReturnValue.equals(thisReturnValue)) {  
  49.                             return false;  
  50.                         }  
  51.                     }  
  52.                 }                     
  53.             } catch (SecurityException ex) {  
  54.                 System.err.println("异常信息:参数错误,安全管理器检测到安全侵犯!\r\n" + ex.getMessage());  
  55.             } catch (NoSuchMethodException ex) {  
  56.                 System.err.println("异常信息:参数错误,无法找到某一特定的方法!\r\n" + ex.getMessage());  
  57.             } catch (IllegalArgumentException ex) {  
  58.                 System.err.println("异常信息:参数错误,向方法传递了一个不合法或不正确的参数!\r\n" + ex.getMessage());  
  59.             } catch (IllegalAccessException ex) {  
  60.                 System.err.println("异常信息:参数错误,对象定义无法访问,无法反射性地创建一个实例!\r\n" + ex.getMessage());  
  61.             } catch (InvocationTargetException ex) {  
  62.                 System.err.println("异常信息:参数错误,由调用方法或构造方法所抛出异常的经过检查的异常!\r\n" + ex.getMessage());  
  63.             }  
  64.         }  
  65.           
  66.         // 通过不相等比较则返回逻辑真  
  67.         return true;  
  68.           
  69.     }  
  70.   
  71.     /** 
  72.      * 返回该对象的哈希码值 
  73.      */  
  74.     @Override  
  75.     public int hashCode() {  
  76.   
  77.         // 生成简单的位运算hash散列码  
  78.         String key = this.toString();  
  79.         int prime = key.hashCode();  
  80.         int hash = prime;  
  81.         for (int i = 0; i < key.length(); i++) {  
  82.              hash ^= (hash << 23 >> 17) ^ key.charAt(i) * 13131;  
  83.         }  
  84.         // 返回结果  
  85.         return (hash % prime) * 33;  
  86.           
  87.     }  
  88.   
  89.     /** 
  90.      * 返回该对象的字符串表示(类似数组的toString方法输出结果) 
  91.      */  
  92.     @Override  
  93.     public String toString() {  
  94.           
  95.         // 当前类反射方法组  
  96.         Method[] methodGroup = this.getClass().getMethods();  
  97.         // 保存内容  
  98.         StringBuffer content = new StringBuffer("[");  
  99.         // 保存属性的getter方法组  
  100.         List<Method> getMethodGroup = new Vector<Method>();  
  101.           
  102.         try {  
  103.             // 遍历反射方法组并提取属性的getter方法  
  104.             for (Method method : methodGroup) {  
  105.                 // 过滤与属性无关的get方法  
  106.                 if (method.getName().startsWith("get")  
  107.                     && !method.getName().equals("getClass")) {  
  108.                     // 保存属性的getter方法  
  109.                     getMethodGroup.add(method);  
  110.                 }  
  111.             }  
  112.             // 处理仅包含属性的getter方法  
  113.             for (int i = 0; i < getMethodGroup.size(); i++) {  
  114.                 // 执行get方法并拼接获取到的返回值(如果底层方法返回类型为 void,则该调用返回 null)  
  115.                 content.append(getMethodGroup.get(i).invoke(this)   
  116.                     + ((i < getMethodGroup.size() - 1) ? ",\u0020" : "]"));  
  117.             }  
  118.         } catch (IllegalAccessException ex) {  
  119.             System.err.println("异常信息:参数错误,对象定义无法访问,无法反射性地创建一个实例!\r\n" + ex.getMessage());  
  120.         } catch (IllegalArgumentException ex) {  
  121.             System.err.println("异常信息:参数错误,向方法传递了一个不合法或不正确的参数!\r\n" + ex.getMessage());  
  122.         } catch (InvocationTargetException ex) {  
  123.             System.err.println("异常信息:参数错误,由调用方法或构造方法所抛出异常的经过检查的异常!\r\n" + ex.getMessage());  
  124.         }  
  125.           
  126.         // 返回结果  
  127.         return content.toString();  
  128.           
  129.     }  
  130. }  

 Aricle类:

Java代码   收藏代码
  1. @Entity  
  2. @Table(name = "article")  
  3. @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)  
  4. public class Aricle extends IdEntity<Integer> {  
  5.     /** 
  6.      *  
  7.      */  
  8.     private static final long serialVersionUID = -8056490229900614401L;  
  9.     private String title;  
  10.     private String subTitle;  
  11.     private Date addTime;  
  12.   
  13.     private AricleDetail aricleDetail;  
  14.   
  15.     public String getTitle() {  
  16.         return title;  
  17.     }  
  18.   
  19.     public void setTitle(String title) {  
  20.         this.title = title;  
  21.     }  
  22.   
  23.     public String getSubTitle() {  
  24.         return subTitle;  
  25.     }  
  26.   
  27.     public void setSubTitle(String subTitle) {  
  28.         this.subTitle = subTitle;  
  29.     }  
  30.   
  31.     @Temporal(TemporalType.TIMESTAMP)  
  32.     public Date getAddTime() {  
  33.         return addTime;  
  34.     }  
  35.   
  36.     public void setAddTime(Date addTime) {  
  37.         this.addTime = addTime;  
  38.     }  
  39.     @OneToOne(fetch = FetchType.LAZY, optional = false)  
  40.     @PrimaryKeyJoinColumn  
  41.     public AricleDetail getAricleDetail() {  
  42.         return aricleDetail;  
  43.     }  
  44.   
  45.     public void setAricleDetail(AricleDetail aricleDetail) {  
  46.         this.aricleDetail = aricleDetail;  
  47.     }  
  48.   
  49. }  

 

AricleDetail类:

Java代码   收藏代码
  1. @Entity  
  2. @Table(name = "article_data")  
  3. public class AricleDetail {  
  4.     private static final long serialVersionUID = 1782600851147896229L;  
  5.     @Id  
  6.     @GeneratedValue(generator = "pkGenerator")  
  7.     @GenericGenerator(name = "pkGenerator", strategy = "foreign", parameters = @Parameter(name = "property", value = "aricle"))  
  8.     @Column(name = "article_id")  
  9.     private Integer articleId;  
  10.     private String content;  
  11.     @OneToOne(mappedBy="aricleDetail",optional=false)   
  12.     private Aricle aricle;  
  13.   
  14.     public String getContent() {  
  15.         return content;  
  16.     }  
  17.   
  18.     public void setContent(String content) {  
  19.         this.content = content;  
  20.     }  
  21.   
  22.     public Integer getArticleId() {  
  23.         return articleId;  
  24.     }  
  25.   
  26.     public void setArticleId(Integer articleId) {  
  27.         this.articleId = articleId;  
  28.     }  
  29.   
  30.     public Aricle getAricle() {  
  31.         return aricle;  
  32.     }  
  33.   
  34.     public void setAricle(Aricle aricle) {  
  35.         this.aricle = aricle;  
  36.     }  
  37. }  

 

三、具体说明

(参考网络文章)
1.@PrimaryKeyJoinColumn

也可以这样写 @PrimaryKeyJoinColumn(name="id",referencedColumnName="article_id")
    告诉hibernate使用主键作为关联字段 大体相当于@JoinColumn(name="id",referencedColumnName="article_id")
2.@Id
@GeneratedValue(generator = "pkGenerator")
@GenericGenerator(name = "pkGenerator", strategy = "foreign", parameters = @Parameter(name = "property", value = "aricle"))
  
这段注解的意思是 使用当前对象中aricle属性的主键来作为本对象的主键

3.@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    optional很重要 指定关联属性不能为空
    如果想要实现延迟加载就一定要将这个属性设置为false
    这是因为JPA需要知道对应的数据是否存在后 才能决定是创建一个"延迟代理"还是"null引用"
    所以就不得不发起一条SQL请求来验证

参考:

http://exceedsun21320070508164500.iteye.com/blog/370806



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值