title: org.hibernate.InstantiationException: How to tell Hibernate which class to use for object instantiation
body: <p>I am currently trying to replace my own database controller implementation with Hibernate and I have the following problem creating an appropriate mapping file.</p>
  
  <p>(I am very new to Hibernate, so please be gentle :-) - I've read through the whole Hibernate Reference documentation but I don't have any practical experience yet).</p>
  
  <p>(The whole thing should represent the relationship between email accounts and their server settings).</p>
  
  <p>I have a class called MailAccount which has 2 properties (see code below):</p>
  
  <pre><code>public class MailAccount{
      long id;
      IncomingMailServer  incomingServer;
      OutgoingMailServer  outgoingServer;
  
      public MailAccount(){
          super();
      }
  
      // Getter and setter omitted
  }
  </code></pre>
  
  <p>The server class hierachy looks like this:</p>
  
  <p><strong>MailServer.java</strong></p>
  
  <pre><code>public abstract class MailServer {
      String password;
      String host;
      String username;
      String port;
  
      // Getter and setter omitted
  }
  </code></pre>
  
  <p><strong>IncomingMailServer.java</strong></p>
  
  <pre><code>public abstract class IncomingMailServer extends MailServer {
  }
  </code></pre>
  
  <p><strong>OutgoingMailServer.java</strong></p>
  
  <pre><code>public abstract class OutgoingMailServer extends MailServer {
  }
  </code></pre>
  
  <p><strong>Pop3Server.java</strong></p>
  
  <pre><code>public class Pop3Server extends IncomingMailServer{
      public Pop3Server(){
          super();
      }
  }
  </code></pre>
  
  <p><strong>ImapServer.java</strong></p>
  
  <pre><code>public class ImapServer extends IncomingMailServer{
      public ImapServer(){
          super();
      }
  }
  </code></pre>
  
  <p><strong>SmtpServer.java</strong></p>
  
  <pre><code>public class SmtpServer extends OutgoingMailServer{
      public SmtpServer(){
          super();
      }
  }
  </code></pre>
  
  <p>The properties incomingServer and outgoingServer in MailAccount.java of course only hold instances of either Pop3Server, ImapServer (for incomingServer) or SmtpServer (for outgoingServer).</p>
  
  <p>Now, I tried to create the mapping file for MailAccount:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&gt;
  &lt;hibernate-mapping package="test.account"&gt;
      &lt;class name="MailAccount" table="MAILACCOUNTS" dynamic-update="true"&gt;
  
          &lt;id name="id" column="MAIL_ACCOUNT_ID"&gt;
              &lt;generator class="native" /&gt;
          &lt;/id&gt;
  
          &lt;component name="incomingServer" class="test.server.incoming.IncomingMailServer"&gt;
              &lt;property name="password" column="INCOMING_SERVER_PASSWORD" /&gt;
              &lt;property name="host" column="INCOMING_SERVER_PASSWORD" /&gt;
              &lt;property name="username" column="INCOMING_SERVER_PASSWORD" /&gt;
              &lt;property name="port" column="INCOMING_SERVER_PASSWORD" /&gt;
          &lt;/component&gt;
  
          &lt;component name="outgoingServer" class="test.server.outgoing.OutgoingMailServer"&gt;
              &lt;property name="password" column="OUTGOING_SERVER_PASSWORD" /&gt;
              &lt;property name="host" column="OUTGOING_SERVER_PASSWORD" /&gt;
              &lt;property name="username" column="OUTGOING_SERVER_PASSWORD" /&gt;
              &lt;property name="port" column="OUTGOING_SERVER_PASSWORD" /&gt;
          &lt;/component&gt;
      &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  </code></pre>
  
  <p><strong>Note:</strong> Since I got a 1:1 relation between MailAccount and IncomingMailServer as well as MailAccount and OutgoingMailServer, I want everything in 1 table in order to prevent unnecessary joins.</p>
  
  <p><strong>The problem:</strong> Whenever I tell Hibernate to save an instance of MailAccount, like this:</p>
  
  <pre><code>session = getSession();
  transaction = session.beginTransaction();
  session.save(mailAccount);
  transaction.commit();
  </code></pre>
  
  <p>.. I get the following exception:</p>
  
  <blockquote>
    <p>org.hibernate.InstantiationException:
    Cannot instantiate abstract class or
    interface:
    test.server.incoming.IncomingMailServer</p>
  </blockquote>
  
  <p>This totally makes sense since abstract classes cannot be instantiated.</p>
  
  <p>However, <strong>here comes my question</strong>: How can I tell Hibernate to create an instance of the right class (Pop3Server, SmtpServer, ImapServer) instead of the abstract ones?</p>
  
  <p><strong>Example:</strong> If the property incomingServer holds an instance of Pop3Server, then Hiberante should store that into my database and when I load the according MailAccount back, I want Hibernate to recreate an instance of Pop3Server.</p>