在名爲「MailAccount」的類與「IncomingServer」和「OutgoingServer」類之間存在兩個一對一的關係。Hibernate:由於一對一關係而導致的主鍵生成不一致
(這是一個在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);
在休眠一對一的關係,郵件帳戶和它的服務器之間的主密鑰必須是相等的,如果不是,則關係完全得到不同步:
實施例:
想象,表中填充數據是這樣的:
表 「MailAccount」(當前AUTO_INCREMENT值:2)
MAIL_ACCOUNT_ID NAME
0 Account1
1 Account2
表 「IncomingMailServer」(當前auto_incremen t值: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
這完全弄亂我的數據庫一致。 我該如何避免這種情況?
如果沒有解決方案,那麼您聲明主鍵必須相同的一對一關係的部分是錯誤的。對於每個關係,MAILACCOUNTS中必須有一個匹配的表或帶有外鍵的列。 – Nicktar
Nicktar部分屬實。映射中的一對一關聯是通過在IncomingMailServer中存在外鍵MAIL_ACCOUNT_ID來實現的。 MailAccount和IncomingMailServer的主鍵可能完全不同。你的問題的診斷是錯誤的。如果某些郵件服務器消失了,那是因爲您將其刪除,或者因爲某個帳戶的郵件服務器設置爲空,由於delete-orphan配置,該郵件服務器從數據庫中刪除了郵件服務器。 –
@Nicktar這很奇怪。我沒有這樣的匹配表。 「外鍵」MAIL_ACCOUNT_ID與匹配沒有任何關係。如果Incoming-/OutgoingServer的主鍵不同步,則從此處的所有內容都會被徹底搞砸。關鍵的MAIL_ACCOUNT_ID仍然可以引用正確的MailAccount,但這沒有幫助。休眠只匹配PK的。 – Timo