J'essaie d'apprendre JSP et les servlets en réalisant un projet. Mon objectif n'est pas de me concentrer sur JPA, ORM et la persistance, ni même sur les EJB pour le moment. Alors, s'il vous plaît, ne me dites pas de lire un tutoriel ou un livre à ce sujet. Malheureusement, je ne suis pas censé utiliser les requêtes SQL pour interagir avec la base de données. Au lieu de cela, j'ai utilisé du code JPA pré-écrit pour gérer la persistance pendant que je me concentrais sur jsp et les servlets.
Lorsque j'exécute mon projet, le message d'erreur suivant s'affiche - Java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName AffableBeanPU.
Mon projet est situé à l'emplacement suivant: - https://github.com/double-whammy/affablebean.git le coin droit.
Remarque - Mon fichier persistence.xml IS situé dans le dossier META-INF. J'ai vérifié et construit mon projet à nouveau. Donc, cette raison peut être exclue.
J'ai googlé et aucune des solutions n'a été d'aide. Comment puis-je corriger cette erreur?
MyProject
|
|__Java (src folder)
| |
| |__controller (package)
| | |__ControllerServlet.Java
| |
| |__entity (entity classes here)
| |__session (facade classes for each entity class)
|
|
|__WebContent
|
|__WEB-INF
|
|__view
| |__category.jsp
| |
| |etc...
|
|__index.jsp
Exception:
Time|Info: Redirecting to /index.jsf
Time|Info: Admin Console: Initializing Session Attributes...
Time|Warning: EJB5184:A system exception occurred during an invocation on EJB CategoryFacade,
method: public Java.util.List session.AbstractFacade.findAll()
Time|Warning: javax.ejb.EJBException
at com.Sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.Java:748)
at com.Sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.Java:698)
at com.Sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.Java:503)
at com.Sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.Java:4475)
at com.Sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.Java:2009)
at com.Sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.Java:1979)
at com.Sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.Java:220)
at com.Sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.Java:88)
at com.Sun.proxy.$Proxy193.findAll(Unknown Source)
at session.__EJB31_Generated__CategoryFacade__Intf____Bean__.findAll(Unknown Source)
at controller.ControllerServlet.init(ControllerServlet.Java:31)
at javax.servlet.GenericServlet.init(GenericServlet.Java:244)
at org.Apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.Java:1583)
at org.Apache.catalina.core.StandardWrapper.allocate(StandardWrapper.Java:1212)
etc ................................................... etc...
at Java.lang.Thread.run(Thread.Java:745)
Caused by: Java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName AffableBeanPU
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.Java:138)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.Java:171)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.getCriteriaBuilder(EntityManagerWrapper.Java:834)
at session.AbstractFacade.findAll(AbstractFacade.Java:41)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
etc ................................................... etc...
at com.Sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.Java:212)
... 33 more
Time|Severe: WebModule[/AffableBean]StandardWrapper.Throwable
javax.ejb.EJBException
at com.Sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.Java:748)
at com.Sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.Java:698)
at com.Sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.Java:503)
etc ................................................... etc...
at session.__EJB31_Generated__CategoryFacade__Intf____Bean__.findAll(Unknown Source)
at controller.ControllerServlet.init(ControllerServlet.Java:31)
at javax.servlet.GenericServlet.init(GenericServlet.Java:244)
at org.Apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.Java:1583)
at org.Apache.catalina.core.StandardWrapper.allocate(StandardWrapper.Java:1212)
etc ................................................... etc...
at Java.lang.Thread.run(Thread.Java:745)
Caused by: Java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName AffableBeanPU
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.Java:138)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.Java:171)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.getCriteriaBuilder(EntityManagerWrapper.Java:834)
at session.AbstractFacade.findAll(AbstractFacade.Java:41)
etc ................................................... etc...
at com.Sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.Java:212)
... 33 more
Time|Warning: StandardWrapperValve[ControllerServlet]: Allocate exception for servlet ControllerServlet
Java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName AffableBeanPU
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.Java:138)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.Java:171)
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.getCriteriaBuilder(EntityManagerWrapper.Java:834)
at session.AbstractFacade.findAll(AbstractFacade.Java:41)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
etc ................................................... etc...
Persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://Java.Sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence http://Java.Sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="AffableBeanPU"
transaction-type="JTA">
<jta-data-source>jdbc/affablebean</jta-data-source>
<properties>
<property name="eclipselink.logging.level" value="FINEST" />
</properties>
</persistence-unit>
</persistence>
Le /META-INF/persistence.xml
doit se retrouver dans le chemin d'accès aux classes, pas dans les ressources Web. Donc, vous devez le placer dans le dossier source Java, pas dans le dossier de contenu Web. Le persistence.xml
n'est pas lié aux ressources Web, mais aux beans Java.
Déplacez-le:
MyProject
|-- Java (src folder)
| |-- controller
| | `--ControllerServlet.Java
| |-- entity
| |-- session
| `-- META-INF
| `-- persistence.xml <-- Here.
`--WebContent
`-- WEB-INF
|-- view
| |-- category.jsp
| `-- etc..
`-- index.jsp
De cette façon, la construction produira la structure WAR appropriée avec /META-INF/persistence.xml
à l'intérieur de /WEB-INF/classes
. Vous semblez utiliser Eclipse, vous pouvez également y parvenir en sélectionnant la facette JPA dans les propriétés du projet.
De cette façon, Eclipse générera un persistence.xml
au bon endroit.
Vous mentionnez que votre persistence.xml
est présent dans META-INF
. Si vous déployez cette application en tant que fichier WAR
, votre persistence.xml
doit être empaqueté en tant que
WEB-INF
`- classes
`- META-INF
`- persistence.xml`
Selon la spécification JPA 2.0 , section 8.2 Emballage d'unité de persistance :
Une unité de persistance est définie par un fichier persistence.xml. Le fichier ou le répertoire jar dont le répertoire META-INF contient le fichier persistence.xml est appelé la racine de l'unité de persistance. Dans les environnements Java EE, la racine d'une unité de persistance doit être l'une des suivantes:
• un fichier EJB-JAR
• le répertoire WEB-INF/classes d'un fichier WAR
• un fichier jar dans le répertoire WEB-INF/lib d'un fichier WAR
• un fichier jar dans le répertoire de la bibliothèque EAR
• un fichier jar de client d'applicationIl n'est pas nécessaire qu'un fichier EJB-JAR ou WAR contenant une unité de persistance soit intégré dans un fichier EAR, à moins que l'unité de persistance ne contienne des classes de persistance autres que celles contenues dans le fichier EJB-JAR ou WAR.
Parce que votre projet a une structure incorrecte. Créez deux parties distinctes pour ejb et une application Web, puis compressez-les dans EAR ou utilisez CDI. JPA (dont EntityManagerFactory fait partie) n'est tout simplement pas activé par conteneur pour votre application.
Pour application d'entreprise:
http://www.youtube.com/watch?v=32wpTh1TmY4
Pour CDI:
J'ai eu un problème similaire avec le serveur Embedded Glassfish, causé par:
Java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName cis_ejbPU
at com.Sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.Java:132)
POUR LE RÉSOUDRE, JE DID CE QUI SUIT
1) Dans le fichier pom.xml, ajoutez les dépendances suivantes
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.2-b06</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
2) Configurer les propriétés HashMap pour le conteneur incorporé
File target = prepareModuleDirectory();
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(EJBContainer.MODULES, target);
properties.put("org.glassfish.ejb.embedded.glassfish.installation.root", "./src/test/glassfish/");
properties.put("org.glassfish.ejb.embedded.glassfish.configuration.file", "./src/test/glassfish/domains/domain1/config/domain.xml");
container = javax.ejb.embeddable.EJBContainer.createEJBContainer(properties);
3)
private static final String MODULE_NAME = "embedded";
private static final String TARGET_DIR = "target/" + MODULE_NAME;
private static File prepareModuleDirectory() throws IOException {
File result = new File(TARGET_DIR);
FileUtils.copyDirectory(new File("target/classes"), result);
FileUtils.copyFile(new File("target/test-classes/META-INF/persistence.xml"),
new File(TARGET_DIR + "/META-INF/persistence.xml"));
return result;
}
4) créer la structure de dossier sous
src\test\glassfish\domains\domain1\config
et copiez le fichier glassfish domain.xml présent sous
<glassfish server install> glassfish\domains\domain1\config to src\test\glassfish\domains\domain1\config.
J'ai suivi les étapes ci-dessus pour résoudre le problème.