I have a very simple web application running on WebSphere Application Server 18.0.0.2. The app is packaged into WAR and put under dropins (for simplicity).
My server.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
<featureManager>
<feature>javaee-8.0</feature>
</featureManager>
<httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" />
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<!-- THE JAR IS THERE (UNDER Liberty lib directory) -->
<library id="H2JDBCLib">
<fileset dir="${wlp.install.dir}/lib" includes="h2-1.4.197.jar"/>
</library>
<!-- AND THIS IS MY DATA SOURCE DEFINITION -->
<dataSource id="h2test" jndiName="jdbc/h2test">
<jdbcDriver libraryRef="H2JDBCLib"/>
<properties.db2.jcc databaseName="testdb" serverName="localhost" portNumber="8082" user="sa" />
</dataSource>
</server>
I have a very simple entity and a service (stateless EJB):
#Stateless
public class CustomerService {
#PersistenceContext(unitName = "h2test")
private EntityManager entityManager;
public List<Customer> getAllCustomers() {
return entityManager
.createNamedQuery(FIND_ALL, Customer.class)
.getResultList();
}
}
And my persistence.xml under META-INF looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1_0.xsd"
version="1.0">
<persistence-unit name="h2test" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/h2test</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
I thought these simple configs should be enough to be able to deploy and run this hello-world-type of app. But I am getting an error at runtime:
[ERROR ] CNTR0019E: EJB throws an exception when invoking "getAllCustomers".
Details: javax.ejb.EJBException: The java:comp/env/com.my.app.service.CustomerService/entityManager reference of type javax.persistence.EntityManager for the null component in the my-app.war module of the my-app application cannot be resolved.
at com.ibm.wsspi.injectionengine.InjectionBinding.getInjectionObject(InjectionBinding.java:1489)
at [internal classes]
at com.my.app.service.EJSLocalNSLCustomerService_22d8d9f5.getAllCustomers(EJSLocalNSLCustomerService_22d8d9f5.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
EntityManager injection fails. From IBM's docs it's not clear what else should be done.
I have no other XML files (config files) in my app.
Am I missing something ?
The main issue I see is the <datasource> definition in server.xml, you have used the <properties.db2.jcc> element, which corresponds to the IBM DB2 JCC JDBC driver. Since Liberty does not have a dedicated <properties.h2> configuration, you must use the generic <properties> config element, as well as defining the DataSource class names on your <jdbcDriver> element.
The config should look something like this:
<dataSource id="h2test" jndiName="jdbc/h2test">
<!-- Define the DataSource class names on the <jdbcDriver> element -->
<jdbcDriver
javax.sql.XADataSource="org.h2.jdbcx.JdbcDataSource"
javax.sql.ConnectionPoolDataSource="org.h2.jdbcx.JdbcDataSource"
javax.sql.DataSource="org.h2.jdbcx.JdbcDataSource"
libraryRef="H2JDBCLib"/>
<!-- set the connection URL on the <properties> element.
this corresponds to the setURL() method on H2's JdbcDataSource class.
you may also list any properties here that have a corresponding setXXX method on H2's JdbcDataSource class -->
<properties URL="jdbc:h2:mem:testdb"/>
</dataSource>
Also, it would be better if you put your H2 JDBC driver somewhere under ${server.config.dir} or ${shared.resource.dir}, since ${wlp.install.dir}/lib is where jars of the Liberty runtime are. You don't want to mix your application jars in with those!
<library id="H2JDBCLib">
<fileset dir="${server.config.dir}" includes="h2-1.4.197.jar"/>
</library>
Lastly, ensure that your persistence.xml file is in the correct location in your WAR application. It should be at WEB-INF/classes/META-INF/persistence.xml
As an intermediate debugging step, you can check to make sure the DataSource is resolvable from your application like this:
#Resource(lookup = "jdbc/h2test")
DataSource ds;
// ...
ds.getConnection().close();
Once you get that part working, move onto injecting your EntityManager. Also, be sure to check ${server.config.dir}/logs/messages.log for more detailed error messages if things are going wrong.
Related
I get in inheritance EAR application which I need to continue to develop. The problem that I can't cause it work on Websphere Liberty 16.0.0.4 while on Websphere Application Server Full Profile 8.5 it works fine. Unfortunately or (fortunately :) ) my working station is Macbook Pro, and WAS Full Profile can't be installed on OSX (can't find links right now, but have done some search and find enough evidences for it) so I need to use VirtualBox with Linux or try to run this app on Liberty.
The latest solution doesn't work so well for me, I get the following error:
[ERROR ] CWWJP0012E: The persistence unit name is not specified and
a unique persistence unit is not found in the BigEnterpriseAppEAR
application and BigEnterpriseAppEJB.jar module. [ERROR ] CWWJP0029E:
The server cannot find the persistence unit in the
BigEnterpriseAppEJB.jar module and the BigEnterpriseAppEAR
application. [ERROR ] CWNEN0035E: The java:comp/env/BigEnterpriseApp
reference of type javax.persistence.EntityManager for the DataProvider
component in the BigEnterpriseAppEJB.jar module of the
BigEnterpriseAppEAR application cannot be resolved. [ERROR ]
CNTR0020E: EJB threw an unexpected (non-declared) exception during
invocation of method "getDataByOwner" on bean
"BeanId(BigEnterpriseAppEAR#BigEnterpriseAppWEB.war#DataAPI, null)".
Exception data: javax.ejb.EJBTransactionRolledbackException: nested
exception is: javax.ejb.EJBException: The
java:comp/env/BigEnterpriseApp reference of type
javax.persistence.EntityManager for the DataProvider component in the
BigEnterpriseAppEJB.jar module of the BigEnterpriseAppEAR application
cannot be resolved.
The app is pretty simple EAR = JPA + EJB + WAR
I don't know which configuration files would be helpful, so just write in a comments what to post and I will do it.
Thank you in advance.
UPDATE 1:
server.xml file:
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>localConnector-1.0</feature>
<feature>servlet-3.1</feature>
<feature>ejbLite-3.1</feature>
<feature>jndi-1.0</feature>
<feature>jaxrs-1.1</feature>
<feature>ssl-1.0</feature>
<feature>jpa-2.0</feature>
<feature>cdi-1.0</feature>
</featureManager>
<basicRegistry id="basic" realm="BasicRealm">
<!-- <user name="yourUserName" password="" /> -->
</basicRegistry>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<applicationMonitor updateTrigger="mbean"/>
<library id="DB2JCC4Lib">
<fileset dir="/Users/anatoly/developer/sql_drivers" includes="*.jar"/>
</library>
<dataSource id="db2_slc" jndiName="jdbc/BEADB" type="javax.sql.DataSource">
<jdbcDriver libraryRef="DB2JCC4Lib"/>
<properties.db2.jcc databaseName="beadb" password="********" portNumber="50000" serverName="db2server" user="db2username"/>
</dataSource>
<keyStore id="defaultKeyStore" password="******"/>
<enterpriseApplication id="BigEnterpriseAppEAR" location="BigEnterpriseAppEAR.ear" name="BigEnterpriseAppEAR"/>
</server>
persistence.xml file, located in BigEnterpriseAppJPA > src > META-INF > persistence.xml
in packaged EAR persistence.xml located in BigEnterpriseAppEAR -> BigEnterpriseAppJPA.jar -> META-INF -> 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="BigEnterpriseApp">
<jta-data-source>jdbc/BEADB</jta-data-source>
<class>com.bea.entities.System</class>
<class>com.bea.entities.Data</class>
<class>com.bea.entities.User</class>
<class>com.bea.entities.Group</class>
<properties>
<property name="openjpa.jdbc.Schema" value="BEADB" />
<property name="openjpa.ConnectionRetainMode" value="transaction" />
</properties>
</persistence-unit>
</persistence>
[ERROR ] CWWJP0012E: The persistence unit name is not specified and a unique persistence unit is not found in the BigEnterpriseAppEAR application and BigEnterpriseAppEJB.jar module.
This would imply your persistence.xml roots are not at the legal locations defined by the JPA spec, section 8.2:
In Java EE environments, the root of a persistence unit must be one of the following:
an EJB-JAR file
the WEB-INF/classes directory of a WAR file[87]
a jar file in the WEB-INF/lib directory of a WAR file
a jar file in the EAR library directory
an application client jar file
NOTE: Java Persistence 1.0 supported use of a jar file in the root of the EAR as the root of a
persistence unit. This use is no longer supported. Portable applications should use the EAR
library directory for this case instead
Your setup seems to be trying to use #4?
BigEnterpriseAppEAR -> BigEnterpriseAppJPA.jar -> META-INF -> persistence.xml
BigEnterpriseAppJPA.jar should be placed inside your EAR library directory. I believe this will be BigEnterpriseAppEAR/lib by default, but you can configure this with your /META-INF/application.xml in the EAR
Also note, that the persistence-unit name must be unique. Make sure that all persistence-unit names are not using the same name.
Lately, I have been trying to use Hibernate as O-R-Mapper for a project based on Eclipse bundles.
Because of the unique class-loading of Eclipse-bundles, many people advise using Eclipselink instead of Hibernate.
Having tried Eclipselink and being not quite satisfied with it, I do want to know:
Isn't there a way to get Hibernate up and running in my Eclipse Plug-In Project?
Here is a small walk-through of how I got it to work. Please feel free to ask questions and post suggestions on how to improve this:
Download Hibernate 4.2.5 or newer, which comes with OSGi-Support (see Hibernate OSGi Documentation). However, the examples there use Apache Felix as OSGi-implementation and not equinox.
Create a new Plug-In Project from existing jar-archives.
In my case, I added the following jars:
hibernate-core-4.2.5
hibernate-osgi-4.2.5
hibernate-commons-annotations-4.0.2 (i am using annotations)
hibernate-jpa-2.0 (i am using the java persistence api for more flexibility)
hibernate-entitymanager-4.2.5 (also the more generic jpa entitymanager instead of hibernates session)
org.osgi.core-4.3.1 (for the osgi classes)
jboss-logging
jboss-transaction-api
dom4j-1.6.1
antlr-2.7.7
Open the MANIFEST.MF of the project and add the following:
Bundle-Activator: org.hibernate.osgi.HibernateBundleActivator (this is hibernate's bundle activator from the hibernate-osgi bundle)
Bundle-ActivationPolicy: lazy (so that osgi passes the context to the bundle once it is activated)
Eclipse-BuddyPolicy: registered (we need this later to make our entity classes known to hibernate and vice versa)
Also make sure all your jars are on the Bundle-Classpath and all packages of the plug-in are exported.
Now, create a new plug-in project for your hibernate configuration and DAO.
Put your persistence configuration file (persistence.xml or hibernate.cfg.xml) in the META-INF folder at the root of your plugin. Here is an example for the persistence.xml:
<persistence 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 persistence_2_1.xsd"
version="1.0">
<persistence-unit name="TheNameOfMyPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<description>My Persistence Unit</description>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>de.eicher.jonas.SomeClass</class>
<class>de.eicher.jonas.AnotherClass</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.connection.url" value="jdbc:derby:C:/Temp/data;create=true"/>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="org.hibernate.FlushMode" value="commit" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.current_session_context_class" value="thread"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Add org.eclipse.core.runtime to your dependencies and create an Activator to get static access to the BundleContext:
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
public class HibernateJpaActivator extends Plugin {
private static BundleContext context;
#Override
public void start(BundleContext context)
throws Exception {
HibernateJpaActivator.context = context;
}
public static BundleContext getContext() {
return context;
}
}
In your DAO or Util class, use the following code to get the EntityManagerFactory or EntityManager:
BundleContext context = HibernateJpaActivator.getContext();
ServiceReference serviceReference = context.getServiceReference( PersistenceProvider.class.getName() );
PersistenceProvider persistenceProvider = (PersistenceProvider) context.getService( serviceReference );
emf = persistenceProvider.createEntityManagerFactory( "TheNameOfMyPersistenceUnit", null );
EntityManager em = emf.createEntityManager();
Only a few more things to do, before it works:
Open the MANIFEST.MF and make sure that your bundle receives the BundleContext on activation.
Bundle-ActivationPolicy: lazy
Bundle-Activator: my.package.name.HibernateJpaActivator
Open the plug-in containing your entities and add a dependecy to the plugin with your hibernate jars (the first one we created).
Now we also need the entities to be known in the plugin with the hibernate jars. We can't add a dependency there, because this would produce a cyclic dependency. Fortunately, Eclipse provides us with a workaround:
Open the MANIFEST.MF of your entity-bundle and register your hibernate-jar plugin as a buddy:
Eclipse-RegisterBuddy: org.hibernate4.osgi (the name of your hibernate plugin, the one where you set Eclipse-Buddy-Policy: registered)
Now Hibernate knows our classes and our classes know Hibernate. We also made sure, that Hibernate finds our persistence.xml (or hibernate.cfg.xml) and creates our readily configured EntityMangerFactory (or Session).
I have been searching for an answer during quite a long time before coming here and ask this question.
My problem is very simple : I cannot run any JUnit test when using the JPA Entity Manager API. It seems that my test is not reading the persistence.xml file.
When I call new Configuration().configure().buildSessionFactory(), it works like a charm but an exception is thrown when calling Persistence.createEntityManagerFactory("myapp") is:
javax.persistence.PersistenceException: No Persistence provider for
EntityManager named myapp at
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:69)
at
javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
at com.myapp.Test01.setUpBeforeClass(Test01.java:22)
My JavaSE project has the following structure :
myapp
++src/main/java
++com.myapp.model
++// My entity classes are here
++src/test/java
++com.myapp
++Test01.java
++src/main/resources
++hibernate.cfg.xml
++META-INF
++persistence.xml
and persistence.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="2.0">
<persistence-unit name="myapp" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"></property>
</properties>
</persistence-unit>
</persistence>
Do you have any idea how to solve this issue ?
Thank you very much for your help.
Put the configuration in src/test/resources/META-INF.
My guess would be that org.hibernate.ejb.HibernatePersistence is not on your classpath. That's not in the main Hibernate jar, it's in the hibernate-entitymanager or some such jar.
A couple of quick experiments would be to do, in the code immediately before the call to Persistence.createEntityManagerFactory():
System.out.println(getClass().getResource("META-INF/persistence.xml"));
And:
System.out.println(Class.forName("org.hibernate.ejb.HibernatePersistence"));
It would also be wise to check that Eclipse is copying your resources; do a Project > Clean and then look in your Eclipse build output directory to see if persistence.xml is where you expect. I have sometimes run into cases where Eclipse doesn't copy resources for some reason or other.
I am trying to develop a web application. I started creating a Play! Framework project in Eclipse.
For the model part I chose to use JPA and since I had already created the database I was searching a way auto-generate the model classes.
I converted it to faceted form and used Dali to create the mapping with the database. During the configuration I was promted to chose a JPA implementation so I chose EclipseLink 2.1.3 Helios as a user library.
All the jars where added in my project.
After searching for similar errors, I modified the persistence.xml to:
<?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="StudentApplication">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>models.Grade</class>
<class>models.GradePK</class>
<class>models.Student</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/studentapplication"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
</properties>
</persistence-unit>
</persistence>
The exact error I am getting now is:
Execution exception (In /app/controllers/class.java around line 98)
PersistenceException occured : No Persistence provider for EntityManager named jpa
I have to note that in application.conf I have declared the db connection and when I run the application I get
22:03:53,084 INFO ~ Connected to jdbc:mysql://localhost/studentapplication?useUnicode=yes&characterEncoding=UTF-8&connectionCollation=utf8_general_ci
Finally the file structure is:
-controllers
-models
-views
-META-INF
|_persistense.xml
As you may have understood (besides my rep) I am a newbie in web application development and specifically in JPA. I would be more than grateful to any kind of help. I apologize in advance if I posted not-needed information or if I missed mandatory information. Thank you for your time.
Thomas
It seems that you are referencing the persistence unit in your application by a different name than in your persistence.xml. Your persistence unit is named "StudentApplication" in persistence.xml. However, the error states that it is named "jpa" in your application.
Assuming that you are using application managed entity manager, there must be a line like this in your app:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa");
Change it to
EntityManagerFactory emf = Persistence.createEntityManagerFactory("StudentApplication");
7.2 with ejbql connection my problem is that when i test the connection, fails because Could not find datasource, in the log says:
Caused by: org.hibernate.HibernateException: Could not find datasource
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
I guees can be the jndi.properties that in the wrong directory, i tried put into java_home/lib but doesn't work
Finally after a lot of work i made the ejbql connection with ireport. Follow this steps to do it!!
1) i'm using jboss 4.2.3, so if you using glashfish or other server, find the libraries that match with the jboss that i'm using
2) You need to find in your jboss directory server/default/lib the follow libraries:
hibernate3.jar
hibernate-entitymanager.jar
jboss-common.jar
hibernate-annotations.jar
ejb3-persistence.jar
jboss.jar
3) copy the libraries previously named and copy your ireport installation directory in this path \Jaspersoft\iReport-3.7.2\ireport\modules\ext and replace it, note that the library call hibernate-common-annotation and jpa.jar need to be erase from that path. You need to do it because this library creates conflicts with hibernate-annotations and ejb3-persistence.jar.
4) get the jar of your project and copy it in your in this example let's called example-core.jar to the installation directory in the path \Jaspersoft\iReport-3.7.2\ireport\libs
5) modify the jar the persistence.xml of your project (in our case "example.jar") and sets with this next properties,
<?xml version="1.0" encoding="UTF-8"?>
<persistence
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_1_0.xsd"
version="1.0">
<persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>/jdbc/example</non-jta-data-source>
<properties>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect"/>
</properties>
</persistence-unit>
</persistence>
6)Go to ireport and add the libraries to the classpath, in tools, options in the tab of classpath
7) go to the installation directory of ireport in the path Jaspersoft\iReport3.7.2\ireport\modules open the jar called com-jaspersoft-ireport with winrar or other tool , and go to META-INF/MANIFEST.INF in the part of Class-Path modify the name of the library "hibernate-common-annotation.jar" (renember you erase this library) for the "hibernate-annotations.jar"
8)Go to Jboss_home/server/default/deploy and modify the datasource xml of your project and put this configuration, (renember in this example the project is call "example" and the datasource should be called example-ds.xml)
<datasources>
<local-tx-datasource>
<jndi-name>jdbc/example</jndi-name>
<use-java-context>false</use-java-context>
<connection-url>jdbc:oracle:thin:#localhost:1521:XE</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>example</user-name>
<password>example</password>
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
Note that the property usa-java-context in false is that allow you to access to the data source outside of the jboss in our case from ireport
9)go to the ireport and add the follow libraries into the ireport classpath
jnp-client.jar
jboss-client.jar
jbossall-client.jar
the database driver in my case ojdbc.jar (for oracle)
jboss-ejb3x.jar
10) sets your jndi.properties and put it into the jar hibernate-entitymanager.jar
11) Now run the jboss, go to ireport and create the ejql connection, in the persistence unit name sets the name that place in the persistence.xml of the jar located in installation directory Jaspersoft\iReport-3.7.2\ireport\libs, in this case the persistence unit name is "example" without the quotes marks
I hope that this help to somebody or someone jeje, i know that's pretty hard, and sorry for my english its not my first language