<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-42  評(píng)論-578  文章-1  trackbacks-0
    近來(lái),在做的一個(gè)NewsMS項(xiàng)目中,需要用到多對(duì)多關(guān)聯(lián)映射,以下是項(xiàng)目中用到的兩個(gè)實(shí)體類:用戶類User和角色類Role,它們之間是多對(duì)多的關(guān)系。
    //用戶表
    @Entity
    @Table(name
    ="rong_user")
    public class User{

        
    //省略其它內(nèi)容

        
    private Set<Role> roles = new 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() {
            
    return roles;
        }

        
    public void setRoles(Set<Role> roles) {
            
    this.roles = roles;
        }

    }

    //角色表
    @Entity
    @Table(name
    ="rong_role")
    public class Role{
        
        
    //省略其它內(nèi)容

        
    private Set<User> user = new LinkedHashSet<User>();        //用戶集合

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

        
    public void setUser(Set<User> user) {
            
    this.user = user;
        }

    }


             這兩個(gè)生成數(shù)據(jù)庫(kù)中的三個(gè)表,分別是rong_user, rong_role和一個(gè)中間表rong_user_role。
             Hibernate和JPA控制關(guān)聯(lián)關(guān)系的,只能是一方,不能雙方控制的,上面的程序中,我通過(guò)在Role類中設(shè)置mappedBy="roles"來(lái)設(shè)置由User來(lái)控制關(guān)系,
             這樣,問(wèn)題就出現(xiàn)了:當(dāng)我在要?jiǎng)h除角色Role時(shí),如果沒(méi)有用戶擁有這個(gè)角色的話,就能成功刪除;如果有用戶擁有這個(gè)角色的時(shí)候,就不能刪除,會(huì)拋以下異常:
    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 constraint fails (`newsms/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.ConstraintViolationException: Could not execute JDBC batch update
    /****堆棧信息略****/
    Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`newsms/rong_user_role`, CONSTRAINT `FKF1698421A337A5FA` FOREIGN KEY (`role_id`) REFERENCES `rong_role` (`id`))
    /******堆棧信息略*****/

          當(dāng)我設(shè)置成單向關(guān)系映射時(shí),即把Role類中,Set<User>信息去掉,這樣,也不能刪,原因也是說(shuō)有外鍵約束!怎么辦?
          苦惱了好幾天,最后,只能歸于Hibernate(JPA)的多對(duì)多關(guān)聯(lián)映射設(shè)計(jì)得有點(diǎn)不符實(shí)際!就像上面我說(shuō)的例子,有人選了某角色,就不能刪掉該角色。還有一種做法是,在Role類中:
    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.REMOVE}, mappedBy = "roles", fetch = FetchType.LAZY)
        
    public Set<User> getUser() {
            
    return user;
        }
            即加多一個(gè)“CascadeType.REMOVE”,這樣能把角色Role給刪掉了,但連擁有該角色的所有用戶User也被級(jí)聯(lián)刪掉了。這樣來(lái)看,某個(gè)用戶擁有許多角色,就因?yàn)槠渲杏羞@一個(gè)角色,就被級(jí)聯(lián)刪了整個(gè)自己,那不是很冤枉。這也不符合實(shí)際!
            個(gè)人認(rèn)為,Hibernate(JPA)在設(shè)置多對(duì)多關(guān)聯(lián)映射時(shí),應(yīng)該有做法能使得雙方都能控制關(guān)聯(lián)關(guān)系才好,才符合實(shí)際吧!但事實(shí)上,好像還沒(méi)有發(fā)現(xiàn)有Hibernate(JPA)這種能力!


    本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處,謝謝!http://m.tkk7.com/rongxh7(心夢(mèng)帆影JavaEE技術(shù)博客)
        

    posted on 2009-06-08 13:33 心夢(mèng)帆影 閱讀(26943) 評(píng)論(15)  編輯  收藏 所屬分類: HibernateJPA

    評(píng)論:
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-08 18:18 | 虎嘯龍吟
    這樣就是符合實(shí)際啊:當(dāng)某個(gè)用戶擁有某個(gè)角色的時(shí)候,不應(yīng)該刪除該角色吧!  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-08 18:26 | 心夢(mèng)帆影
    @虎嘯龍吟
    用戶與角色是多對(duì)多的關(guān)系,如果系統(tǒng)不需要或個(gè)角色了,而因?yàn)橛杏脩舾@個(gè)角色有關(guān)聯(lián),而刪不了!那怎么對(duì)角色進(jìn)行管理?只能添加,修改,不能刪除?  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-08 19:20 | YangL
    LZ也在用SpringSide吧,呵呵  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-08 21:01 | 心夢(mèng)帆影
    @YangL
    被你看穿了,呵呵
    但我沒(méi)有直接把Springside當(dāng)組件用,而是學(xué)習(xí)它!
    有興趣交流一下不?我QQ:121040245,呵呵  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-08 21:18 | 小人物
    學(xué)習(xí)了!  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-09 20:44 | huliqing
    這不應(yīng)該是hibernate的不完美之處,數(shù)據(jù)庫(kù)的這個(gè)作法是正確的,這涉及到數(shù)據(jù)完整與安全性的問(wèn)題。我認(rèn)為你應(yīng)該先明確的處理掉相關(guān)的持有該角色的相關(guān)用戶的對(duì)于該角色的關(guān)系。也就是說(shuō)先刪除相關(guān)用戶對(duì)該角色的持有關(guān)系,再刪除該角色就沒(méi)有問(wèn)題。
    或者選擇不作外鍵約束,但是這樣就會(huì)對(duì)比較嚴(yán)格的系統(tǒng)造成數(shù)據(jù)冗余,不完整,還包括安全問(wèn)題。  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2009-06-11 00:33 | 虎嘯龍吟
    @YangL
    可以先去掉該用戶的角色,再刪除該角色啊  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2012-12-23 11:32 | lin
    雙方都用OneToMany就行了  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處[未登錄](méi) 2013-06-15 13:01 | James
    關(guān)聯(lián)關(guān)系不要雙方配置 只在主表配置  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處[未登錄](méi) 2013-06-15 13:03 | James
    @ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
    @JoinTable(name = "adgroup_ad", joinColumns = { @JoinColumn(name = "adgroup_id") }, inverseJoinColumns = { @JoinColumn(name = "ad_version_id") })
    這是我的項(xiàng)目的主表部分的注解配置 測(cè)試增加修改都可以 刪除也只刪除關(guān)聯(lián)關(guān)系  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處[未登錄](méi) 2013-06-15 13:10 | James
    汗 SORRY 發(fā)現(xiàn)我的問(wèn)題和你的不一樣的 我這里還是會(huì)出現(xiàn)你說(shuō)的這種情況 SORRY 看來(lái)它還真是設(shè)計(jì)有點(diǎn)不合理的  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2013-09-02 10:49 | phevose
    這在業(yè)務(wù)邏輯上是完全合理的,正在被使用的角色是不應(yīng)該被刪除的,如果刪除那么應(yīng)該做級(jí)聯(lián)刪除,對(duì)應(yīng)的用戶也應(yīng)該一并刪除,或者應(yīng)該先解除關(guān)聯(lián)關(guān)系后再刪除該角色。  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2014-11-14 16:16 | 雪妮星跡
    樓主想要的級(jí)聯(lián)功能,可以使用數(shù)據(jù)庫(kù)的外鍵約束控制。  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2015-01-27 15:20 | lp
    @心夢(mèng)帆影
    可以不建立外鍵關(guān)聯(lián),通過(guò)應(yīng)用控制數(shù)據(jù)的完整性。  回復(fù)  更多評(píng)論
      
    # re: Hibernate(JPA)多對(duì)多(ManyToMany)關(guān)聯(lián)映射不完美之處 2016-04-07 15:10 | coolcjava
    只有兩個(gè)實(shí)體類都配置了joinColumns和inverseJoinColumns屬性,并且位置互相調(diào)換,就可以使用雙向維護(hù)  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲AV无码成人精品区日韩| 亚洲精品高清视频| 亚洲成AV人片在WWW| 九九九精品成人免费视频| 亚洲视频在线观看网址| 999任你躁在线精品免费不卡| 国产AV无码专区亚洲A∨毛片| 成人免费区一区二区三区 | 亚洲免费一区二区| 久久激情亚洲精品无码?V| 国产免费牲交视频免费播放 | 亚洲影视自拍揄拍愉拍| 动漫黄网站免费永久在线观看| 亚洲国产成人资源在线软件| 一个人看www在线高清免费看| 国产精品亚洲片在线va| 日本成人在线免费观看| 免费看内射乌克兰女| 国产自偷亚洲精品页65页| 国产精品白浆在线观看免费| 久久久久亚洲AV无码观看| 国产一卡二卡3卡四卡免费| 亚洲精品V天堂中文字幕| 亚洲精品黄色视频在线观看免费资源| 一区二区三区在线免费| 亚洲AV无码成人网站久久精品大| 最近中文字幕完整免费视频ww| 亚洲永久在线观看| 免费在线观看黄网站| 91免费福利视频| 伊人久久亚洲综合影院首页| 亚洲高清成人一区二区三区| 久久中文字幕免费视频| 亚洲中文无码卡通动漫野外| 亚洲国产精品成人| 人与禽交免费网站视频| 精品免费AV一区二区三区| 亚洲Av综合色区无码专区桃色| 一区二区无码免费视频网站| 国产日韩久久免费影院 | 亚洲香蕉在线观看|