工作需要一个双向多对多映射,照着李刚的书做了映射,碰到了一些问题,现就问题及解决方案进行总结归纳。

1、首先奉上最初代码

Person5.java

@Entity
@Table(name = "person_manyandmany")
public class Person5 {
@Id
@GeneratedValue
private Long id;
private String name;
private int age;
@ManyToMany(targetEntity = Address5.class)
@JoinTable(name = "person_and_address",
joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id", nullable = false, updatable = false),
inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id", nullable = false, updatable = false))
private Set<Address5> address5s = new HashSet<Address5>();
  //get、set方法省略
}

Address5.java

@Entity
@Table(name = "address_manyandmany")
public class Address5 {
@Id
@GeneratedValue
private Long id;
private String address;
@ManyToMany(targetEntity = Person5.class)
@JoinTable(name = "person_and_address",
joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id", nullable = false))
private Set<Person5> person5s = new HashSet<Person5>();
  //get、set方法省略
}

问题1:

  因为我做了<property name="hbm2ddl.auto">update</property>配置,所以项目启动时报关联表重名错误。经分析时因为实体类两边都有@JoinTable注解,所以就会产生两张关联表。

解决方案1:

  将Address5中name改为address_and_person,重新启动项目,项目启动不会报错。但是这种方式会创建两张关联表,是不被提倡的。

解决方案二:

  Address5放弃控制权,将控制权交给Person5,代码如下(只修改Address5中代码即可):

  @ManyToMany(targetEntity = Person5.class, mappedBy = "address5s")
private Set<Person5> person5s = new HashSet<Person5>();

  增加mappedBy = "address5s"属性,此事Address5放弃控制权交给Person5。这时启动项目不会报错,并只创建了一张关联表,另外两边都可以获取到关联对方的信息(这才是关联的重点,减少代码逻辑)。到此关联的问题解决了,添加、获取和更新信息都没有问题了。

  添加信息代码

       Person5 p1 = new Person5();
p1.setName("many and many 5"); Person5 p2 = new Person5();
p2.setName("many and many 6"); Address5 a1 = new Address5();
a1.setAddress("many and many address 1");
a1.getPerson5s().add(p1); Address5 a2 = new Address5();
a2.setAddress("many and many address 2");
a1.getPerson5s().add(p2); p1.getAddress5s().add(a1);
p1.getAddress5s().add(a2);
p2.getAddress5s().add(a2); session.save(p1);
session.save(p2);
session.save(a1);
session.save(a2);

  获取信息代码

       Person5 person5 = (Person5) session.get(Person5.class, 1l);
Set<Address5> address5s = person5.getAddress5s();
for(Address5 address5 : address5s) {
System.out.println("person : " + person5.getName() + " | " + address5.getAddress());
} Address5 address5 = (Address5) session.get(Address5.class, 2l);
System.out.println("address5 : " + address5.getAddress());
Set<Person5> person5s = address5.getPerson5s();
for(Person5 person51 : person5s) {
System.out.println("address : " + address5.getAddress() + " | " + person51.getName());
}

问题二:

  删除问题,我们需要的删除规则是主控方和被控方删除信息时删除关联表中的对应信息,而不会删除对方的信息。代码测试,主控方的删除是没有问题的,在删除被控一方(Address5)信息时报错不能删除关联信息(就是关联表中信息没法删除)。

解决方案:

  在Address5中增加cascade = CascadeType.REMOVE或ALL,这时确实可以删除关联表中信息,但同时也将主控方(Person5)信息也删除了,这不是我想要的。到此发现通过代码注解已无法解决这个问题,网上查找获得这么一条建议”去数据库中设置外键中间表的关联关系为delete cascade就可以了“,按照此法,在数据库中手动设置关联表中address外键的删除级联为CASCADE,这时测试问题解决了。表结构如下图

  

CREATE TABLE `t_master_mastertype` (

`master_id` bigint(20) NOT NULL,

`type_id` bigint(20) NOT NULL,

PRIMARY KEY (`master_id`,`type_id`),

KEY `type_id` (`type_id`),

CONSTRAINT `master` FOREIGN KEY (`master_id`) REFERENCES `t_master` (`id`),

CONSTRAINT `type` FOREIGN KEY (`type_id`) REFERENCES `t_master_type` (`id`) ON DELETE CASCADE

) ENGINE=InnoDB DEFAULT CHARSET=utf8

hibernate双向ManyToMany映射的更多相关文章

  1. Hibernate双向多对多对象关系模型映射

    1 双向many-to-many 业务模型: 描述员工和项目 一个员工同时可以参与多个项目 一个项目中可以包含多个员工 分析:数据库的数据模型,通过中间关系表,建立两个one-to-many构成man ...

  2. Hibernate的关联映射——双向1-N关联

    Hibernate的关联映射--双向1-N关联 对于1-N的关联,Hibernate推荐使用双向关联,而且不要让1的一端控制关联关系,而是用N的一端控制关联关系.双线的1-N关联和N-1关联是两种相同 ...

  3. Hibernate从入门到精通(十一)多对多双向关联映射

    上次我们在中Hibernate从入门到精通(十)多对多单向关联映射讲解了一下多对多单向关联映射,这次我们讲解一下七种映射中的最后一种多对多双向关联映射. 多对多双向关联映射 按照我们之前的惯例,先看一 ...

  4. Hibernate(十一)多对多双向关联映射

    上次我们在中Hibernate从入门到精通(十)多对多单向关联映射讲解了一下多对多单向关联映射,这次我 们讲解一下七种映射中的最后一种多对多双向关联映射. 多对多双向关联映射 按照我们之前的惯例,先看 ...

  5. Hibernate在关于一对多,多对一双向关联映射

    [Hibernate]之关于一对多,多对一双向关联映射 因为一对多.和多对一的双向关联映射基本上一样,所以这里就一起写下来! Annotations配置 @Entity @Table(name=&qu ...

  6. [置顶] Hibernate从入门到精通(十一)多对多双向关联映射

    上次我们在中Hibernate从入门到精通(十)多对多单向关联映射讲解了一下多对多单向关联映射,这次我们讲解一下七种映射中的最后一种多对多双向关联映射. 多对多双向关联映射 按照我们之前的惯例,先看一 ...

  7. (Hibernate进阶)Hibernate映射——一对一双向关联映射(六)

    上一篇博客我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.如图所示: 关键原因在于对象模型具有方向性: 单向: ...

  8. Hibernate一对一双向关联映射

    关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介 ...

  9. Hibernate从入门到精通(九)一对多双向关联映射

    上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映射,即在一的 ...

随机推荐

  1. setTimeout()和setInterval()方法的区别

    setTimeout(); //5秒后执行yourFunction(),只执行一次 setInterval(); //每隔5秒执行一次 1.setTimeout(funhander,time)的作用是 ...

  2. HTML/CSS/JS编码规范

    最近整理了一份HTML/CSS/JS编码规范,供大家参考.目录:一.HTML编码规范二.CSS编码规范三.JS编码规范 一.HTML编码规范 1. img标签要写alt属性 根据W3C标准,img标签 ...

  3. arpspoof dnsspoof中间人攻击

    最近搞了一个监听神器,尽管使用了网卡混杂模式,不过监听到的几乎全是本地流量, 为了获取更多有用的数据,搞一下中间人攻击,最基本的就是arpspoof + IP转发,这样就可以获得局域网内任何人的上网流 ...

  4. 调试应用程序(Debugging Applications)

    调试应用程序(Debugging Applications)¶ Phalcon中提供了提供了几种调试级别即通知,错误和异常. 异常类 Exception class 提供了错误发生时的一些常用的调试信 ...

  5. 【swupdate文档 二】许可证

    许可证 SWUpdate是免费软件.它的版权属于Stefano Babic和其他许多贡献代码的人(详情请参阅实际源代码和git提交信息). 您可以根据自由软件基金会发布的GNU通用公共许可证第2版的条 ...

  6. 【openjudge】C15C Rabbit's Festival CDQ分治+并查集

    题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...

  7. 《Java编程思想》阅读笔记一

    Java编程思想 这是一个通过对<Java编程思想>(Think in java)第四版进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会 ...

  8. 【Android开发日记】之基础篇(二)——Android的动画效果

          什么是动画,动画的本质是通过连续不断地显示若干图像来产生“动”起来的效果.比如说一个移动的动画,就是在一定的时间段内,以恰当的速率(起码要12帧/秒以上,才会让人产生动起来的错觉)每隔若干 ...

  9. POJ 1733 Parity game(带权并查集)

    题目链接:http://poj.org/problem?id=1733 题目大意:给你m条信息,每条信息告诉你区间l~r的1的个数是奇数还是偶数,如果后面出现信息跟前面矛盾则这条信息是错误的,问在第一 ...

  10. HDU-5272

    Dylans loves numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...