gpt4 book ai didi

java - Hibernate:由于一对一关系,主键生成不一致

转载 作者:搜寻专家 更新时间:2023-11-01 02:53:00 25 4
gpt4 key购买 nike

我在名为“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

这完全破坏了我的数据库一致性。我怎样才能避免这种情况?

最佳答案

如果你想要一个共享的主键,你只能使用一次 native 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 相同。

基本遵循关于 bidirectional one-to-one association on a primary key 的引用.

关于java - Hibernate:由于一对一关系,主键生成不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7554535/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com