我目前想我的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