簡體   English   中英

Hibernate:由於一對一關系而導致主鍵生成不一致

[英]Hibernate: Inconsistent primary key generation due to one-to-one relation

我在一個名為“MailAccount”的類和“IncomingServer”和“OutgoingServer”類之間有兩個一對一的關系。

(它是在Tomcat和Ubuntu服務器版上運行的Java應用程序)。

映射看起來像這樣:

MailAccount.hbm.xml

<hibernate-mapping package="com.mail.account">
    <class name="MailAccount" table="MAILACCOUNTS" dynamic-update="true">

        <id name="id" column="MAIL_ACCOUNT_ID">
            <generator class="native" />
        </id>

        <one-to-one name="incomingServer" cascade="all-delete-orphan">
        </one-to-one>
        <one-to-one name="outgoingServer" cascade="all-delete-orphan">
        </one-to-one>

    </class>
</hibernate-mapping>

IncomingMailServer.hbm.xml

<hibernate-mapping>
    <class name="com.IncomingMailServer" table="MAILSERVER_INCOMING" abstract="true">

        <id name="id" type="long" access="field">
            <column name="MAIL_SERVER_ID" />
            <generator class="native" />
        </id>

        <discriminator column="SERVER_TYPE" type="string"/>

        <many-to-one name="mailAccount" column="MAIL_ACCOUNT_ID" not-null="true" unique="true" />

        <subclass name="com.ImapServer" extends="com.IncomingMailServer" discriminator-value="IMAP_SERVER" />           
        <subclass name="com.Pop3Server" extends="com.IncomingMailServer" discriminator-value="POP3_SERVER" />

    </class>
</hibernate-mapping>

OutgoingMailServer.hbm.xml

<hibernate-mapping>
    <class name="com.OutgoingMailServer" table="MAILSERVER_OUTGOING" abstract="true">

        <id name="id" type="long" access="field">
            <column name="MAIL_SERVER_ID" />
            <generator class="native" />
        </id>

        <discriminator column="SERVER_TYPE" type="string"/>

        <many-to-one name="mailAccount" column="MAIL_ACCOUNT_ID" not-null="true" unique="true" />

        <subclass name="com.SmtpServer" extends="com.OutgoingMailServer" discriminator-value="SMTP_SERVER" />

    </class>
</hibernate-mapping>

類層次結構如下所示:

public class MailAccount{
 IncomingMailServer incomingServer;
 OutgoingMailServer outgoingServer;
}

public class MailServer{
 HostAddress hostAddress;
 Port port;
}

public class IncomingMailServer extends MailServer{
 // ...
}

public class OutgoingMailServer extends MailServer{
 // ...
}

public class ImapServer extends IncomingMailServer{
 // ...
}

public class Pop3Server extends IncomingMailServer{
 // ...
}

public class SmtpServer extends OutgoingMailServer{
 // ...
}

現在, 問題出現

雖然大部分時間我的應用程序運行良好,但似乎有一種情況是電子郵件服務器被刪除,但相應的帳戶沒有,而且這是在進行此調用時:

session.delete(mailAccountInstance);

在Hibernate中的一對一關系中,郵件帳戶與其服務器之間的主鍵必須相等,否則,關系完全不同步:

例:

想象一下,表格中填充了以下數據:

表“MailAccount”(當前auto_increment值:2)

MAIL_ACCOUNT_ID NAME
0               Account1
1               Account2

表“IncomingMailServer”(當前auto_increment值:2)

MAIL_SERVER_ID  MAIL_ACCOUNT_ID
0               0
1               1

現在,圖像ID = 1的帳戶被刪除,新帳戶被添加。 然后發生以下有時:

表“MailAccount”(當前auto_increment值:3)

MAIL_ACCOUNT_ID NAME
0               Account1
1               Account2
2               Account3

表“IncomingMailServer”(當前auto_increment值:2)

MAIL_SERVER_ID  MAIL_ACCOUNT_ID
0               0
1               2

這完全擾亂了我的數據庫一致性。 我怎么能避免這個?

如果需要共享主鍵,則只能使用本機ID生成器一次。 您首先創建郵件帳戶,這將生成自己的ID,但是當您創建Incoming-或OutgoingMailServer時,這些需要從mailAccount屬性中獲取其ID。

所以你需要“外來”發電機:

<class name="OutgoingMailServer">
    <id name="id" column="MAIL_SERVER_ID"> 
       <generator class="foreign"> 
           <param name="property">mailAccount</param> 
       </generator>
    </id>
    <one-to-one name="mailAccount" not-null="true" constrained="true"/>
<class>

您不需要MAIL_ACCOUNT_ID列,因為它始終與MAIL_SERVER_ID完全相同。

基本遵循關於主鍵上的雙向一對一關聯的參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM