關(guān)于hibernate 3 配置one-to-one 單向關(guān)聯(lián)出現(xiàn)的異常:No row with the given identifier exists

最近需要增加業(yè)務(wù)扰付,需要增加一對(duì)一關(guān)聯(lián),由于系統(tǒng)采用hibernate3价脾,而且使用了xml配置方式,所以就舉例一下xml配置方式:

假設(shè)我們有兩個(gè)類笛匙,人和身份證侨把。我們要達(dá)到的效果就是查詢?nèi)说男畔r(shí)自動(dòng)讀取身份證。

類:

//人
public class Person(){
    Long id;
    IdCard idCard;
}

// 身份證
public class IdCard(){
    Long id;
    String cardNo;
}

接下來是xml的配置:

<!-- person.hbm.xml -->
<hibernate-mapping package="beans" auto-import="true">
    <class name="Person" table="person">
        <id name="id" column="id" type="java.lang.Long">
            <!-- 手動(dòng)指定ID -->
            <generator class="assigned" />
        </id>

        <one-to-one name="idCard" cascade="save-update" constrained="true" lazy="false"/>
    </class>
</hibernate-mapping>

<!-- id_card.hbm.xml -->
<hibernate-mapping package="beans" auto-import="true">
    <class name="IdCard" table="id_card">
        <id name="id" column="id" type="java.lang.Long">
            <!-- 手動(dòng)指定ID -->
            <generator class="assigned" />
        </id>
    </class>
</hibernate-mapping>

這樣配置后妹孙,如果數(shù)據(jù)一致是沒有問題的秋柄,但是由于我們是后加業(yè)務(wù),所以肯定會(huì)造成數(shù)據(jù)不一致的情況蠢正,意思就是有人的信息骇笔,但是沒有身份證的信息。這樣一來嚣崭,hibernate會(huì)報(bào)錯(cuò):

No row with the given identifier exists

讓我們閱讀源碼笨触,了解出錯(cuò)原因(之前已通過查閱異常棧定位到出錯(cuò)位置):

// EntityType 有幾個(gè)子類,ManyToOneType,OneToOneType
public class EntityType{
    protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
        ...
        boolean isProxyUnwrapEnabled = unwrapProxy &&
                session.getFactory()
                        .getEntityPersister( getAssociatedEntityName() )
                        .isInstrumented( session.getEntityMode() );
    
        
        // 調(diào)用查詢雹舀,傳了傳了一個(gè)isNullable()用于處理為空的情況
        // isNullable()是抽象的芦劣,又子類實(shí)現(xiàn)
        Object proxyOrEntity = session.internalLoad(
                getAssociatedEntityName(),
                id,
                eager,
                isNullable() && !isProxyUnwrapEnabled
        );
        ...
    }
}

// 由于我們使用OneToOne,所以我們看一下OneToOneType的isNullable實(shí)現(xiàn):

public class OneToOneType extends EntityType {
    ...
    protected boolean isNullable() {
        // 可以看到是根據(jù)foreignKeyType來進(jìn)行判斷葱跋,稍后我們來看一下foreignKeyType是如何來的
        return foreignKeyType==ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;
    }
    ...
}

// 調(diào)用SessionImpl進(jìn)行查詢
public class SessionImpl{
    public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) throws HibernateException {
        // todo : remove
        LoadEventListener.LoadType type = nullable
                ? LoadEventListener.INTERNAL_LOAD_NULLABLE
                : eager
                        ? LoadEventListener.INTERNAL_LOAD_EAGER
                        : LoadEventListener.INTERNAL_LOAD_LAZY;
        LoadEvent event = new LoadEvent(id, entityName, true, this);
        // 調(diào)用查詢
        fireLoad(event, type);
        if ( !nullable ) {
            UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName );
        }
        return event.getResult();
    }
}
// fireLoad調(diào)用了DefaultLoadEventListener的load
public class DefaultLoadEventListener {
    ...
    protected Object load(
            final LoadEvent event,
            final EntityPersister persister,
            final EntityKey keyToLoad,
            final LoadEventListener.LoadType options) {
    
            ...
            
            // 讀取關(guān)聯(lián)對(duì)象
            Object entity = doLoad(event, persister, keyToLoad, options);
    
            boolean isOptionalInstance = event.getInstanceToLoad() != null;
    
            // 進(jìn)行為空處理持寄,如果為空直接拋異常
            if ( !options.isAllowNulls() || isOptionalInstance ) {
                if ( entity == null ) {
                    event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
                }
            }
    
            ...
    
            return entity;
        }
    ...
}

在上面的代碼里我們可以看到源梭,在關(guān)聯(lián)對(duì)象為空時(shí)娱俺,hibernate通過調(diào)用"options.isAllowNulls()和isOptionalInstance"來判斷是否需要拋異常。接下來我們?cè)傺芯恳幌耾ptions.isAllowNulls()是如何來的废麻。

接上面的話荠卷,我們看一下OneToOneType的foreignKeyType是如何來的,觀察一下構(gòu)建hbm時(shí)做了什么:

public final class HbmBinder {
    // 綁定one-to-one
    public static void bindOneToOne(Element node, OneToOne oneToOne, String path, boolean isNullable,
                Mappings mappings) throws MappingException {
    
            bindColumns( node, oneToOne, isNullable, false, null, mappings );
    
            Attribute constrNode = node.attribute( "constrained" );
            boolean constrained = constrNode != null && constrNode.getValue().equals( "true" );
            oneToOne.setConstrained( constrained );
    
            // 如果constrained為true則ForeignKeyType就為FOREIGN_KEY_FROM_PARENT
            oneToOne.setForeignKeyType( constrained ?
                    ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT :
                    ForeignKeyDirection.FOREIGN_KEY_TO_PARENT );
            
            ...
    }
}

所以最終的解決辦法:去掉constrained="true":

<hibernate-mapping package="beans" auto-import="true">
    <class name="Person" table="person">
        <id name="id" column="id" type="java.lang.Long">
            <!-- 手動(dòng)指定ID -->
            <generator class="assigned" />
        </id>

        <one-to-one name="idCard" cascade="save-update" lazy="false"/>
    </class>
</hibernate-mapping>

那么constrained的意思是什么呢烛愧,通過閱讀以上代碼油宜,我們得出結(jié)論掂碱,當(dāng)constrained為true時(shí),表明關(guān)聯(lián)表肯定存在對(duì)應(yīng)的鍵與主表進(jìn)行對(duì)應(yīng)慎冤。

至于其他意思請(qǐng)百度疼燥。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蚁堤,隨后出現(xiàn)的幾起案子醉者,更是在濱河造成了極大的恐慌,老刑警劉巖披诗,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撬即,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡呈队,警方通過查閱死者的電腦和手機(jī)剥槐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪摧,“玉大人粒竖,你說我怎么就攤上這事∩芄危” “怎么了温圆?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)孩革。 經(jīng)常有香客問我岁歉,道長(zhǎng),這世上最難降的妖魔是什么膝蜈? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任锅移,我火速辦了婚禮,結(jié)果婚禮上饱搏,老公的妹妹穿的比我還像新娘非剃。我一直安慰自己,他們只是感情好推沸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布备绽。 她就那樣靜靜地躺著,像睡著了一般鬓催。 火紅的嫁衣襯著肌膚如雪肺素。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天宇驾,我揣著相機(jī)與錄音倍靡,去河邊找鬼。 笑死课舍,一個(gè)胖子當(dāng)著我的面吹牛塌西,可吹牛的內(nèi)容都是我干的他挎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼捡需,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼办桨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起站辉,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤崔挖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后庵寞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狸相,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年捐川,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脓鹃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡古沥,死狀恐怖瘸右,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岩齿,我是刑警寧澤太颤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站盹沈,受9級(jí)特大地震影響龄章,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乞封,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一做裙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肃晚,春花似錦锚贱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晋修,卻和暖如春吧碾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背飞蚓。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工滤港, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留廊蜒,地道東北人趴拧。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓溅漾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親著榴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子添履,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)脑又,斷路器暮胧,智...
    卡卡羅2017閱讀 134,672評(píng)論 18 139
  • Hibernate: 一個(gè)持久化框架 一個(gè)ORM框架 加載:根據(jù)特定的OID,把一個(gè)對(duì)象從數(shù)據(jù)庫(kù)加載到內(nèi)存中OID...
    JHMichael閱讀 1,973評(píng)論 0 27
  • 相信每一個(gè)結(jié)婚的女人,都會(huì)面臨婆媳關(guān)系問題问麸,為了防止婚姻被破壞往衷,為了守護(hù)家庭的和平,給大家總結(jié)一下引發(fā)婆媳關(guān)系的矛...
    婚禮紀(jì)閱讀 1,259評(píng)論 0 51
  • 寫作是將生活過的生活復(fù)原化的過程严卖,特別是那些敘事或回憶錄之類的寫作席舍。能做到何種程度的還原,取決于寫作者的觀察力哮笆、才...
    藍(lán)柿閱讀 1,342評(píng)論 7 22
  • 《皓月當(dāng)空》—穿石— 帝都冬季的夜晚很難與你相遇如玉盤般的你走進(jìn)了我的眼簾是才明月幾時(shí)有 此刻微風(fēng)徐來竹影輕盈也許...
    東方詩空閱讀 308評(píng)論 2 2