title: How to save the correct discriminator value through Hibernate
body: <p>I am currently trying to map my Java class hierarchy into my database using Hibernate but I keep failing with the following (sub-)classes:</p>
  
  <p>I have a class called MailAccount which has 3 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>I use the following mapping configuration:</p>
  
  <p><strong>MailAccount.hbm.xml</strong></p>
  
  <pre><code>&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;one-to-one name="incomingServer" cascade="all"&gt;
          &lt;/one-to-one&gt;
          &lt;one-to-one name="outgoingServer" cascade="all"&gt;
          &lt;/one-to-one&gt;
      &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  </code></pre>
  
  <p><strong>MailServer.hbm.xml</strong></p>
  
  <pre><code>&lt;hibernate-mapping&gt;
      &lt;class name="test.server.MailServer" table="MAILSERVER" abstract="true"&gt;
  
          &lt;id name="id" type="long" access="field"&gt;
              &lt;column name="MAIL_SERVER_ID" /&gt;
              &lt;generator class="native" /&gt;
          &lt;/id&gt;
  
          &lt;discriminator column="SERVER_TYPE" type="string"/&gt;
  
          &lt;property name="password" column="PASSWORD" /&gt;
          &lt;property name="host" column="HOST" /&gt;
          &lt;property name="username" column="USERNAME" /&gt;
          &lt;property name="port" column="PORT" /&gt;
  
          &lt;one-to-one name="mailAccount" class="test.account.MailAccount" foreign-key="MAIL_SERVER_ID"&gt;&lt;/one-to-one&gt;
  
          &lt;subclass name="test.server.incoming.ImapServer" extends="test.server.incoming.IncomingMailServer" discriminator-value="IMAP_SERVER"&gt;
          &lt;/subclass&gt;
  
          &lt;subclass name="test.server.incoming.Pop3Server" extends="test.server.incoming.IncomingMailServer" discriminator-value="POP3_SERVER"&gt;
          &lt;/subclass&gt;
  
          &lt;subclass name="test.server.outgoing.SmtpServer" extends="test.server.outgoing.OutgoingMailServer" discriminator-value="SMTP_SERVER"&gt;
          &lt;/subclass&gt;
  
          &lt;subclass name="test.server.incoming.IncomingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="INCOMING_SERVER"&gt;
          &lt;/subclass&gt;
  
          &lt;subclass name="test.server.outgoing.OutgoingMailServer" extends="test.server.MailServer" abstract="true" discriminator-value="OUTGOING_SERVER"&gt;
          &lt;/subclass&gt;
  
      &lt;/class&gt;
  &lt;/hibernate-mapping&gt;
  </code></pre>
  
  <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>.. Hibernate stores everything correctly EXCEPT for the discriminator column SERVER_TYPE in the table MailServer.
  In this column, Hibernate should store either "IMAP_SERVER", "POP3_SERVER" or "SMTP_SERVER" but instead it saves either "INCOMING_SERVER" or "OUTGOING_SERVER".</p>
  
  <p>When I try to load this entity from the database, an exception occurs (of course) because Hibernate is trying to instantiate objects of type "IncomingMailServer" or "OutgoingMailServer" which are both abstract.
  So, how do I get Hibernate to save the correct type?</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>
  
  <p><strong>Note:</strong> I am pretty new to Hibernate and these are my first steps with it, so please be gentle :-) . I am aware that my .hmb.xml files might look messy, so if you have suggestions for improvements, go ahead :-)</p>