简体   繁体   English

Hibernate:由于一对一关系而导致主键生成不一致

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

I have two one-to-one relations here between a class called "MailAccount" and the classes "IncomingServer" and "OutgoingServer". 我在一个名为“MailAccount”的类和“IncomingServer”和“OutgoingServer”类之间有两个一对一的关系。

(It's a Java application running on Tomcat and Ubuntu server edition). (它是在Tomcat和Ubuntu服务器版上运行的Java应用程序)。

The mapping looks like this: 映射看起来像这样:

MailAccount.hbm.xml 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 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 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>

The class hierarchy looks like this: 类层次结构如下所示:

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{
 // ...
}

Now, here comes the problem : 现在, 问题出现

Although most of the time my application runs well, there seems to be one situation in which email servers get deleted, but the corresponding account doesn't and that's when this call is made: 虽然大部分时间我的应用程序运行良好,但似乎有一种情况是电子邮件服务器被删除,但相应的帐户没有,而且这是在进行此调用时:

session.delete(mailAccountInstance);

In a one-to-one relation in Hibernate, the primary keys between mail account and its servers must be equal, if not, the relation completely gets out of sync: 在Hibernate中的一对一关系中,邮件帐户与其服务器之间的主键必须相等,否则,关系完全不同步:

Example: 例:

Imagine, the tables are filled with data like this: 想象一下,表格中填充了以下数据:

Table "MailAccount" (Current auto_increment value: 2) 表“MailAccount”(当前auto_increment值:2)

MAIL_ACCOUNT_ID NAME
0               Account1
1               Account2

Table "IncomingMailServer" (Current auto_increment value: 2) 表“IncomingMailServer”(当前auto_increment值:2)

MAIL_SERVER_ID  MAIL_ACCOUNT_ID
0               0
1               1

Now, image the account with ID=1 gets deleted and new accounts get added. 现在,图像ID = 1的帐户被删除,新帐户被添加。 The following then SOMETIMES happens: 然后发生以下有时:

Table "MailAccount" (Current auto_increment value: 3) 表“MailAccount”(当前auto_increment值:3)

MAIL_ACCOUNT_ID NAME
0               Account1
1               Account2
2               Account3

Table "IncomingMailServer" (Current auto_increment value: 2) 表“IncomingMailServer”(当前auto_increment值:2)

MAIL_SERVER_ID  MAIL_ACCOUNT_ID
0               0
1               2

This completely messes up my database consistency. 这完全扰乱了我的数据库一致性。 How can I avoid this? 我怎么能避免这个?

If you want a shared primary key, you can use the native id generator only once. 如果需要共享主键,则只能使用本机ID生成器一次。 You create the mail account first, which will generate its own id, but when you create the Incoming- or OutgoingMailServer, these need to take their id from the mailAccount property. 您首先创建邮件帐户,这将生成自己的ID,但是当您创建Incoming-或OutgoingMailServer时,这些需要从mailAccount属性中获取其ID。

So you need the "foreign" generator: 所以你需要“外来”发电机:

<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>

You don't need a MAIL_ACCOUNT_ID column, since it will always be identical to the MAIL_SERVER_ID anyway. 您不需要MAIL_ACCOUNT_ID列,因为它始终与MAIL_SERVER_ID完全相同。

Quite basic follow the reference about bidirectional one-to-one association on a primary key . 基本遵循关于主键上的双向一对一关联的参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在休眠中实现一对一的外键关系映射 - how to implement one-to-one foreign key relation mapping in hibernate 休眠+春季+保持一对一关系+空外键 - Hibernate + Spring + persist one-to-one relation + empty foreign key 在另一个充当主键的实体上休眠一对一映射 - Hibernate one-to-one mapping on another entity acting as primary key JPA / Hibernate使用共享主键进行单向一对一映射 - JPA / Hibernate unidirectional one-to-one mapping with shared primary key JPA 2:通过查找JoinColumn-一对一关系中的共享主键来确定实体ID - JPA 2: Determine an entitys id by looking up JoinColumn - Shared primary key in one-to-one relation 休眠外键一对一单向 - Hibernate One-to-One unidirectional on foreign key 休眠外键一对一null - Hibernate one-to-one null in foreign key 尽管没有外键,Hibernate 如何以一对一的关系匹配实体? - How Hibernate match entity in one-to-one relation, despite of absence of a foreign Key? 如何确保 hibernate 5 在与共享主键的一对一关系中以正确的顺序持续存在 - How to make sure hibernate 5 persists in the correct order in a one-to-one relationship with shared primary key 如何在非主键上使用休眠注释设置单向一对一关系? - how to set unidirectional one-to-one relationship using hibernate annotation on a non-primary key?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM