Hibernate 無主鍵表(複合主鍵)映射

1. 爲何要有複合主鍵映射

在現實中咱們可能會遇到許多表多是沒有主鍵的,那麼咱們對其作映射後使用會是什麼樣的結果?能正常獲得咱們想要的嗎?結果應該是得不到想要的結果,而獲得的可能會是以下的報錯:java

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

這個結果告訴咱們:Hibernate映射表是須要主鍵的。測試

因此複合主鍵映射就應運而生了。this

2. 注意點

複合主鍵使用一個可嵌入的類做爲主鍵表示,所以你須要使用@Id@Embeddable兩個註解.還有一種方式是使用@EmbeddedId註解.固然還有一種方法那就是——使用@IdClass註解。具體請查看【hibernate-annotations-3.4.0.GA 2.2.6.映射覆合主鍵與外鍵】。spa

固然,只須要選擇其中的一種就能夠了。^_^.net

注意所依賴的類必須實現 serializable以及實現equals()/hashCode()方法.hibernate

舉一個具體事例:code

2.1. User.java

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

2.2. UserId.javablog

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


3. 可能還會出現的問題ip

具體來講問題就是查詢出來的結果列表爲‘null’(這一點我此次在我機器上測試時沒有出現)。
若是出現了該問題,那麼看到這一點就應該能解決問題啦,若是不出現那就更好,呵呵!
可是我的以爲這一點應該仍是得說的。^_^
有時候查詢出來的結果列表爲‘null’,這使人非常費解,能夠想下這是什麼緣由?
直接上緣由,嘎嘎……。
緣由:做爲聯合主鍵的字段理論上不該該包含可能爲空的字段。
緣由分析:根據緣由,說明實體Bean中的某個(些)對應的表字段有空值。
解決方案:只須要將可能爲空的字段不做爲聯合主鍵的一部分就能夠。
說的估計暈頭了吧,直接來個事例吧(我的一直以爲,例子是解釋問題的最好說明)。

假設表中的varcName和varcAddress是可能爲空的,其它都不可能爲空,那麼映射應該是這樣的

User.java

  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. public void setVarcName(String varcName) {
  14. this.varcName = varcName;
  15. }
  16. @Column (name="varcAddress", length=50)
  17. public String getVarcAddress() {
  18. return this.varcAddress;
  19. }
  20. public void setVarcAddress(String varcAddress) {
  21. this.varcAddress = varcAddress;
  22. }
……
private UserId id;
private String varcName;
private String varcAddress;
……
/*
這裏加入varcName和varcAddress映射內容,嗯仍是貼出來吧,反正電子檔的又不怕木有地方,嘎嘎……
*/
	@Column(name="varcName", length=50)
    public String getVarcName() {
        return this.varcName;
    }
    
    public void setVarcName(String varcName) {
        this.varcName = varcName;
    }

    @Column(name="varcAddress", length=50)
    public String getVarcAddress() {
        return this.varcAddress;
    }
    
    public void setVarcAddress(String varcAddress) {
        this.varcAddress = varcAddress;
    }


UserId.java

  1. ……
  2. private int intId;
  3. private int intAge;
  4. ……
相關文章
相關標籤/搜索