У меня здесь два взаимно-однозначных отношения между классом с именем «MailAccount» и классами «IncomingServer» и «OutgoingServer».
(Это Java-приложение, работающее на серверах Tomcat и Ubuntu).
Отображение выглядит так:
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
Теперь изображение с идентификатором = 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
Это полностью нарушает целостность моей базы данных.
Как я могу избежать этого?