Apache Camel SQL component is not closing resultset? - apache-camel

I am using Camel sql component to run select queries against Oracle DB. The war file is deployed on Jboss EAP 6.1. In the config file under configuration I have track-statements set to true (i.e. true). So Jboss checks if the result sets are closed when a connection is returned back to the pool.
I am configuring sql component as follows:
//datasource is injected here
#Resource(mappedName = "java:/jdbc/OracleDS")
private DataSource dataSource;
...
...
//SQL component
SqlComponent sqlComponent = new SqlComponent();
sqlComponent.setDataSource(dataSource);
camelCtx.addComponent("sql", sqlComponent);
The sql component is used in a recipientList as follows:
from("activemq:"+queue)
...
.recipientList(simple(getFromConfig(sqlStmtName)),"false")
..
The sql statement is nothing special. Just a regular select statement from a single table.
In Jboss logs I see this warning.
2015-04-16 16:23:07,169 WARN [org.jboss.jca.adapters.jdbc.WrappedConnection] (ajp-8009-2|R:r2K4crKLnPRT-0br|ctvc|1.0) Closing a result set you left open! Please close it yourself.: java.lang.Throwable: STACKTRACE
at org.jboss.jca.adapters.jdbc.WrappedStatement.registerResultSet(WrappedStatement.java:1357)
at org.jboss.jca.adapters.jdbc.WrappedStatement.getResultSet(WrappedStatement.java:740)
at org.apache.camel.component.sql.SqlProducer$2.doInPreparedStatement(SqlProducer.java:127)
at org.apache.camel.component.sql.SqlProducer$2.doInPreparedStatement(SqlProducer.java:90)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
at org.apache.camel.component.sql.SqlProducer.process(SqlProducer.java:90)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:573)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:506)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:215)
at org.apache.camel.processor.RecipientList.sendToRecipientList(RecipientList.java:167)
at org.apache.camel.processor.RecipientList.process(RecipientList.java:120)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:72)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:398)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
...
...
I checked SqlProducer.java (line 127). Since sql component uses Spring JDBCtemplate I would assume that resultset would be closed by the template.
Is there anything I need to do to close the resultset?

Yes that is a bug in Apache Camel. I have logged a ticket to get this fixed in future releases
https://issues.apache.org/jira/browse/CAMEL-8715

Related

Using a remote database as spring boot datasource

I'm trying to configure spring boot datasource as a remote IBM DB2 database. I have added the following configurations in my application.properties file:
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:db2://<dbhost>:<dbport>/<db>
spring.datasource.username=<username>
spring.datasource.password=<password>
I even added the same properties in application.yml:
spring:
datasource:
url: jdbc:db2://dashdb-txn-sbox.services.eu-gb.bluemix.net:3000/BLUDB:sslConnection=true;
username: <username>
password: <password>
driverClassName: com.ibm.db2.jcc.DB2Driver
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.DB2Dialect
However, I'm still getting this error:
A communication error occurred during operations on the connection's underlying socket, socket input stream, or socket output stream. Error location: Reply.fill() - socketInputStream.read (-1). Message: Read timed out. ERRORCODE=-4499, SQLSTATE=08001
This question is more about configuration than programming.
See this FAQ for JDBC ERRORCODE -4499
which mentions:
(A.5) Message: Read timed out
This message is returned when client is waiting for reply from the
server and the server did not reply in time. Could be caused by client
timeout. Ensure no timeouts set in JDBC driver properties:
blockingReadConnectionTimeout=0 (default)
commandTimeout=0 (default)
loginTimeout = 0 (default)
Could also be caused by server or network issues.
If the issue is persistent, ensure you are using the latest jdbc Db2 driver ( at the present date that would be version 4.26.14 or higher).
You can use jdbc trace (follow the instructions in IBM Db2 documentation to enable jdbc trace) to look under the covers to see exactly what is happening.
Ensure the remote Db2-server has sufficient compute resources to respond in time. You may need to open a ticket with your cloud vendor (IBM) if the jdbc trace suggests a server side issue that is not under your direct control.
50001 is the usual (default) port number for ssl connections, not 3000 as you have in your question

Hibernate persists Java 8 DateTimeLocal as VARBINARY in SQL Server

I'm trying to make use of the Java 8 date & time API in a new application which is backed by SQL Server database. All the resources on the Internet state that Hibernate 5.2+ support this API and Java 8 out of the box and suggest a simple approach as:
#Entity
#Table(name="...", schema="...")
public class DepositDetails {
// ... id, other fields ...
private LocalDateTime createdOn;
// ... other fields, getters/setters ...
}
In my case, however, the column which is created in the database (using hibernate-jpamodelgen), is created as VARBINARY(255) instead of DATETIME/DATETIME2.
I've also tried specifying the datatype explicitly (columnDefinition = "DATETIME") - in this case the column type is created correctly as specified, but when I try to persist data in the table, I get an exception stating that varbinary data cannot be converted to datetime...
Some more details about the application setup that may be related to the issue:
Hibernate is 5.2.12.Final
SQL Server is Microsoft SQL Server Developer Edition (64-bit) 14.0.900.75 (in a Docker container)
MSSQL JDBC driver is 6.2.2.jre8
The problem was, as suggested by #Alan Hay, that Hibernate 5.2 was replaced in the dependency tree by Hibernate 5.0, which is used by default by Spring Boot.
Moreover, I had a property in my child pom.xml which was set to 5.2.12.Final, but on a parent level the same property was set (again by Spring Boot) to 5.0.x. In this way the parent application, which should have taken the 5.2 dependency from the child module, was actually taking the old version from Spring Boot.
The solution was to set the property in the parent pom.xml.

Destroying connection that could not be successfully matched : Error in jboss while connecting with Database

Modified: I am using Jboss 7 server and oracle 10g for my web Application but when I starting the server application working properly but after 2 or 3 hours it is becoming slow.
I guessed like.
1. connection is not happening between database and jboss server properly so that it is not fetching data, so cause of this it becoming slow.
Datasource information in my standalone-full.xml file in jboss server is below:
<datasources>
<datasource jndi-name="java:/TTKConnectionDataSource" pool-name="TTKConnectionDataSourcePool" enabled="true" use-java-context="true" use-ccm="false">
<connection-url>jdbc:oracle:thin:#10.1.0.112:1521:vidaltest</connection-url>
<driver-class>oracle.jdbc.OracleDriver</driver-class>
<driver>oracle</driver>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>150</max-pool-size>
<prefill>true</prefill>
<use-strict-min>true</use-strict-min>
<flush-strategy>FailingConnectionOnly</flush-strategy>
</pool>
<security>
<user-name>appln</user-name>
<password>appln</password>
</security>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
<validate-on-match>true</validate-on-match>
<background-validation-millis>300000</background-validation-millis>
<stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
<exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
</validation>
<timeout>
<idle-timeout-minutes>10</idle-timeout-minutes>
</timeout>
</datasource>
And error what I am getting during slow down of server :
11:31:04,689 WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (http-web-10) IJ000612: Destroying connection that could not be successfully matched: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener#323ff8fa[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection#62b2c9f connection handles=0 lastUse=1494391408674 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool#547ac048 pool internal context=SemaphoreArrayListManagedConnectionPool#46e5e24c[pool=TTKConnectionDataSourcePool] xaResource=LocalXAResourceImpl#1e6c0ff1[connectionListener=323ff8fa connectionManager=488aa6d1 warned=false currentXid=null] txSync=null]
11:37:09,075 INFO [com.ttk.action.claims.TTKListener] (http-web-20) Session is created sessionCreated
11:37:09,078 ERROR [org.apache.struts.actions.DispatchAction] (http-web-20) Request[/LoginAction] does not contain handler parameter named 'mode'. This may be caused by whitespace in the label text.
11:46:35,964 WARN [org.jboss.jca.adapters.jdbc.local.LocalManagedConnectionFactory] (http-web-10) Destroying connection that is not valid, due to the following exception: oracle.jdbc.driver.T4CConnection#5b8b1ccb: java.sql.SQLException: pingDatabase failed status=-1
at org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker.isValidConnection(OracleValidConnectionChecker.java:74) [ironjacamar-jdbc-1.0.12.Final.jar:1.0.12.Final]
05: Connection error occured: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener#38b370[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection#a8c7e2d connection handles=0 lastUse=1494390662156 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool#547ac048 pool internal context=SemaphoreArrayListManagedConnectionPool#46e5e24c[pool=TTKConnectionDataSourcePool] xaResource=LocalXAResourceImpl#dafc1c4[connectionListener=38b370 connectionManager=488aa6d1 warned=false currentXid=null] txSync=null]: java.sql.SQLException: pingDatabase failed status=-1
when I am restarting server than connection is fine up to 2 or 3 hours maximum after that server again becoming slowdown ,Please suggest me what are the possibilities to overcome on this issue.
Thanks in advance.
sorry for disturbance, but again I am facing this problem actually what is happening ? when my server become slowdown then it's not allowing me to login its keep on buffering because its not connecting with my database as i think or may be its not getting connection object. and after some time of buffering its giving warning message what i mentioned above "Destroying connection that could not be successfully matched" . than after that if i will try to login the application than its taking time to get login or last option i need to restart my server that is not that much preferable ever.
The WARN messages are not unusual when something outside JBoss closes a connection.
That warning indicates that JBoss got the Oracle JDBC driver to ping the database to ensure that the connection still worked, and it reported that it didn't, so JBoss destroyed the connection. JBoss would then create a new one and give that to the application, so it should in theory not cause any actual problems.
Method "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker.isValidConnection()" throws this exception. Method isValidConnection() internally calls OracleConnection's pingDatabase() [1] method. It the database is closed it returns -1, refer [2]. This issue is a known issue with Oracle driver which is seen when their are issues with network or database and is not related to JBoss
This is a known type of error indicating some problem with your Oracle database or occasionally with the network.
I would ask you to check the network connectivity is stable between the JBoss node and Database.
[1] https://docs.oracle.com/cd/E18283_01/appdev.112/e13995/oracle/jdbc/OracleConnection.html#pingDatabase__
[2] https://docs.oracle.com/cd/E18283_01/appdev.112/e13995/oracle/jdbc/OracleConnection.html#DATABASE_CLOSED

How to set autoReconnect after configuration error in Play Framework?

I have an application on Play Framework 2.3, and connecting to SQL Server (2008, 2012 and 2014 versions). Configuration looks like this:
db.default.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
db.default.url="jdbc:sqlserver://192.168.100.101;databaseName=myDatabase;SelectMethod=direct;autoReconnect=true"
That works propperly except for application starting before starting SQL Server. In that case play generates an error:
Configuration error[Cannot connect to database [default]]
Is, that possible, to set PlayFramework automaticly reconnect, after that error, when Play arrives a new request, and how can I do that?
HikariCP has a property to do exactly what you want:
initializationFailFast: This property controls whether the pool will "fail fast" if the pool cannot be seeded with initial connections successfully. If you want your application to start even when the database is down/unavailable, set this property to false. Default: true
You can use play-hikaricp module to replace the default pool (BoneCP) and then configure HikariCP as explained above.

exception occurred when using GAE/J and Google Cloud SQL with multiple project

following exception occured.
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:33)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1117)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:350)
at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2416)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2450)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2235)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:818)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
Caused by: java.net.SocketException: Unable to open connection to the instance: project-A:dba
at com.mysql.jdbc.GoogleCloudSqlSocket.<init>(GoogleCloudSqlSocket.java:48)
at com.mysql.jdbc.GoogleCloudSqlSocketFactory.connect(GoogleCloudSqlSocketFactory.java:81)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:300)
... 44 more
Caused by: java.io.FileNotFoundException: /cloudsql/project-A:dba(No such file or directory)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:247)
at java.io.RandomAccessFile.<init>(RandomAccessFile...(length 8379)
I have two GAE/J project and both refer same google cloud sql instance.
ex)
project-A(gae/j) use project-A:dba(cloudsql)
project-B(gae/j) use project-A:dba(cloudsql)
such exception occured in project-B.
db connection setting is following.
////(in project-B's java file)//////
String url = "jdbc:google:mysql://"+ "project-B" + ":db/db1";
Connection con = DriverManager.getConnection(url, properties);
////
this is bug? or any mistake?
If the Cloud SQL instance is the same for both projects, then the "project X" used as a qualifier of the instance, must be the same for both applications. This is the project name under which the Cloud SQL instance was created.
The DB host is built in Java as "jdbc:google:mysql://your-project-id:your-instance-name/"
According to your example, it would be "project-A:db/".
Don't forget to authorize your project-B app to access the Cloud SQL instance.

Resources