java - org.hibernate.InstantiationException: How to tell Hibernate which class to use for object instantiation -


i trying replace own database controller implementation hibernate , have following problem creating appropriate mapping file.

(i new hibernate, please gentle :-) - i've read through whole hibernate reference documentation don't have practical experience yet).

(the whole thing should represent relationship between email accounts , server settings).

i have class called mailaccount has 2 properties (see code below):

public class mailaccount{     long id;     incomingmailserver  incomingserver;     outgoingmailserver  outgoingserver;      public mailaccount(){         super();     }      // getter , setter omitted } 

the server class hierachy looks this:

mailserver.java

public abstract class mailserver {     string password;     string host;     string username;     string port;      // getter , 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();     } } 

the properties incomingserver , outgoingserver in mailaccount.java of course hold instances of either pop3server, imapserver (for incomingserver) or smtpserver (for outgoingserver).

now, tried create mapping file mailaccount:

<?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="test.account">     <class name="mailaccount" table="mailaccounts" dynamic-update="true">          <id name="id" column="mail_account_id">             <generator class="native" />         </id>          <component name="incomingserver" class="test.server.incoming.incomingmailserver">             <property name="password" column="incoming_server_password" />             <property name="host" column="incoming_server_password" />             <property name="username" column="incoming_server_password" />             <property name="port" column="incoming_server_password" />         </component>          <component name="outgoingserver" class="test.server.outgoing.outgoingmailserver">             <property name="password" column="outgoing_server_password" />             <property name="host" column="outgoing_server_password" />             <property name="username" column="outgoing_server_password" />             <property name="port" column="outgoing_server_password" />         </component>     </class> </hibernate-mapping> 

note: since got 1:1 relation between mailaccount , incomingmailserver mailaccount , outgoingmailserver, want in 1 table in order prevent unnecessary joins.

the problem: whenever tell hibernate save instance of mailaccount, this:

session = getsession(); transaction = session.begintransaction(); session.save(mailaccount); transaction.commit(); 

.. following exception:

org.hibernate.instantiationexception: cannot instantiate abstract class or interface: test.server.incoming.incomingmailserver

this totally makes sense since abstract classes cannot instantiated.

however, here comes question: how can tell hibernate create instance of right class (pop3server, smtpserver, imapserver) instead of abstract ones?

example: if property incomingserver holds instance of pop3server, hiberante should store database , when load according mailaccount back, want hibernate recreate instance of pop3server.

the problem occurring because component not stand-alone entity, "a class instances stored intrinsic part of owning entity , share identity of entity". in jpa terms considered embeddable class. these classes used create class object out of number of table columns have stored individual attributes in entity (you can @ grouping).

while there number of benefits approach, there restrictions. 1 of these restrictions component or embeddable cannot abstract class. reason being there isn't way hibernate associate particular concrete subclass value trying store or read. think of way: able tell instance create looking @ column data? it's not straight forward, persistence engine.

in order functionality desire, want storing mailserver data separate entity own primary key field. doing allows manage data subclasses using various inheritance methods such including discriminatorcolumn or separate tables (depending on configuration).

here links should setting these mappings , using entity inheritance:

hope helps.

http://www.vaannila.com/hibernate/hibernate-example/hibernate-example.html

if use approach using hibernate (i prefer jpa-based annotation configurations), configure mailserver abstract entity define common column mappings between classes , discriminatorcolumn (if using same table inheritance). subclasses built off of definition, adding custom attributes needed.


Comments