我有以下课程hierachy:
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{
// ...
}
我的(简化)映射文件如下所示:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<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>
<component name="incomingServer">
<component name="hostAddress">
<property name="address" column="IS_HOST_ADDRESS"></property>
</component>
<component name="port">
<property name="portNumber" column="IS_PORT_NUMBER"></property>
</component>
</component>
<component name="outgoingServer">
<component name="hostAddress">
<property name="address" column="OS_HOST_ADDRESS"></property>
</component>
<component name="port">
<property name="portNumber" column="OS_PORT_NUMBER"></property>
</component>
</component>
</class>
</hibernate-mapping>
问题:当我拨打session.save(mailAccountInstance);
时,Hibernate会抛出此异常:
org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: IncomingMailServer
因此,我将以下行添加到incomingServer组件:
<discriminator column="SERVER_TYPE" type="string"/>
<subclass name="ImapServer" extends="IncomingMailServer" discriminator-value="IMAP_SERVER" />
<subclass name="Pop3Server" extends="IncomingMailServer" discriminator-value="POP3_SERVER" />
到传出服务器:
<discriminator column="SERVER_TYPE" type="string"/>
<subclass name="SmtpServer" extends="OutgoingMailServer" discriminator-value="SMTP_SERVER" />
但是现在,Hibernate给了我这个错误信息:
org.xml.sax.SAXParseException: The content of element type "component" must match "(meta*,tuplizer*,parent?,(property|many-to-one|one-to-one|component|dynamic-component|any|map|set|list|bag|array|primitive-array)*)".
显然,Hibernate不喜欢组件中的这些标签。
我该如何解决这个问题?
Ps:我已经尝试将IncomingServer和OutgoingServer各自移动到他们自己的表中并通过一对一映射它们。这有效但导致数据库不一致,因为我注意到MailAccount和IncomingServer / OutgoingServer必须始终具有相同的主键ID。如果没有,一切都不同步,主键的自动增量值不再匹配(在Mailaccount和服务器之间)。
答案 0 :(得分:4)
这个映射对我有用:
<class name="MailServer" abstract="true" table="SERVER">
<id name="id" column="id">
<generator class="native" />
</id>
<discriminator column="SERVER_TYPE" type="string"/>
<subclass name="IncomingMailServer" abstract="true">
<property name="address" column="IS_HOST_ADDRESS"></property>
<property name="portNumber" column="IS_PORT_NUMBER"></property>
</subclass>
<subclass name="OutgoingMailServer" abstract="true">
<property name="address" column="OS_HOST_ADDRESS"></property>
<property name="portNumber" column="OS_PORT_NUMBER"></property>
</subclass>
</class>
<subclass name="IMAPServer" extends="com.mail.account.IncomingMailServer"
discriminator-value="IMAP_SERVER"/>
<subclass name="POP3Server" extends="com.mail.account.IncomingMailServer"
discriminator-value="POP3_SERVER"/>
<subclass name="SMTPServer" extends="com.mail.account.OutgoingMailServer"
discriminator-value="SMTP_SERVER" />
抽象类:
MailServer
是一个抽象类IncomingServer
是一个抽象类:这有助于不指定DISCRIMINATOR VALUE
OutgoingServer
是一个抽象类:这有助于不指定DISCRIMINATOR VALUE
具体课程:
IMAPServer
使用DISCRIMINATOR VALUE : IMAP
POP3Server
使用DISCRIMINATOR VALUE : POP3
SMTPServer
使用DISCRIMINATOR VALUE : SMTP
所有具体服务器都映射到同一个表“SERVER”,但是如果需要,可以使用连接表将它们映射到各个表。
我能够使用以下简单的代码片段保存实例:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction txn =session.beginTransaction();
IMAPServer imap=new IMAPServer();
imap.setAddress("SMTP_01");
imap.setPortNumber("SMTP_PORT_0001");
session.save(imap);
SMTPServer smtp=new SMTPServer();
smtp.setAddress("STMP_01");
smtp.setPortNumber("STMP_PORT_0001");
session.save(smtp);
MailAccount account=new MailAccount();
account.setIncomingServer(imap);
account.setOutgoingServer(smtp);
session.save(account);
txn.commit();
如果这解决了问题,请告诉我。 :)
编辑:将邮件从MailAccount添加到MailServer。
<class name="MailAccount" table="MAILACCOUNT" dynamic-update="true">
<id name="id" column="id">
<generator class="native" />
</id>
<many-to-one name="incomingServer" column="incoming" unique="true"/>
<many-to-one name="outgoingServer" column="outgoing" unique="true"/>
</class>
答案 1 :(得分:0)
我的方法是:
而且,请告诉我们更多代码。如果不知道就很难提供帮助:)