J'ai un problème lorsqu'une entité est mappée sur une autre entité qui a une mise en œuvre directe sur ses sous-classes. Voir l'exemple de mappage ci-dessous: MAINTENANT, c'est ce que j'ai sur ma table de base de données: p> emplacement-table:
id = 1, personne_id = 1
Personne-table:
ID = 1, personne_type = "m" p> Lorsque je récupère l'emplacement à l'aide de l'entité gestionnaire, Hibernate jette une exception disant que je ne peux pas instancier une classe abstraite ou une interface. P> javax.persistence.PersistenceException: org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: Person
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:195)
at ......
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runTestMethod(UnitilsJUnit4TestClassRunner.java:174)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:156)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:44)
at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:62)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:68)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
7 Réponses :
Comme indiqué dans mon commentaire ci-dessus, j'ai essayé la même chose avec Eclipselink et ça fonctionne.
Après avoir créé des données de test, j'ai effacé la valeur discriminatrice d'une entrée de personne dans la DB et je reçois maintenant une exception similaire lors de la tentative de chargement de l'emplacement associé. Eclipselink's Message est un peu plus descriptif: p> Le mappage semble fonctionner, de sorte que si les données ne sont "corrompues" (que ce n'est pas dans votre cas comme vous l'avez dit. ), c'est probablement un bug ou au moins un comportement différent dans l'hibernate. p> p>
de Tutoriel Java EE 6 - Intérité de l'entité A >: p>
n'importe quelle cartographie ou relation
Annotations dans les superclasses de non-entité
sont ignorés. P>
blockQuote>
Vous semblez donc être correct que vous devez annoter la classe du @mapsuperclass Javadoc P >
une classe désignée avec le
L'annotation mapperclass peut être
mappé de la même manière qu'une entité
Sauf que les mappages s'appliqueront
seulement à ses sous-classes depuis aucune table
existe pour la superclasse mappée
lui-même. p>
blockQuote>
Vous ne pouviez donc pas utiliser semble que les annotations JPA que vous utilisez sont correctes. Avez-vous essayé la suggestion de @Martin Klinke d'une valeur nominale discriminator pour la classe code> la classe code> p>
personne code> avec
@entity code> pour l'associer à un emplacement code> via
@Enetoone code>. P>
@mapapsuperclass code> sur personne, puis mappez-le avec le
@onetoone code>, car il n'y aurait pas de table de personne. P>
Cela a résolu mon problème, j'ai oublié @enttity sur la sous-classe et j'ai reçu la même erreur jusqu'à ce que je l'ai ajouté à la classe enfant.
J'ai trouvé ce genre de problème de problème lui-même si les classes d'entité implémentent sérialisable code>. p>
Je rencontre un code similaire à cela, avec quelques différences. Premièrement, je place la classe abstraite derrière une interface. Deuxièmement, je définis explicitement la cépitée de la cartographie @Enetoone. Un exemple serait: ici j'ai renommé classe abstraite de votre personne à "abstractperson" pour la clarté. A pris un peu de jeu pour le faire fonctionner, j'espère que cela résout votre problème. P> p>
Essayez d'ajouter @Forcediscriminator à la personne. Sans cette annotation Hibernate tente souvent d'instancier la classe mère, en ignorant le discriminateur qui devrait lui dire quelle classe enfant à instanecter. P>
J'ai eu un message d'erreur similaire avec la structure suivante: avec une instance d'enfant concrete p> et une classe qui a Un champ référençant la classe abstraite: p> Les modifications suivantes résolvent le problème pour moi: P> MISE À JOUR: J'ai également trouvé que je n'établissais pas l'objet Realperson avant de le relier à la somlasse. Alors maintenant, j'ai d'abord enregistrer l'instance en premier, l'attribut
@onetoone code> à
@onetoone (cascade = cascadetype.all) code> li>
@generatedValue code> à
@generatedValue (stratégie = générationtype.table) code> li>
OL>
cascade code> n'est plus requis p> p>
Cela m'a fait le tour pour moi, en utilisant Hibernate comme fournisseur de persistance.
@OneToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE})
Quel est le type de données de votre colonne discriminator dans la DB?
Pouvez-vous montrer la structure complète?
Avez-vous essayé @mapsuperclass au lieu de @entity sur personne?
Cet article sur le forum peut également aider aussi bien que cela soit à partir de 2007. Essentiellement, Il suggère d'ajouter une valeur discriminatrice factice à la classe de base abstraite.
@Martin - Je veux stocker ces entités sur la même table et je suppose @MePapsuPlassclass ne peut pas être cartographié sur une relation d'entité. @Un par un
J'ai essayé votre exemple avec Eclipselink tel quel et je ne reçois aucune exception. Peut-être que c'est un problème avec la façon dont vous avez initialement initialisé les données? Y a-t-il une entrée sans valeur dans la colonne discriminator de la table de la personne?