hibernatejpa:Hibernate(JPA)多对多(ManyToMany)关联映射不完美的处

  近来在做个NewsMS项目中需要用到多对多关联映射以下是项目中用到两个实体类:用户类User和角色类Role它们的间是多对多关系

//用户表
@Entity
@Table(name="rong_user")
public User{

    //省略其它内容

    private Set<Role> roles = LinkedHashSet<Role>;    //角色集合
   
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "rong_user_role", joinColumns = { @JoinColumn(name ="user_id" )}, inverseJoinColumns = { @JoinColumn(name = "role_id") })
    @OrderBy("id")
    public Set<Role> getRoles {
        roles;
    }
    public void Roles(Set<Role> roles) {
        this.roles = roles;
    }
}
//角色表
@Entity
@Table(name="rong_role")
public Role{
   
    //省略其它内容

    private Set<User> user = LinkedHashSet<User>;        //用户集合

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "roles", fetch = FetchType.LAZY)
    public Set<User> getUser {
        user;
    }
    public void User(Set<User> user) {
        this.user = user;
    }
}


   这两个生成数据库中 3个表分别是rong_user, rong_role和个中间表rong_user_role

   Hibernate和JPA控制关联关系只能是不能双方控制上面我通过在Role类中设置mappedBy="roles"来设置由User来控制关系

   这样问题就出现了:当我在要删除角色Role时如果没有用户拥有这个角色就能成功删除;如果有用户拥有这个角色时候就不能删除会抛以下异常:

  12:53:33,125  WARN JDBCExceptionReporter:100 - SQL Error: 1451, SQLState: 23000

  12:53:33,125 ERROR JDBCExceptionReporter:101 - Cannot delete or update a parent row: a foreign key constra fails (`sms/rong_user_role`, CONSTRAINT `FKF1698421A337A5FA` FOREIGN KEY (`role_id`) REFERENCES `rong_role` (`id`))

  12:53:33,171 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session

  org.hibernate.exception.ConstraViolationException: Could not execute JDBC batch update

  /****堆栈信息略****/

  Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constra fails (`sms/rong_user_role`, CONSTRAINT `FKF1698421A337A5FA` FOREIGN KEY (`role_id`) REFERENCES `rong_role` (`id`))

  /******堆栈信息略*****/

   当我设置成单向关系映射时即把Role类中Set<User>信息去掉这样也不能删原因也是说有外键约束!如何办?

   苦恼了好几天最后只能归于Hibernate(JPA)多对多关联映射设计得有点不符实际!就像上面我说例子有人选了某角色就不能删掉该角色还有种做法是在Role类中:

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.REMOVE}, mappedBy = "roles", fetch = FetchType.LAZY)
    public Set<User> getUser {
        user;
    }




   即加多个“CascadeType.REMOVE”这样能把角色Role给删掉了但连拥有该角色所有用户User也被级联删掉了这样来看某个用户拥有许多角色其中有这个角色就被级联删了整个自己那不是很冤枉这也不符合实际!

   个人认为Hibernate(JPA)在设置多对多关联映射时应该有做法能使得双方都能控制关联关系才好才符合实际吧!但事实上好像还没有发现有Hibernate(JPA)这种能力!

Tags:  hibernate多对多 jpa多对多删除 jpa多对多 hibernatejpa

延伸阅读

最新评论

发表评论