"MailAccount"というクラスと "IncomingServer"と "OutgoingServer"というクラスの間には、2つの1対1の関係があります。Hibernate:1対1の関係による一貫性のないプライマリキーの生成
(これは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{
// ...
}
、ここ問題来る:
私のアプリケーションがうまく実行されるほとんどの時間、1つの状況があるように思われるが、どの電子メールサーバーが削除されますが、対応するアカウントは対応していません。この呼び出しが行われます。
session.delete(mailAccountInstance);
休止状態で1対1の関係では、メールアカウントとそのサーバ間の主キーが同じでなければなりませんが、ない場合は、関係が完全に同期しなくなります:
例:
想像を
表 "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のアカウントは削除され、新しいアカウントが追加されます。 SOMETIMES次起こる:
表 "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
これは完全に台無し私のデータベースの一貫性。 どうすればこの問題を回避できますか?
解決策がなければ、プライマリキーが等しくなければならないことを1対1の関係で述べる部分は間違っています。リレーションごとに、MAILACCOUNTSに一致するテーブルまたは外部キーを持つ列が存在する必要があります。 – Nicktar
Nicktarは部分的に真です。マッピングの1対1関連は、IncomingMailServerの外部キーMAIL_ACCOUNT_IDの存在によって実現されます。 MailAccountとIncomingMailServerの主キーはまったく異なるかもしれません。あなたの問題の診断は間違っています。一部のメールサーバーが消えた場合は、メールサーバーが削除されたか、アカウントのメールサーバーがnullに設定されているためです。これは、delete-orphan configによってデータベースからメールサーバーが削除されたためです。 –
@Nicktarそれはとても奇妙です。私はそのような一致するテーブルがありません。 "外部キー" MAIL_ACCOUNT_IDはマッチングとは関係ありません。 Incoming-/OutgoingServerの主キーが同期しなくなると、そこからのすべてが完全に台無しになります。キーMAIL_ACCOUNT_IDは依然として正しいMailAccountを参照するかもしれませんが、それは役に立ちません。 HibernateはPKのものにしかマッチしません。 – Timo