hibernate 无主键表映射

Hibernate 无主键表(复合主键)映射

1.     为什么要有复合主键映射

在现实中我们可能会遇到许多表可能是没有主键的,那么我们对其做映射后使用会是什么样的结果?能正常得到我们想要的吗?结果应该是得不到想要的结果,而得到的可能会是如下的报错:

Caused by:org.hibernate.AnnotationException: No identifier specified for entity: xxx.xxx.xxx

这个结果告诉我们:Hibernate映射表是需要主键的。

所以复合主键映射就应运而生了。

2.     注意点

复合主键使用一个可嵌入的类作为主键表示,因此你需要使用@Id@Embeddable两个注解.还有一种方式是使用@EmbeddedId注解.当然还有一种方法那就是——使用@IdClass注解。具体请查看【hibernate-annotations-3.4.0.GA 2.2.6.映射复合主键与外键】。

当然,只需要选择其中的一种就可以了。^_^

注意所依赖的类必须实现 serializable以及实现equals()/hashCode()方法.

举一个具体事例:

2.1. User.java

 
[java]  view plain copy
  1. <span style="font-size:12px;">package com.sourcefour.bean;  
  2. // default package  
  3.   
  4. import javax.persistence.AttributeOverride;  
  5. import javax.persistence.AttributeOverrides;  
  6. import javax.persistence.Column;  
  7. import javax.persistence.EmbeddedId;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.Table;  
  10.   
  11.   
  12. /** 
  13.  * User entity. @author MyEclipse Persistence Tools 
  14.  */  
  15. @Entity  
  16. @Table(name="t_user_composite_pk"  
  17. )  
  18.   
  19. public class User  implements java.io.Serializable {  
  20.   
  21.   
  22.     // Fields      
  23.   
  24.      private UserId id;  
  25.   
  26.   
  27.     // Constructors  
  28.   
  29.     /** default constructor */  
  30.     public User() {  
  31.     }  
  32.   
  33.       
  34.     /** full constructor */  
  35.     public User(UserId id) {  
  36.         this.id = id;  
  37.     }  
  38.   
  39.      
  40.     // Property accessors  
  41.     @EmbeddedId  
  42.       
  43.     @AttributeOverrides( {  
  44.         @AttributeOverride(name="intId", column=@Column(name="intId", nullable=false) ),   
  45.         @AttributeOverride(name="varcName", column=@Column(name="varcName", length=50) ),   
  46.         @AttributeOverride(name="varcAddress", column=@Column(name="varcAddress", length=50) ),   
  47.         @AttributeOverride(name="intAge", column=@Column(name="intAge", nullable=false) ) } )  
  48.   
  49.     public UserId getId() {  
  50.         return this.id;  
  51.     }  
  52.       
  53.     public void setId(UserId id) {  
  54.         this.id = id;  
  55.     }  
  56. }  
  57. </span>  

2.2. UserId.java

[java]  view plain copy
  1. <span style="font-size:12px;">package com.sourcefour.bean;  
  2.   
  3. // default package  
  4.   
  5. import javax.persistence.Column;  
  6. import javax.persistence.Embeddable;  
  7.   
  8. /** 
  9.  * UserId entity. @author MyEclipse Persistence Tools 
  10.  */  
  11. @Embeddable  
  12. public class UserId implements java.io.Serializable {  
  13.   
  14.     // Fields  
  15.   
  16.     private int intId;  
  17.     private String varcName;  
  18.     private String varcAddress;  
  19.     private int intAge;  
  20.   
  21.     // Constructors  
  22.   
  23.     /** default constructor */  
  24.     public UserId() {  
  25.     }  
  26.   
  27.     /** minimal constructor */  
  28.     public UserId(int intId, int intAge) {  
  29.         this.intId = intId;  
  30.         this.intAge = intAge;  
  31.     }  
  32.   
  33.     /** full constructor */  
  34.     public UserId(int intId, String varcName, String varcAddress, int intAge) {  
  35.         this.intId = intId;  
  36.         this.varcName = varcName;  
  37.         this.varcAddress = varcAddress;  
  38.         this.intAge = intAge;  
  39.     }  
  40.   
  41.     // Property accessors  
  42.   
  43.     @Column(name = "intId", nullable = false)  
  44.     public int getIntId() {  
  45.         return this.intId;  
  46.     }  
  47.   
  48.     public void setIntId(int intId) {  
  49.         this.intId = intId;  
  50.     }  
  51.   
  52.     @Column(name = "varcName", length = 50)  
  53.     public String getVarcName() {  
  54.         return this.varcName;  
  55.     }  
  56.   
  57.     public void setVarcName(String varcName) {  
  58.         this.varcName = varcName;  
  59.     }  
  60.   
  61.     @Column(name = "varcAddress", length = 50)  
  62.     public String getVarcAddress() {  
  63.         return this.varcAddress;  
  64.     }  
  65.   
  66.     public void setVarcAddress(String varcAddress) {  
  67.         this.varcAddress = varcAddress;  
  68.     }  
  69.   
  70.     @Column(name = "intAge", nullable = false)  
  71.     public int getIntAge() {  
  72.         return this.intAge;  
  73.     }  
  74.   
  75.     public void setIntAge(int intAge) {  
  76.         this.intAge = intAge;  
  77.     }  
  78.   
  79.     public boolean equals(Object other) {  
  80.         if ((this == other))  
  81.             return true;  
  82.         if ((other == null))  
  83.             return false;  
  84.         if (!(other instanceof UserId))  
  85.             return false;  
  86.         UserId castOther = (UserId) other;  
  87.   
  88.         return (this.getIntId() == castOther.getIntId())  
  89.                 && ((this.getVarcName() == castOther.getVarcName()) || (this.getVarcName() != null  
  90.                         && castOther.getVarcName() != null && this.getVarcName().equals(castOther.getVarcName())))  
  91.                 && ((this.getVarcAddress() == castOther.getVarcAddress()) || (this.getVarcAddress() != null  
  92.                         && castOther.getVarcAddress() != null && this.getVarcAddress().equals(  
  93.                         castOther.getVarcAddress()))) && (this.getIntAge() == castOther.getIntAge());  
  94.     }  
  95.   
  96.     public int hashCode() {  
  97.         int result = 17;  
  98.   
  99.         result = 37 * result + this.getIntId();  
  100.         result = 37 * result + (getVarcName() == null ? 0 : this.getVarcName().hashCode());  
  101.         result = 37 * result + (getVarcAddress() == null ? 0 : this.getVarcAddress().hashCode());  
  102.         result = 37 * result + this.getIntAge();  
  103.         return result;  
  104.     }  
  105.   
  106. }</span>  

 


3. 可能还会出现的问题

具体来说问题就是查询出来的结果列表为‘null’(这一点我这次在我机器上测试时没有出现)。
如果出现了该问题,那么看到这一点就应该能解决问题啦,如果不出现那就更好,呵呵!
但是个人觉得这一点应该还是得说的。^_^
有时候查询出来的结果列表为‘null’,这令人很是费解,可以想下这是什么原因?
直接上原因,嘎嘎……。
原因:作为联合主键的字段理论上不应该包含可能为空的字段。
原因分析:根据原因,说明实体Bean中的某个(些)对应的表字段有空值。
解决方案:只需要将可能为空的字段不作为联合主键的一部分就可以。
说的估计晕头了吧,直接来个事例吧(个人一直觉得,例子是解释问题的最好说明)。

假设表中的varcName和varcAddress是可能为空的,其它都不可能为空,那么映射应该是这样的

 

User.java

[java]  view plain copy
  1. ……  
  2. private UserId id;  
  3. private String varcName;  
  4. private String varcAddress;  
  5. ……  
  6. /* 
  7. 这里加入varcName和varcAddress映射内容,嗯还是贴出来吧,反正电子档的又不怕木有地方,嘎嘎…… 
  8. */  
  9.     @Column(name="varcName", length=50)  
  10.     public String getVarcName() {  
  11.         return this.varcName;  
  12.     }  
  13.       
  14.     public void setVarcName(String varcName) {  
  15.         this.varcName = varcName;  
  16.     }  
  17.   
  18.     @Column(name="varcAddress", length=50)  
  19.     public String getVarcAddress() {  
  20.         return this.varcAddress;  
  21.     }  
  22.       
  23.     public void setVarcAddress(String varcAddress) {  
  24.         this.varcAddress = varcAddress;  
  25.     }  


UserId.java

[java]  view plain copy
  1. ……  
  2. private int intId;  
  3. private int intAge;  
  4. ……  

对应文档,demo及sql下载:CSDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值