Как сохранить правильное значение дискриминатора через Hibernate - PullRequest
3 голосов
/ 03 мая 2011

В настоящее время я пытаюсь отобразить мою иерархию классов Java в моей базе данных, используя Hibernate, но мне не удается выполнить следующие (под-) классы:

У меня есть класс с именем MailAccount, который имеет 3 свойства (см. Кодниже):

public class MailAccount{
    long id;
    IncomingMailServer  incomingServer;
    OutgoingMailServer  outgoingServer;

    public MailAccount(){
        super();
    }

    // Getter and setter omitted
}

Иерархия класса сервера выглядит следующим образом:

MailServer.java

public abstract class MailServer {
    String password;
    String host;
    String username;
    String port;

    // Getter and setter omitted
}

IncomingMailServer.java

public abstract class IncomingMailServer extends MailServer {
}

OutgoingMailServer.java

public abstract class OutgoingMailServer extends MailServer {
}

Pop3Server.java

public class Pop3Server extends IncomingMailServer{
    public Pop3Server(){
        super();
    }
}

ImapServer.java

public class ImapServer extends IncomingMailServer{
    public ImapServer(){
        super();
    }
}

SmtpServer.java

public class SmtpServer extends OutgoingMailServer{
    public SmtpServer(){
        super();
    }
}

Свойства входящий и исходящий сервер в MailAccount.java, конечно, содержат только экземплярыPop3Server, ImapServer (для входящего сервера) или SmtpServer (для исходящего сервера).

Я использую следующую конфигурацию сопоставления:

MailAccount.hbm.xml

<hibernate-mapping package="test.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">
        </one-to-one>
        <one-to-one name="outgoingServer" cascade="all">
        </one-to-one>
    </class>
</hibernate-mapping>

MailServer.hbm.xml

<hibernate-mapping>
    <class name="test.server.MailServer" table="MAILSERVER" abstract="true">

        <id name="id" type="long" access="field">
            <column name="MAIL_SERVER_ID" />
            <generator class="native" />
        </id>

        <discriminator column="SERVER_TYPE" type="string"/>

        <property name="password" column="PASSWORD" />
        <property name="host" column="HOST" />
        <property name="username" column="USERNAME" />
        <property name="port" column="PORT" />

        <one-to-one name="mailAccount" class="test.account.MailAccount" foreign-key="MAIL_SERVER_ID"></one-to-one>

        <subclass name="test.server.incoming.ImapServer" extends="test.server.incoming.IncomingMailServer" discriminator-value="IMAP_SERVER">
        </subclass>

        <subclass name="test.server.incoming.Pop3Server" extends="test.server.incoming.IncomingMailServer" discriminator-value="POP3_SERVER">
        </subclass>

        <subclass name="test.server.outgoing.SmtpServer" extends="test.server.outgoing.OutgoingMailServer" discriminator-value="SMTP_SERVER">
        </subclass>

        <subclass name="test.server.incoming.IncomingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="INCOMING_SERVER">
        </subclass>

        <subclass name="test.server.outgoing.OutgoingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="OUTGOING_SERVER">
        </subclass>

    </class>
</hibernate-mapping>

Проблема: Всякий раз, когда я звонюl Hibernate для сохранения экземпляра MailAccount, например:

session = getSession();
transaction = session.beginTransaction();
session.save(mailAccount);
transaction.commit();

.. Hibernate правильно хранит все, КРОМЕ столбца дискриминатора SERVER_TYPE в таблице MailServer.В этом столбце Hibernate должен хранить либо «IMAP_SERVER», «POP3_SERVER» или «SMTP_SERVER», но вместо этого он сохраняет либо «INCOMING_SERVER», либо «OUTGOING_SERVER».

Когда я пытаюсь загрузить эту сущность из базы данных,Исключение происходит (конечно), потому что Hibernate пытается создать объекты типа "IncomingMailServer" или "OutgoingMailServer", которые оба являются абстрактными.Итак, как мне получить Hibernate для сохранения правильного типа?

Пример: Если свойство входящийServer содержит экземпляр Pop3Server, то Hiberante должен сохранить это в моей базе данных, и когда я загружаюв соответствии с MailAccount, я хочу, чтобы Hibernate воссоздает экземпляр Pop3Server.

Примечание: Я довольно новичок в Hibernate, и это мои первые шаги в этом, поэтому будьте осторожны :-),Я знаю, что мои файлы .hmb.xml могут выглядеть грязно, поэтому, если у вас есть предложения по улучшению, продолжайте: -)

1 Ответ

2 голосов
/ 03 мая 2011

Вложенность <subclass> элементов должна напоминать иерархию наследования:

<subclass name="test.server.incoming.IncomingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="INCOMING_SERVER">
    <subclass name="test.server.incoming.ImapServer" extends="test.server.incoming.IncomingMailServer" discriminator-value="IMAP_SERVER">
    </subclass> 
    <subclass name="test.server.incoming.Pop3Server" extends="test.server.incoming.IncomingMailServer" discriminator-value="POP3_SERVER">
    </subclass>
</subclass>

<subclass name="test.server.outgoing.OutgoingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="OUTGOING_SERVER">
    <subclass name="test.server.outgoing.SmtpServer" extends="test.server.outgoing.OutgoingMailServer" discriminator-value="SMTP_SERVER">
    </subclass>
</subclass>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...