本文介绍了休眠:“ InstantiationException:无法实例化抽象类或接口”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下类层次结构:

I have the following class 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{
 // ...
}

我的(简化的)映射文件如下:

My (simplified) mapping file looks like this:

<?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>

问题:当我呼叫<$ c $时,Hibernate抛出此异常c> session.save(mailAccountInstance); :

org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: IncomingMailServer

因此,我在呼入服务器组件中添加了以下几行:

So, I added the following lines to the incomingServer component:

<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给了我这个错误信息:

But now, Hibernate gives me this error message:

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不喜欢组件中的这些标签。

Obviously, Hibernate does not like these tags in components.

我该如何解决?

Ps :我已经尝试移动IncomingServer和OutgoingServer每个都映射到自己的表格并通过一对一映射。那行得通,但是会导致数据库不一致,因为我注意到MailAccount和IncomingServer / OutgoingServer必须始终具有相同的主键ID。如果不是,则所有内容都不同步,并且主键的自动增量值不再匹配(在Mailaccount和Servers之间)。

Ps: I already tried moving IncomingServer and OutgoingServer each to their own tables and map them via a one-to-one. That works but leads to inconsistencies in the database because I noticed that MailAccount and IncomingServer/OutgoingServer must always have the same primary key id. If not, everything gets out of sync and the autoincrement value for the primary keys don't match any more (between Mailaccount and Servers).

推荐答案

此映射对我有用:








<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 是一个抽象类:这有助于不指定判别值

  • OutgoingServer 是一个抽象类:这有助于不指定标识符值

  • MailServer is an abstract class
  • IncomingServer is an abstract class : this helped NOT specifing DISCRIMINATOR VALUE
  • OutgoingServer is an abstract class : this helped NOT specifing DISCRIMINATOR VALUE

具体类别:


  • IMAPServer DISCRIMINATOR VALUE扩展了IncomingServer:IMAP

  • POP3Server DISCRIMINATOR VALUE扩展IncomingServer:POP3

  • SMTPServer DISCRIMINATOR VALUE扩展IncomingServer:SMTP

  • IMAPServer extends IncomingServer with DISCRIMINATOR VALUE : IMAP
  • POP3Server extends IncomingServer with DISCRIMINATOR VALUE : POP3
  • SMTPServer extends IncomingServer with DISCRIMINATOR VALUE : SMTP

所有具体服务器都映射到同一表 SERVER,但是如果需要,可以将它们映射到单个表

All the concrete servers are mapped to the same table "SERVER" however if need be they can be mapped to individual tables using join table.

我能够使用以下简单代码段保存实例:

I was able to save the instances using the following simple code snippet:

    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();

让我知道这是否可以解决问题。 :)

Let me know if this solves the problem. :)

编辑:添加了从MailAccount到MailServer的映射。

added the mapping from MailAccount to 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>

这篇关于休眠:“ InstantiationException:无法实例化抽象类或接口”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 16:38