您好,欢迎访问一九零五行业门户网

Hibernate一对一双向关联(外键关联)用法小结

这几天在改一个项目源码,遇到一个问题坑了很久。场景如下(注:此处是借鉴网络上的例子,并不是自己的实验环境): 一夫一妻制——比如夫妻关系的两张数据表,一个是wif表,一个是husban表,其数据表信息如下: create table `wife` ( `id` int(11) not nul
这几天在改一个项目源码,遇到一个问题坑了很久。场景如下(注:此处是借鉴网络上的例子,并不是自己的实验环境):
一夫一妻制——比如夫妻关系的两张数据表,一个是wif表,一个是husban表,其数据表信息如下:
create table `wife` ( `id` int(11) not null auto_increment, `name` varchar(50) not null, primary key (`id`)) engine=innodb auto_increment=15 default charset=utf8create table `husband` ( `id` int(11) not null auto_increment, `name` varchar(50) not null, `wifeid` int(11) default null, primary key (`id`), key `fk_wife` (`wifeid`), constraint `fk_wife` foreign key (`wifeid`) references `wife` (`id`)) engine=innodb auto_increment=20 default charset=utf8
即一个wife表和一个husband表,这里wife表为基表,husband表中的wifeid依赖于wife的主键id。
下面是相应的pojo:
wife: 1. package com.linys.model; 2. 3. /** 4. * wife entity. @author myeclipse persistence tools 5. */ 6. 7. public class wife implements java.io.serializable { 8. 9. // fields 10. 11. /** 12. * 13. */ 14. private static final long serialversionuid = 1l; 15. private integer id; 16. private string name; 17. private husband husband; 18. // constructors 19. 20. /** default constructor */ 21. public wife() { 22. } 23. 24. /** minimal constructor */ 25. public wife(string name) { 26. this.name = name; 27. } 28. 29. 30. // property accessors 31. 32. public integer getid() { 33. return this.id; 34. } 35. 36. public void setid(integer id) { 37. this.id = id; 38. } 39. 40. public string getname() { 41. return this.name; 42. } 43. 44. public void setname(string name) { 45. this.name = name; 46. } 47. 48. public husband gethusband() { 49. return husband; 50. } 51. 52. public void sethusband(husband husband) { 53. this.husband = husband; 54. } 55. 56. 57. } husband: 1. package com.linys.model; 2. 3. /** 4. * husband entity. @author myeclipse persistence tools 5. */ 6. 7. public class husband implements java.io.serializable { 8. 9. // fields 10. 11. /** 12. * 13. */ 14. private static final long serialversionuid = 1l; 15. private integer id; 16. private wife wife; 17. private string name; 18. 19. // constructors 20. 21. /** default constructor */ 22. public husband() { 23. } 24. 25. /** minimal constructor */ 26. public husband(string name) { 27. this.name = name; 28. } 29. 30. /** full constructor */ 31. public husband(wife wife, string name) { 32. this.wife = wife; 33. this.name = name; 34. } 35. 36. // property accessors 37. 38. public integer getid() { 39. return this.id; 40. } 41. 42. public void setid(integer id) { 43. this.id = id; 44. } 45. 46. public wife getwife() { 47. return this.wife; 48. } 49. 50. public void setwife(wife wife) { 51. this.wife = wife; 52. } 53. 54. public string getname() { 55. return this.name; 56. } 57. 58. public void setname(string name) { 59. this.name = name; 60. } 61. 62. }
以上是基本的数据表映射。这时候假设我们需要一对一双向关联,即在保存或者更新时,可以根据一个husband实例可以获得其wife实例,也可根据wife实例去获得一个husband实例。
一对一双向关联比较特殊,不像单向关联,在hbm配置文件中仅仅使用one-to-one配置即可,这种情况下需要使用may-to-one和one-to-one来模拟一一对应,既然是一一对应,所以在many-to-one的一段,要加上unique=true属性,从而保证其唯一性。不要问我为什么,这是hibernate的机制吧,其实说到这里,我对于hibernate还不是很了解,如果有大神读到希望可以指点一二。从项目经验来看,如果不这么做,在同时修改了这两个实体,然后保存到库中时,总是报错,错误信息为session无法同步,或者外键id为null。使用了这样的配置后,就没有问题了。下面看二者的配置文件:
wife.hbm.xml java代码 1. 2. 4. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. husband.hbm.xml:1. 2. 4. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
外键所依赖的那个表的配置文件(wife)使用one-to-one,外键所在的表(husband)用many-to-one,但是要指定unique为true从而保证其唯一性。注意many这一端中的colum,配置的应该是外键所在表的外键列名,对应这里也就是husband表中的“wifeid”,需要与数据库中的数据表表中一致,切勿弄错。
one-to-one:指定在wife这个类中用于双向关联的属性husband
property-ref: 在关联对象中用于与本对象关联的属性。
注意:property-ref=wife不能少,否则会造成查询时关联查询失败!
以上是实际经验的总结,如有错误,欢迎指正。
其它类似信息

推荐信息