I'm trying to instantiate an EntityManager using a JTA Datasource, but I always get NullPointerException.
Here's my environment:
Server : JBossAS 7.0
JPA : 2.0
DB : MySQL
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="WebStock" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>stockmanagementDS</jta-data-source>
<class>prv.stockmanagement.business.Product</class>
</persistence-unit>
</persistence>
On a dao class I'm trying this :
#PersistenceContext(type=PersistenceContextType.EXTENDED, unitName="WebStock")
private EntityManager em;
but when I use its getter, I get NullPointerException here :
public EntityManager getEntityManager() {
return em;
}
the debug shows it's null.
Here's the datasource definition in the standalone.xml :
<datasource jndi-name="stockmanagementDS" pool-name="stockmanagement" enabled="true" jta="true" use-java-context="true" use-ccm="true">
<connection-url>
jdbc:mysql://localhost:3306/kitchen_stock
</connection-url>
<driver>
mysql
</driver>
<security>
<user-name>
root
</user-name>
<password>
rootroot
</password>
</security>
<statement>
<prepared-statement-cache-size>
100
</prepared-statement-cache-size>
<share-prepared-statements/>
</statement>
</datasource>
"mysql" is the name of the driver I defined after the datasource :
<drivers>
<driver name="mysql" module="com.sql.mysql">
<driver-class>
com.mysql.jdbc.Driver
</driver-class>
</driver>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>
org.h2.jdbcx.JdbcDataSource
</xa-datasource-class>
</driver>
</drivers>
Persistence is under META-INF, it's dynamic web project, and it's working well. The classing using the entity manager is not an EJB.
Any hint?
Let me draw your attention to the following moments:
1. I don't see in your code driver for MySql to which you refer from datasource:
<driver>
mysql
</driver>
You mast do follow:
Enter in the file path ${jboss_home}/modules and create the directories com/mysql/jdbc/main. Into the folder main copy the driver library jar (for example mysql-connector-java-5.1.38-bin.jar) and create a file module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="com.mysql.jdbc">
<resources>
<resource-root path="mysql-connector-java-5.1.38-bin.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
And to the <drivers> tag in the standalone.xml add:
<driver name="mysql" module="com.mysql.jdbc">
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>
2. May be you should put your persistence.xml in your web module:
web
src
main
java
..
resources
META-INF
persistence.xml
webapp
..
3. You can do inject EntiryManeger only into EJB or class with #Transactional annotation. Check to be sure your DAO class it is EJB bean.
Related
Here's my persistence xml file
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="GoodreadsJpa">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>entity.Book</class>
<class>entity.Review</class>
<class>entity.UserActionLog</class>
<class>entity.User</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/goodreads_clone?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC;" />
<property name="eclipselink.jdbc" value="jdbc:mysql://localhost:3306/goodreads_clone?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC;"/>
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
</properties>
</persistence-unit>
As you can see I have provided jdbc url for connecting to the database. However, when I run my application I get the following information.
14:31:57,377 INFO [org.eclipse.persistence.connection] (default task-2) Connected: jdbc:h2:mem:test
User: ROOT
Database: H2 Version: 1.3.173 (2013-07-28)
Driver: H2 JDBC Driver Version: 1.3.173 (2013-07-28)
which states that I connected to jdbc:h2:mem:test and consequently I cannot perform the desired actions.
It makes me think I am connected to a wrong database?Am I missing something? How can I actually connect to the db that I want?
I am using Wildfly 10 and EclipseLink. Not using Maven.
Assuming you're using container-managed em, you should define your data source in Wildfly configuration (standalone.xml). You should then refer to your datasource using the persistence-unit.jta-data-source (or persistence-unit.non-jta-data-source) tag in your persistence unit definition.
If you need both the MySQL and H2 data sources, you can create multiple persistence units and differentiate between them using #PersistenceContext(name = "...")
1.You need to add mysql driver to Jboss like here : Can't add mysql driver to jboss
or here
https://synaptiklabs.com/posts/adding-the-mysql-jdbc-driver-into-wildfly/
You need add mysql datasource in standalone.xml configuration file like here :
https://zorq.net/b/2011/07/12/adding-a-mysql-datasource-to-jboss-as-7/
<datasource jndi-name="java:/mydb" pool-name="my_pool" enabled="true" jta="true" use-java-context="true" use-ccm="true">
<connection-url>jdbc:mysql://localhost:3306/mydb</connection-url>
<driver>mysql</driver>
<security>
<user-name>root</user-name>
<password>root</password>
</security>
<statement>
<prepared-statement-cache-size>100</prepared-statement-cache-size>
<share-prepared-statements />
</statement>
</datasource>
I am trying to add datasource for IBM DB2 database and it is showing below error
ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 2) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("data-source" => "DB2DS1")
]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => ["jboss.jdbc-driver.db2"],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"org.wildfly.data-source.DB2DS1 is missing [jboss.jdbc-driver.db2]",
"jboss.driver-demander.java:/DB2DS1 is missing [jboss.jdbc-driver.db2]"
]
}
I have below configuration in module.xml which is placed along with database driver in EAP-7.1.0\modules\system\layers\base\com\ibm\db2\main location
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.5" name="com.ibm.db2">
<properties>
<property name="jboss.api" value="unsupported"/>
</properties>
<resources>
<resource-root path="db2jcc.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true"/>
</dependencies>
Also I think I have successfully installed driver as module because I am seeing it's entry in standalone.xml like
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="db2" module="com.ibm.db2">
<datasource-class>com.ibm.db2.jcc.DB2Driver</datasource-class>
</driver>
</drivers>
What thing I am missing here ?.
To add datasource I am hitting below command from CLI
data-source add --name=DB2DS1--jndi-name=java:/DB2DS1--driver-name=db2 --connection-url=jdbc:db2://localhost:50000/sample
It was a silly mistake I did...
Below is the correct configuration that should be there in standalone.xml
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
<driver name="db2" module="com.ibm.db2">
<driver-class>com.ibm.db2.jcc.DB2Driver</driver-class>
</driver>
</drivers>
For simplicity I have followed below steps to add db2 datasource
Created module.xml as mentioned in above question
Added database driver for datasource
/subsystem=datasources/jdbc-driver=ibmdb2:add(driver-name=ibmdb2,driver-module-name=com.ibm.db2,driver-class-name=com.ibm.db2.jcc.DB2Driver)
Added datasource to subsystem
data-source add --name=DB2_EFTDEVS1 --driver-name=ibmdb2 --driver-class=com.ibm.db2.jcc.DB2Driver --user-name=Administrator --password=Test#123 --connection-url=jdbc:db2://localhost:50000/sample --jndi-name="java:jboss/datasources/DB2_EFTDEVS1"
I am trying to get a Java8EE application working on Wildfly10 and Postgres 9.6.6.
Somehow I allways bump into the error that the relation cannot be found.
My Postgres is running on localhost, default port. I am connecting with the user postgres and the correct password. The database (hbnac) has a schema with the same name.
Wildfly is configured to use the database and the “Test connection” is confirming a successful connection.
Using pgAdmin 4 I can also browse the database, see the schema, as well as the table group_member.
The config in Jboss looks as follow:
<datasource jta="false" jndi-name="java:jboss/datasources/hbnac" pool-name="hbnac" enabled="true" use-ccm="false">
<connection-url>jdbc:postgresql://localhost:5432/hbnac</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgres</driver>
<pool>
<min-pool-size>1</min-pool-size>
<initial-pool-size>1</initial-pool-size>
<max-pool-size>10</max-pool-size>
<flush-strategy>Gracefully</flush-strategy>
</pool>
<security>
<user-name>postgres</user-name>
<password>password</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"/>
<background-validation>true</background-validation>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"/>
</validation>
</datasource>
However, my application fails to select a record from the very same table, resulting in the following error:
Caused by: org.postgresql.util.PSQLException: ERROR: relation "group_member" does not exist
The configuration of my persistence.xml is doing a jndi lookup of the connection defined in Wildfly:
<persistence-unit name="hbnac">
<jta-data-source>java:jboss/datasources/hbnac</jta-data-source>
<class>hbnac.birthday.domain.groupmember.GroupMember</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL94Dialect" />
<!--property name="hibernate.hbm2ddl.auto" value="validate"/-->
<!--property name="hibernate.default_schema" value="hbnac"/-->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
And obviously, the jta-data-source is matching the working datasource in Wildfly. As you can see, I have experimented a bit with the validate (which fails for the same reason at startup) and with the schema name, which also does not make a difference.
The entity itsel is annoted:
#Entity
#Table(name = "group_member")
public class GroupMember extends AbstractEntity {
public final static String FACEBOOK_NAME_FIELD = "facebookName";
public final static String BIRTHDAY_FIELD = "birthday";
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
It has getters, setters, hashcode and equals methode for all fields available.
If I copy the query generated by hibernate into pgadmin it also works perfectly...
Any ideas left?
success to test connection, but even couldn't find table
that indicates ,perhaps schema setting is not defined correctly.
then, should put a currentSchema like this
<connection-url>jdbc:postgresql://localhost:5432/hbnac?currentSchema=hbnac</connection-url>
and if you use Hibernate to issue query should enable this comment outed code
<!--property name="hibernate.default_schema" value="hbnac"/-->
I found the error after many tries! It was caused by the configuration of the Postgres module in Wildfly itself.
What I had before:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">
<resources>
<resource-root path="postgresql-42.1.4.jar" />
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true" />
</dependencies>
and in the standalone.xml:
<driver name="postgres" module="org.postgres">
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
<datasource-class>org.postgresql.ds.PGSimpleDataSource</datasource-class>
</driver>
for the datasource itself:
<datasource jta="false" jndi-name="java:jboss/datasources/hbnac" pool-name="hbnac" enabled="true" use-ccm="false">
<connection-url>jdbc:postgresql://localhost:5432/hbnac</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgres</driver>
...
This configuration gave a successful connection but the error that a relation could not be found.
By replacing it with the following configuration, everything is working fine:
For the module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.postgres">
<resources>
<resource-root path="postgresql-42.1.4.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="javax.servlet.api" optional="true"/>
</dependencies>
For the driver in the standalone.xml:
<driver name="postgresql" module="org.postgres">
<driver-class>org.postgresql.Driver</driver-class>
</driver>
And finally for the db connection:
<datasource jta="true" jndi-name="java:/PostgresDS" pool-name="PostgresDS" enabled="true" use-java-context="true">
<connection-url>jdbc:postgresql://localhost:5432/hbnac</connection-url>
<driver>postgresql</driver>
<security>
...
I've got a JPA unit that fails to create the database schema in Wildfly10 when the data-source is marked with jta=true. Any idea how could I work around this problem?
The stack trace:
javax.persistence.PersistenceException: Could not set provided connection [org.jboss.jca.adapters.jdbc.jdk7.WrappedConnectionJDK7#12f9ae77] to auto-commit mode (needed for schema generation)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$ConnectionProviderJdbcConnectionAccess.<init>(JpaSchemaGenerator.java:644)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$ConnectionProviderJdbcConnectionAccess.<init>(JpaSchemaGenerator.java:620)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.determineAppropriateJdbcConnectionContext(JpaSchemaGenerator.java:402)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.access$100(JpaSchemaGenerator.java:55)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$GenerationProcess.execute(JpaSchemaGenerator.java:113)
at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.performGeneration(JpaSchemaGenerator.java:65)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:885)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
..
Wildfly data source:
<datasource jta="true" jndi-name="java:/xxx" pool-name="xxx" enabled="true" use-ccm="true">
<connection-url>jdbc:mariadb:failover://xxx/xxx</connection-url>
<driver-class>org.mariadb.jdbc.Driver</driver-class>
<driver>mariadb-java-client-1.5.8.jar</driver>
..
</datasource>
Persistence XML:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="xxx" transaction-type="JTA">
<jta-data-source>java:/xxx</jta-data-source>
<class>xxx</class>
<properties>
<property name="javax.persistence.schema-generation.database.action" value="create" />
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
</properties>
</persistence-unit>
</persistence>
I'm having some issues getting a JNDI lookup of a datasource in JBoss 7.0.2 to work properly. Basically, this application is one that should be deployable across multiple application servers, so I'd like to adhere to appropriate standards. The application in question is a simple portlet application deployed in Liferay 6.1 running in a Jboss managed domain; I've tried various combinations of naming conventions in web.xml, jboss-web.xml, and persistence.xml; all to no avail. My current configuration looks like this:
Spring persistence.xml:
<jee:jndi-lookup id="surveyDS" jndi-name="jdbc/surveyDS" resource-ref="true" />
web.xml:
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd" id="WebApp_ID" version="2.4">
...
<resource-ref>
<res-ref-name>jdbc/surveyDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
jboss-web.xml:
<?xml version="1.0"?>
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.4//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd">
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/surveyDS</res-ref-name>
<jndi-name>java:jboss/datasources/surveyDS</jndi-name>
</resource-ref>
</jboss-web>
Datasource definition in ${JBOSS_HOME}/domain/configuration/domain.xml:
<datasource jndi-name="java:jboss/datasources/surveyDS" pool-name="TestDSPool" enabled="true" jta="true" use-java-context="true" use-ccm="true">
<connection-url>****</connection-url>
<driver>com.mysql</driver>
<pool>
<prefill>false</prefill>
<use-strict-min>false</use-strict-min>
<flush-strategy>FailingConnectionOnly</flush-strategy>
</pool>
<security>
<user-name>****</user-name>
<password>****</password>
</security>
</datasource>
Deploying the portlet application works just fine; however, when I attempt to actually view the portlet, I get the following exception:
15:10:05,493 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/survey-portlets].[surveydisplay Servlet]] (ajp--0.0.0.0-8009-3) Servlet.service() for servlet surveydisplay Servlet threw exception: javax.naming.NameNotFoundException: jdbc/surveyDS -- service jboss.naming.context.java.jdbc.surveyDS
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:87)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:173)
at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:47)
at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:209)
at javax.naming.InitialContext.lookup(InitialContext.java:392) [:1.6.0_26]
at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:104) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:201) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:187) [org.springframework.context-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) [org.springframework.beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) [org.springframework.beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) [org.springframework.beans-3.0.5.RELEASE.jar:]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [org.springframework.beans-3.0.5.RELEASE.jar:]
[ ... stack truncated for brevity ]
I feel like I must be missing something very simple and obvious at this point, but I have no idea what it might be. Any suggestions would be greatly appreciated!
Change the DataSource jndi-name in the JBoss domain.xml file to java:jdbc/surveyDS, and you should be fine.