hibernate annotation 之 一对多单向外键关联

本文介绍Hibernate框架下一对多关系的实现方式,通过Farm(农场)与Plant(植物)的关系映射,展示如何避免生成不必要的中间表,并提供级联保存的具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


转自:hibernate annotation 之 一对多单向外键关联

假设,一个农场产出多种植物,具体的某一植物产于某一农场。


 1  package  net.yeah.fancydeepin.po;
 2 
 3  import  java.io.Serializable;
 4  import  java.util.Set;
 5  import  javax.persistence.Column;
 6  import  javax.persistence.Entity;
 7  import  javax.persistence.GeneratedValue;
 8  import  javax.persistence.Id;
 9  import  javax.persistence.OneToMany;
10  /**
11   * -----------------------------------------
12   * @描述  农场
13   * @作者  fancy
14   * @邮箱  fancydeepin@yeah.net
15   * @日期  2012-10-21 <p>
16   * -----------------------------------------
17    */
18  @Entity
19  public   class  Farm  implements  Serializable{
20 
21       private   static   final   long  serialVersionUID  =   1L ;
22      
23       private  Integer id;
24       private  String  name;
25       private  Set < Plant >  plantSet;
26      
27      @Id
28      @GeneratedValue
29       public  Integer getId() {
30           return  id;
31      }
32      @Column(length  =   18 , nullable  =   false )
33       public  String getName() {
34           return  name;
35      }
36      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
37       public  Set < Plant >  getPlantSet() {
38           return  plantSet;
39      }
40       public   void  setId(Integer id) {
41           this .id  =  id;
42      }
43       public   void  setName(String name) {
44           this .name  =  name;
45      }
46       public   void  setPlantSet(Set < Plant >  plantSet) {
47           this .plantSet  =  plantSet;
48      }
49  }


 1  package  net.yeah.fancydeepin.po;
 2 
 3  import  java.io.Serializable;
 4  import  javax.persistence.Column;
 5  import  javax.persistence.Entity;
 6  import  javax.persistence.GeneratedValue;
 7  import  javax.persistence.Id;
 8  /**
 9   * -----------------------------------------
10   * @描述  植物
11   * @作者  fancy
12   * @邮箱  fancydeepin@yeah.net
13   * @日期  2012-10-21 <p>
14   * -----------------------------------------
15    */
16  @Entity
17  public   class  Plant  implements  Serializable{
18 
19       private   static   final   long  serialVersionUID  =   1L ;
20      
21       private  Integer id;
22       private  String  name;
23      
24      @Id
25      @GeneratedValue
26       public  Integer getId() {
27           return  id;
28      }
29      @Column(length  =   18 , nullable  =   false )
30       public  String getName() {
31           return  name;
32      }
33       public   void  setId(Integer id) {
34           this .id  =  id;
35      }
36       public   void  setName(String name) {
37           this .name  =  name;
38      }
39 
40  }

Junit 测试 : 

1  @Test
2       public   void  createTable(){
3          
4           new  SchemaExport( new  AnnotationConfiguration().configure()).create( true true );
5      }

执行上面的单元测试,数据库中生成的表结构图 : 



从上面的图可以看出,多出了一张中间表,这张中间表是冗余的,它没有必要存在,它之所以存在,这是因为 hibernate 在默认的情况下,

会将 OneToMany 当成是 ManyToMany 的一种特殊情况,故而生成了一张中间表。想要去掉这张中间表只需要加上 @JoinColumn 注解即可 : 

1      @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
2      @JoinColumn(name  =   " farm_id " )
3       public  Set < Plant >  getPlantSet() {
4           return  plantSet;
5      }

再次执行单元测试 ( 注意要手动删除之前生成的表,因为有中间表的存在,中间表参考了与它关联的主表,这种情况下 hibernate 无法帮我们删除表 )




级联保存 : 

 1      private   static  Session session;
 2      
 3      @BeforeClass
 4       public   static   void  beforeClass(){
 5          
 6          session  =   new  AnnotationConfiguration().configure().buildSessionFactory().getCurrentSession();
 7      }
 8      
 9      @Test
10       public   void  insert(){
11           try  {
12              Plant tomato   =   new  Plant();
13              tomato.setName( " 番茄 " );
14              Plant cabbage  =   new  Plant();
15              cabbage.setName( " 卷心菜 " );
16              Set < Plant >  plantSet  =   new  HashSet < Plant > ();
17              plantSet.add(tomato);
18              plantSet.add(cabbage);
19              Farm farm  =   new  Farm();
20              farm.setName( " fancy-farm " );
21              farm.setPlantSet(plantSet);
22              session.beginTransaction();
23              session.persist(farm);
24              session.getTransaction().commit();
25          }  catch  (Exception e) {
26              e.printStackTrace();
27          }
28      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值