2011-05-03 43 views
3

我目前想我的Java类层次结构映射到使用Hibernate我的数据库,但我一直用下面的(子)类没有保存正确的鉴别值:如何通过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(); 
    } 
} 

性质incomingServer和outgoingServer中当然MailAccount.java仅持有的实例任Pop3Server,ImapServer(对于incomingServer)或SMTPSERVER(用于outgoingServer)。

我使用下面的映射配置:

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> 

问题:每当我告诉Hibernate来保存麦的实例lAccount,像这样:

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

.. Hibernate正确存储所有内容,除了表MailServer中的鉴别器列SERVER_TYPE以外。 在此列,休眠应该将任“IMAP_SERVER”,“POP3_SERVER”或“SMTP_SERVER”,而是将其保存或者“INCOMING_SERVER”或“OUTGOING_SERVER”。

当我尝试从数据库中加载这个实体时,发生了一个异常(当然),因为Hibernate试图实例化两个抽象类型的“IncomingMailServer”或“OutgoingMailServer”类型的对象。 所以,我如何才能休眠保存正确的类型?

例子:如果incomingServer持有Pop3Server实例的属性,则应该的Hiberante存储到我的数据库,当我加载根据MailAccount回来了,我想休眠重新Pop3Server的一个实例。

注:我是Hibernate的新手,这些是我的第一步,所以请温柔:-)。我很清楚,我.hmb.xml文件可能会显得凌乱,所以如果你有改进建议,继续:-)

+1

我不没有使用.hbm文件的经验,但指定抽象类的鉴别器值有什么意义?你不应该只为叶子指定这些吗? – 2011-05-03 12:36:57

+0

嗨,谢谢你的回复!当我删除行'和''时,我得到以下异常:'org.hibernate.MappingException:持久化类不知道:test.server.incoming.IncomingMailServer'。如果我只删除“discriminator-value =”INCOMING_SERVER“'和discriminator-value =”OUTGOING_SERVER“属性,那么Hibernate将保存完整的类名'test.server.incoming.IncomingMailServer'和'test.server.outgoing。 OutgoingMailServer'到鉴别器列SERVER_TYPE – Timo 2011-05-03 12:57:28

回答

2

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

太棒了!有效。非常感谢! – Timo 2011-05-03 13:56:18

相关问题