We need to make a connection to ms sql server from java persistence unit 1.0. I hace following code for oracle database.
<properties>
<property name="toplink.jdbc.url" value="jdbc:oracle:thin:#IP:PORT"/>
<property name="toplink.jdbc.user" value="####"/>
<property name="toplink.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="toplink.jdbc.password" value="####"/>
<property name="toplink.ddl-generation" value="create-tables"/>
<property name="toplink.jdbc.read-connections.max" value="1"/>
<property name="toplink.jdbc.read-connections.min" value="1"/>
<property name="toplink.jdbc.write-connections.max" value="1"/>
<property name="toplink.jdbc.write-connections.min" value="1"/>
<property name="toplink.logging.level" value="SEVERE" />
</properties>
I need the changes that I have to make in the previous code for making a connection to MS Sql Server.
Finally I got the solution.....
Steps to make connection to ms sql from JPA persistence.xml are:
Download the jar files from http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21599
I chose sql server 2005 so I used sqljdbc4 jar file from the above link.
Change driver name to com.microsoft.sqlserver.jdbc.SQLServerDriver in above given xml file.
Provide necessary username and password at corresponding position in xml file.
In connection url, write jdbc:sqlserver://localhost:port;databaseName=<Database>
Microsoft SQL Server connection can be done in few ways. To use windows authentication, you need to place a dll file in your System 32 directory. After that, you can replace the
connection URL, and user credentials as required. You may need to configure your SQL server
by SQL Server Surface Configuration Manager to allow remote connections and connections through TCP IP.
After that you may try to connect through a plain java class. And after that connect using a persistence unit (in EJB?).
When you download the SQL Server - JDBC Connector ZIP file, you can find a HTML Documentation,
which you must read (it will take 20 minutes). It was a 2 day struggle for me to connect to SQL Server from JDBC.
Related
The following exceptions when happened, this means there is something wrong on the environment especially if those exceptions happened only on production environment with big number of users without any problem in testing environment with normal number of users.
1. Could not open connection: org.hibernate.exception.GenericJDBCException: Could not open connection.
2. java.sql.SQLRecoverableException: Closed Connection.
3. java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
My environment information:
windows server 2012, oracle DB, jboss 7.1 application server and java application use hibernate 4 with c3p0 connection pools
I searched a lot about the related topics and I found many useful topics but the most useful topics was those two topics. topic_1 topic_2
I simulate this case when I decrease the configuration maxStatements inside c3p0 configuration file but as the definition for this parameter which defined here , it is the size of c3p0's global PreparedStatement cache.
I have the following questions:
Why I got error cannot open connection when I decrease maxStatements attributes which should effect only on the performance since this is cache attribute and this error disappears when I decrease it?
Why I got also cannot open connection when I increase maxStatements value with big number? How can I know the limitation from the database?
Is there any limitation from the database can limit this attributes and how can I check it?
I checked the connection pool maximum attributes with the database session parameter and I found that, the database session parameter is greater than the maximum pool size for my application which is right. I checked also the active and idle connections on the database and no problem in those numbers. Is there any other DB attributes should be checked instead of session parameter for database to be sure the database can give me the configured number of connection pools?
My c3p0-config is the following:
<default-config>
<property name="checkoutTimeout">300</property>
<property name="idleConnectionTestPeriod">70</property>
<property name="initialPoolSize">50</property>
<property name="maxIdleTime">270</property>
<property name="maxPoolSize">500</property>
<property name="minPoolSize">50</property>
<property name="maxStatements">400</property>
<property name="maxStatementsPerConnection">0</property>
<property name="testConnectionOnCheckout">true</property>
<property name="testConnectionOnCheckin">true</property>
<property name="preferredTestQuery">SELECT 1 from dual</property>
<property name="acquireRetryAttempts">0</property>
<property name="acquireRetryDelay">1000</property>
<property name="breakAfterAcquireFailure">false</property>
<property name="unreturnedConnectionTimeout">270</property>
<property name="debugUnreturnedConnectionStackTraces">true</property>
</default-config>
I'm developing a Java/Spring/Hibernate/CXF/MySQL SOAP webservice and corresponding web Spring MVC client on my laptop. The plan is to eventually move the two resulting war-files over to my remote server hosted at mybiz.com .
Both laptop and server have an instance of MySQL version 5.x.x
Both laptop and server have a root#localhost user (duh)
The server also has three other users:
zzdb_admin#%
zzdb_admin#localhost
zzdb_admin#mybiz.com
all with the same password remotepw and which have all had assorted privileges granted and flushed.
Both instances of MySQL have a database named zzdb.
Both instances of MySQL have ##session.old_passwords, ##global.old_passwords and ##global.secure_auth set to 0; In all cases hashes of passwords are 41 characters wide.
While logged in to the remote server directly I can manually log in to all accounts on both machines
mysql --user=root --password=remoterootpw
mysql --user=zzdb_admin --password=remotepw
mysql --host=localhost --user=zzdb_admin --password=remotepw
On the laptop I can log in to the local mysql with
mysql --user=root --password=localrootpw
mysql --host=mybiz.com --user=zzdb_admin --password=remotepw
So all users and passwords are correct. And their hashes are all 41 characters. Important: note this last proves that connection can be made with the instance on the remote machine.
The webservice' pom has version 5.1.8 of mysql-connector-java.
Now it gets weird. With these lines in the webservice' properties file:
hibernate.connection.url=jdbc:mysql://localhost:3306/zzdb
hibernate.connection.username=root
hibernate.connection.password=localrootpw
the webapp can connect to the local db instance and all is peachy. But changing only these three lines to
hibernate.connection.url=jdbc:mysql://mybiz.com:3306/zzdb
hibernate.connection.username=zzdb_admin
hibernate.connection.password=remotepw
throws the dreaded "Access denied for user 'zzdb_admin'#'localhost' " error
This has got me pulling out what few hairs I have left. Doesn't look like I'm missing anything and everything is spelled correctly. Anybody have an idea of what's going on?
TIA,
Still-learning Steve
Addendum: trying a different, simpler approach WORKED!
Class.forName("com.mysql.jdbc.Driver");
String connectionUrl = "jdbc:mysql://mybiz.com/zzdb?user=zzdb_admin&password=remoteapw";
Connection conn = DriverManager.getConnection(connectionUrl);
Now how about that? Only change is the method of connecting. Crazy
MySQL remote link have a bind address. You should comment it. You can refer this blog.
Solved the problem, and oh what a subtle bugger it was!
The applicationContext.xml at the base of the web service uses an Atomikos bean for a data source
<bean id="dataSourceServerA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="XADBMS_A" />
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties"> <!-- properties will be different for different data sources ie MySQL/HSDB/DB2 etc -->
<props>
<prop key="uri">$dbServerA{hibernate.connection.uri}</prop>
<prop key="user">$dbServerA{hibernate.connection.username}</prop>
<prop key="password">$dbServerA{hibernate.connection.password}</prop>
</props>
</property>
<property name="poolSize"><value>20</value></property>
<property name="testQuery" value="SELECT 1" />
which in turn gets used in the EntityManagerFactor bean. This configuration works great as long as I'm pointing to the local instance of MySQL. Changing the configuration to point to the remote instance kept failing with references to zzdb_admin#localhost no matter what I did.
So I created a second, much simpler connectivity tester using only
Class.forName("com.mysql.jdbc.Driver");
String connectionUrl = "jdbc:mysql://mybiz.com/zzdb?user=zzdb_admin&password=removepw";
theApp.conn = DriverManager.getConnection(connectionUrl);
and EUREKA! It worked to make a remote connection. So that got me thinking the problem had to lie with the Atomikos bean configuration.
Turns out there's one crucial xaProperty I wasn't setting - serverName, which when not explictly set defaults to - you guessed it - localhost. Atomikos isn't "smart" enough to infer the hostname out of the uri passed to it.
So merely switching to
<bean id="dataSourceServerA" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
<property name="uniqueResourceName" value="XADBMS_A" />
<property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
<property name="xaProperties"> <!-- properties will be different for different data sources ie MySQL/HSDB/DB2 etc -->
<props>
<prop key="serverName">mybiz.com</prop>
<prop key="port">3306</prop>
<prop key="databaseName">zzdb</prop>
<prop key="user">$dbServerA{hibernate.connection.username}</prop>
<prop key="password">$dbServerA{hibernate.connection.password}</prop>
</props>
</property>
<property name="poolSize"><value>20</value></property>
<property name="testQuery" value="SELECT 1" />
did the trick. So the problem was one of configuration. Fiendishly subtle indeed!
Thanks to all who replied!
CASE CLOSED!
Still-learning Steve
I have a Java Hibernate project configuration which worked with SQL Server 2008 R2, now with a new OS 8.1 (from 7) and SQL Server 2012 (express), I'm unable to connect to SQL server.
Relevant configuration which is/should be syntactically correct since it worked with 2008 R2:
datasource.properties
jdbc.driverClassName=net.sourceforge.jtds.jdbc.Driver
jdbc.url=jdbc:jtds:sqlserver://localhost:1433/dbname;instance=SQLEXPRESS
jdbc.username=auser
jdbc.password=xyz
I've tried two dialects org.hibernate.dialect.SQLServerDialect worked in 2008 R2.
hibernate.hbm2ddl.auto=create-drop
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
#hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
hibernate.show_sql=true
springConfiguration.xml
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
SQL Server 2012 was installed with mixed mode authentication and SQL Server Management Studio has no problem connecting (with or without the instance name).
I've updated the SQL Server Network Configuration for SQLEXPRESS.
Protocols for SQLEXPRESS:
TCP/IP Enabled
As well as all of the TCP/IP Properties - TCP Port's to 1433.
I've tried disabling Windows Firewall just to test if it's in the way but it results in the same error.
I ended up adding Firewall rules and following some of the steps in this excellent configure SQL Express 2012 to accept remote connections article.
The error message:
Caused by: java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
Your problem is jTDS does not support the way DBCP2 validates a connection by default (I'm assuming you use DBCP2 from <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource">). See the solution below.
Usually the error stacktrace is as shown:
Caused by: java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.isValid(DelegatingConnection.java:913)
The problem, though, is not related to the SQL Server version, but to the DBCP (Tomcat) version used (or the Tomcat server version the project is deployed to).
Once I was using jTDS 1.3.1 and the project worked fine (and connected to SQLServer 2012 as well) under Tomcat7. When I changed to Tomcat 8, that error appeared.
The reason, as hinted in jTDS forums, is:
(Tomcat7 uses DBCP 1 and Tomcat 8 uses DBCP 2)
Unlike DBCP 1.x, DBCP 2 will call java.sql.Connection.isValid(int) to validate the connection
jTDS doesn't implement .isValid(), so jTDS driver won't work with DBCP 2, unless...
...unless you set the validationQuery parameter, which will make DBCP not call .isValid() to test the validity of the connection.
Workaround
So, the workaround is to set the validationQuery parameter, which will make DBCP2 not call .isValid() to test the validity of the connection. Here's how:
On Tomcat
Add validationQuery="select 1" to your Tomcat <Resource> tag for connection pool, which is usually in META-INF/context.xml of your app or conf/server.xml:
<Resource ... validationQuery="select 1" />
On Spring
When using DBCP2 through Spring, the solution is something around:
<bean id="..." ...>
...
<property name="validationQuery" value="select 1" />
</bean>
On Simple java Code
dataSource.setValidationQuery("select 1");
It appears that jTDS has some issues with SQL Server 2012 (update 2?) or something has changed in 2012/8.1 which previously worked in 2008 R2/7.
Using nearly the same configuration as above with a couple minor changes, I downloaded and changed the datasource.properties to use Microsoft JDBC Driver 4.0 for SQL Server.
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://localhost:1433;
#jdbc.url=jdbc:sqlserver://localhost\dbname:1433;
I just put the sqljdbc4.jar in tomcat\lib\ to verify that the MS JDBC driver 4.0 works with SQL Server 2012 with all updates and it works perfectly. The dialect org.hibernate.dialect.SQLServerDialect worked in 2012 too.
I have a project that uses EclipseLink 2.1.3 under Tomcat 7.
What's bugging me is that the connection to the server doesn't persist through all of the app's life.
For a ServerSession to start I have to access the application manually.
Is there a way to automatically start a ServerSession when the application deploys and keep it running at all times ? So that I can access the application after a long idle time without having to wait ?
Thank you!
EDIT:
I have the following lines in persistence.xml
<property name="eclipselink.jdbc.read-connections.min" value="5"/>
<property name="eclipselink.jdbc.read-connections.max" value="10"/>
<property name="eclipselink.jdbc.write-connections.min" value="6"/>
<property name="eclipselink.jdbc.write-connections.max" value="12"/>
Server applications usually use a JDBC connection pool to get connections and reuse them. Depending on the pool you use, you may configure it to keep a given number of connections open.
I have a machine running a java app talking to a mysql instance running on the same instance. the app
uses jdbc4 drivers from mysql. I keep getting com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
at random times.
Here is the whole message.
Could not open JDBC Connection for transaction; nested exception is
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was25899 milliseconds ago.The last packet sent successfully to the server was 25899 milliseconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
For mysql, the value of global 'wait_timeout' and 'interactive_timeout' is set to 3600 seconds and 'connect_timeout' is set to 60 secs. the wait timeout value is much higher than the 26 secs(25899 msecs). mentioned in the exception trace.
I use dbcp for connection pooling and here is spring bean config for the datasource.
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db"/>
<property name="username" value="xxx"/>
<property name="password" value="xxx" />
<property name="poolPreparedStatements" value="false" />
<property name="maxActive" value="3" />
<property name="maxIdle" value="3" />
</bean>
Any idea why this could be happening? Will using c3p0 solve the problem ?
Try setting up the Apache Commons DBCP correctly.
You need to set:
validationQuery to SELECT 1+1
testOnBorrow to true
That should fix the problem.
Can you describe how your app is handling connection pooling? I doubt that autoReconnect=true in the JDBC driver would re-pool connections from your app. The app needs to reconnect when it loses a connection.
I'd follow the advice in the exception. You should consider either:
expiring and/or testing connection validity before use in your application,
increasing the server configured values for client timeouts, or
using the Connector/J connection property 'autoReconnect=true' to avoid this problem. Try adding that to your connection URL (consult the docs for the exact syntax) and see if it helps.
I doubt that C3P0 will be that much better than the DBCP that you're already using. The exception is giving you some specific advice. You've tried #3. What about the other two?
I know how to ask WebLogic to check connections before using them. You should find out how to do the same with Tomcat.
I have seen before that Windows machines which have been moved on the network have had trouble with connecting to themselves.
Is there any connectivity problems outside the JVM - i.e. mysql client connecting to the server, and timing out, etc?