我目前想我的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文件可能会显得凌乱,所以如果你有改进建议,继续:-)
我不没有使用.hbm文件的经验,但指定抽象类的鉴别器值有什么意义?你不应该只为叶子指定这些吗? – 2011-05-03 12:36:57
嗨,谢谢你的回复!当我删除行 '和' '时,我得到以下异常:'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