I am trying to integrate HikariCP with PostgreSQL in my web application,I am using the postgresql driver and this DataSource class: org.postgresql.ds.PGSimpleDataSource and my hibernate configuration file is this:
<property name ="hibernate.connection.provider_class"> com.zaxxer.hikari.hibernate.HikariConnectionProvider</property>
<property name ="hibernate.hikari.dataSourceClassName"> org.postgresql.ds.PGSimpleDataSource</property>
<property name ="hibernate.hikari.dataSource.url">jdbc:postgresql:// localhost:5432/database</property>
<property name ="hibernate.hikari.dataSource.user">user</property>
<property name ="hibernate.hikari.dataSource.password">passwd</property>
<property name ="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
When I run my application i have this exception:
org.hibernate.HibernateException: java.lang.RuntimeException: Property url does not exist on target class org.postgresql.ds.PGSimpleDataSource`
I read related information about this and what I did was replace the versions using the postgresql-9.4.1208 driver and hikaricp 2.4.6.
Related
I have an SpringBoot application with integrationtests utilising an H2 inmemory database. The tests work, if I use SpringBoot in versino 2.3.4.RELEASE. They fail if I upgrade to 2.4.0 with the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is java.lang.RuntimeException: Driver com.microsoft.sqlserver.jdbc.SQLServerDriver claims to not accept jdbcUrl, jdbc:h2:mem:integrationTestDB;DB_CLOSE_DELAY=-1;MODE=MSSQLServer;INIT=CREATE SCHEMA IF NOT EXISTS dbo\;SET SCHEMA dbo
Caused by: java.lang.RuntimeException: Driver com.microsoft.sqlserver.jdbc.SQLServerDriver claims to not accept jdbcUrl, jdbc:h2:mem:integrationTestDB;DB_CLOSE_DELAY=-1;MODE=MSSQLServer;INIT=CREATE SCHEMA IF NOT EXISTS dbo\;SET SCHEMA dbo
Here is my integration-test.properties, that is used by the tests:
spring.datasource.url=jdbc:h2:mem:integrationTestDB;\
DB_CLOSE_DELAY=-1;\
MODE=MSSQLServer;\
INIT=CREATE SCHEMA IF NOT EXISTS dbo\\;SET SCHEMA dbo
spring.datasource.driver=org.h2.Driver
spring.datasource.hikari.driver-class-name=org.h2.Driver
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.hbm2ddl.auto=none
spring.datasource.username=sa
spring.datasource.password=
spring.liquibase.user=sa
spring.liquibase.password=
The version of H2 is 1.4.200.
The difference between success and failure is the SpringBoot version in the parent element of the pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
</parent>
The liquibase version changed from 3.8.9 to 3.10.3. I configured it to stay at 3.8.9 but that didn't help.
I read the release notes and found the part about the embedded database detection: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.4-Release-Notes#embedded-database-detection
But adding
spring.datasource.initialization-mode=always
to the properties didn't help either.
I remember that it took some time to find the right datasource url last time, but I can't find any new clues with google.
Can you give me a hint, what causes this problem?
Kind regards,
Ulrich
Your properties contain a mixture of H2 and SQL Server configuration. For example, you've configured an H2 JDBC URL for the DataSource but configured Hibernate to use SQLServerDialect. The exception shows that SQL Server's JDBC driver is being used when trying to initialise Liquibase. It looks to me like you're trying to use H2 in your integration tests, replacing SQL Server that's used when your app's deployed.
There's a new spring.liquibase.driver-class-name property in 2.4.0. When not set, it falls back to using spring.datasource.driver-class-name. There's no spring.datasource.driver property so try replacing the following two lines:
spring.datasource.driver=org.h2.Driver
spring.datasource.hikari.driver-class-name=org.h2.Driver
with the following line:
spring.datasource.driver-class-name=org.h2.Driver
i want to deploy my application in AWS.
i have setup my env.
and in root-context.xml of my application i have setup data source.
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#mydbinstance.cnn31xputfwg.ap-northeast-2.rds.amazonaws.com:1521:orcl" />
<property name="username" value="myid" />
<property name="password" value="mypassword" />
</bean>
this setting works fine locally in tomcat server.
but in AWS, it throws this error message
nested exception is org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is
java.sql.SQLException: Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'
The error may exist in file [/var/lib/tomcat8/webapps/ROOT/WEB-INF/classes/mappers/emp/emp-mapper.xml]
The error may involve EmpDAO.List ### The error occurred while executing a query
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is
java.sql.SQLException: Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'
Now my question is: what should i do to use get jdbc connection in AWS?
Looks like when you run the app on AWS it lacks Oracle JDBC driver in its CLASSPATH. So the answer is to add the driver to the classpath.
And I foresee the next question: "how to do this?", and simplest way is just to copy the driver to your classpath manually.
If you don't like manual work, you can generate Spring application template using Spring Initializr. Its build script has org.springframework.boot plugin, which does two important things:
builds single jar file which includes Tomcat, so the application can be started just by java -jar my-app.jar (avoiding deployment to tomcat)
includes all dependencies from build-script dependencies section to this jar file (including Oracle JDBC driver)
I have a spring mvc application which i am deploying on IBM WebSphere Application Server Liberty Profile, the application is supposed to access a mysql database server that is hosted locally. I have added the datasource configuration as follows in the sever.xml file
<dataSource id="springdb" jndiName="jdbc/springdb">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.Driver" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
I am getting the following stack trace
Caused by: java.lang.RuntimeException: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.resource.internal.ResourceFactoryTrackerData$1.getService(ResourceFactoryTrackerData.java:123)
... 77 more
Caused by: java.sql.SQLNonTransientException: DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[springdb]/jdbcDriver[default-0] using the library mysqlJDBCLib. [/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql/mysql-connector-java-6.0.6.jar]
at com.ibm.ws.jdbc.internal.JDBCDriverService.classNotFound(JDBCDriverService.java:196)
... 77 more
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
at com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:499)
... 77 more
I have tried the following
Replacing com.mysql.cj.jdbc.Driver with com.mysql.jdbc.Driver and string got the same error
Replacing javax.sql.XADataSource with javax.sql.DataSource and still got the same error
Replacing javax.sql.XADataSource with javax.sql.MysqlConnectionPoolDataSource, same error
Switching out the mysql connector jar from mysql-connector-java-6.0.6.jar to mysql-connector-java-5.1.45-bin.jar, still same error (both the jars are there in the specified file path)
Background info about datasource config:
For all datasources (except for id="DefaultDataSource") the type of DataSource is selected in the following priority:
Use the type class configured on the <dataSource> element, if configured
javax.sql.ConnectionPoolDataSource This option is active in your case
javax.sql.DataSource
javax.sql.XADataSource
(According to Configuring relational database connectivity in Liberty)
If no class is defined for a type, then the next lowest priority will be checked.
By default, Liberty will scan for use the following priority for locating data source implementation class names:
Use the corresponding value configured on the <jdbcDriver> element
Use the default classes for a <properties.DRIVER_TYPE> element. Note that only some JDBC drivers have their own element types. For JDBC drivers that do not have their own properties element (such as MySQL) use the generic <properties> element
Based on the JDBC driver jar name, Liberty will try to guess the implementation class name. This option is active in your case
Reason why your configuration is not working
You've configured your <jdbcDriver> element to say "Use this specific class for XADataSource's", however, the <dataSource> element you've configured is not attempting to create an XADataSource. Using the priority order mentioned above, it will first try to create a ConnectionPoolDataSource (which Liberty has internally mapped to com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource.
To fix the problem:
Specify <dataSource .. type="javax.sql.XADataSource"> in your configuration so that Liberty will try to create an XADataSource instead of a ConnectionPoolDataSource. Then when it tries to create the XADataSource it will look at the class name you've configured on the <jdbcDriver> element.
Specify MySQL's XADataSource class name for the javax.sql.XADataSource property (which is com.mysql.cj.jdbc.MysqlXADataSource) instead of their java.sql.Driver implementation class name.
So your final configuration would look like this:
<dataSource id="springdb" jndiName="jdbc/springdb" type="javax.sql.XADataSource">
<jdbcDriver javax.sql.XADataSource="com.mysql.cj.jdbc.MysqlXADataSource" libraryRef="mysqlJDBCLib"/>
<properties databaseName="spring_db" password="**********" portNumber="3306" serverName="localhost" user="root"/>
</dataSource>
<library id="mysqlJDBCLib">
<fileset dir="/opt/IBM/WebSphere/Liberty_16.0.0.4/usr/shared/resources/mysql" includes="mysql-connector-java-6.0.6.jar"/>
</library>
If you don't specify the type attribute in the dataSource config element, Liberty will try to infer the datasource class to load based on the driver jar filename. In your example, it is incorrectly inferring implementation class names based on a previous mySQL driver. It appears that mySQL has changed the package names of their implementations for DataSource, ConnectionPoolDataSource and XADataSource. I'll open an git issue for this. In the meantime, you can simply specify the type of datasource to create using the type attribute of the dataSource config element and then update your jdbcDriver config element with javax.sql.DataSource="com.mysql.cj.jdbc.MysqlDataSource" to point to the proper mysql driver class. If instead you need a conn pool or XA datasource instead, just update the type attribute of dataSource to identify the type and update jdbcDriver with the driver class impl.
I'm struggling to set connect a Java program to MySQL using JPA/Hibernate.
I'm currently getting the following error when I try to call createEntityManagerFactory():
[main] ERROR org.hibernate.connection.DatasourceConnectionProvider - Could not find datasource: java:jdbc/myDataDS
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
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
Googling seems to indicate that I need a jndi.properties file in META-INF in my classpath, but I can't seem to find any information about what that file should contain in my case.
Edit: I'm running this stand-alone, for the time being.
A jndi.properties file should be at the root of the classpath and typically contains the URL of the JNDI server and the initial context factory to use. For example, with JBoss:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
But, when using Hibernate, you should actually declare these properties in the hibernate.cfg.xml. For example, with WebLogic:
<property name="jndi.class">weblogic.jndi.WLInitialContextFactory</property>
<property name="jndi.url">t3://127.0.0.1:7001</property>
I am trying to bind connection to the DB using JNDI in my application that runs on JBoss. I did the following:
I created the datasource file oracle-ds.xml filled it with the relevant xml elements:
<datasources>
<local-tx-datasource>
<jndi-name>bilby</jndi-name>
...
</local-tx-datasource>
</datasources>
and put it in the folder \server\default\deploy
Added the relevant oracle jar file
than in my application I performed:
JndiObjectFactoryBean factory = new
JndiObjectFactoryBean();
factory.setJndiName("bilby");
try{
factory.afterPropertiesSet();
dataSource = factory.getObject();
}
catch(NamingException ne) {
ne.printStackTrace();
}
and this cause the error:
javax.naming.NameNotFoundException:
bilby not bound
then in the output after this error occured I saw the line:
18:37:56,560 INFO
[ConnectionFactoryBindingService]
Bound ConnectionManager 'jb
oss.jca:service=DataSourceBinding,name=bilby'
to JNDI name 'java:bilby'
So what is my configuration problem? I think that it may be that JBoss first loads and runs the .war file of my application and only then it loads the oracle-ds.xml that contain my data-source definition.
The problem is that they are both located in the same folder.
Is there a way to define priority of loading them, or maybe this is not the problem at all.
Any idea?
You should use such construction to call Datasource: java:bilby.
You can read more about that here:
Naming and Directory (JNDI) - JBOSS jndi Datasource: jdbc not bound
To check how the datasource is bound in the JNDI tree you should use the jmx-console
http://localhost8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss%3Aservice%3DJNDIView
and invoke the list() method.
Datasources are registered under "jdbc". In your case "jdbc/bilby"
EDIT: That was an example that works for me without spring.
Now found this example which injects a more complete JNDI name.
<bean id="idDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/bilby" />
</bean>