[Hibernate 3]Exception avec Polymorphisme : Hibernate veut instancier l'interface!
Bonjour,
J'ai 2 classes qui implémentent une interface. J'essaye d'utiliser le polymorphisme d'Hibernate pour pouvoir manipuler mes données à l'aide de l'interface : je souhaite qu'en faisant une requête sur l'interface, Hibernate renvoie les objets des classes l'implémentant.
Petit rappel :
http://www.hibernate.org/hib_docs/v3...heritance.html
Le même en anglais :
http://www.hibernate.org/hib_docs/v3...heritance.html
Mais je déclenche une exception car Hibernate essaye d'instancier l'interface elle-même! Voici le fichier de mapping.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entreprise.gestapp.backend.model.ChampDemandeInterface" abstract="true">
<meta attribute="class-description" inherit="false">
@hibernate
</meta>
<composite-id>
<meta attribute="class-description" inherit="false">
@hibernate.id
generator-class="assigned"
</meta>
<!-- bi-directional many-to-one association to ChampEtat -->
<key-many-to-one
name="champEtat"
class="com.entreprise.gestapp.backend.model.ChampEtat"
>
<meta attribute="field-description">
@hibernate.many-to-one
column="cha_cod""
</meta>
<column name="cha_cod" />
</key-many-to-one>
<!-- bi-directional many-to-one association to Demande -->
<key-many-to-one
name="demande"
class="com.entreprise.gestapp.backend.model.Demande"
>
<meta attribute="field-description">
@hibernate.many-to-one
column="dem_num""
</meta>
<column name="dem_num" />
</key-many-to-one>
</composite-id>
<union-subclass name="com.entreprise.gestapp.backend.model.ChampDemandeTexte" table="champdemandetexte">
<property
name="valueTexte"
type="java.lang.String"
column="chd_valuetexte"
not-null="false"
length="32"
>
<meta attribute="field-description">
@hibernate.property
column="chd_valuetexte"
not-null="false"
length="32"
</meta>
</property>
</union-subclass>
<union-subclass name="com.entreprise.gestapp.backend.model.ChampDemandeDate" table="champdemandedate">
<property
name="valueDate"
type="java.util.Date"
column="chd_valuedate"
not-null="false"
>
<meta attribute="field-description">
@hibernate.property
column="chd_valuedate"
not-null="false"
</meta>
</property>
</union-subclass>
</class>
</hibernate-mapping> |
et le code effectuant la requête :
Code:
1 2 3
|
Criteria crit = getSession().createCriteria(ChampDemandeInterface.class);
List listDemandeChampsModel = crit.list(); |
J'ai enlevé tous les critères pour rendre le code plus lisible, j'ai d'ailleurs testé le code ainsi.
J'obtiens alors l'exception suivante:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: com.entreprise.gestapp.backend.model.ChampDemandeInterface
at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:56)
at org.hibernate.tuple.AbstractComponentTuplizer.instantiate(AbstractComponentTuplizer.java:89)
at org.hibernate.type.ComponentType.instantiate(ComponentType.java:345)
at org.hibernate.type.ComponentType.instantiate(ComponentType.java:351)
at org.hibernate.type.EmbeddedComponentType.instantiate(EmbeddedComponentType.java:52)
at org.hibernate.type.ComponentType.resolve(ComponentType.java:441)
at org.hibernate.type.ComponentType.nullSafeGet(ComponentType.java:182)
at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:759)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:292)
at org.hibernate.loader.Loader.doQuery(Loader.java:412)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
at org.hibernate.loader.Loader.doList(Loader.java:1593)
at org.hibernate.loader.Loader.list(Loader.java:1577)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:111)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1322)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
at com.entreprise.gestapp.backend.dao.DemandeDao.getListDemandeChamps(DemandeDao.java:762)
at com.entreprise.gestapp.backend.dao.DemandeDao.transformModelToTransport(DemandeDao.java:148)
at com.entreprise.gestapp.backend.dao.DemandeDao.transformModelToTransportWithLibelle(DemandeDao.java:244)
at com.entreprise.gestapp.backend.dao.DemandeDao.getListDemande(DemandeDao.java:522)
at com.entreprise.gestapp.backend.service.DemandeManager.getListDemande(DemandeManager.java:152)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:292)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:122)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy10.getListDemande(Unknown Source)
at com.entreprise.gestapp.frontend.webapp.action.PortefeuilleListActionBean.getListDemande(PortefeuilleListActionBean.java:308) |
au lieu d'une belle liste contenant des objets de classe ChampDemandeTexte et CHampDemandeDate, les deux classes implémentant l'interface ChampDemandeInterface. ChampDemandeTexte et ChampDemandeTexte sont des classes de données classiques, avec uniquement des getters et des setters.
J'ai fait la même chose pour une autre hiérarchie interface - classe similaire, le concept lui-même est donc viable. (L'autre hiérarchie utilise cependant une séquence pour créer sa clé primaire, pas deux clés étrangère. J'ignore si c'est important.)
J'ai essayé de faire une requête directement sur la classe ChampDemandeTexte, sans faire un autre fichier de mapping. Hibernate a quand même essayé d'instancier ChampDemandeInterface!
J'avoue que je suis perdu. Quelqu'un sait-il ce qui ne va pas?