Spring Integration - Message Store configuration for Microsoft SQL Server 2012 - java

I setup a MessageStore in Spring Integration using JDBC, following there's my configuration:
<bean id="queryProvider" class="org.springframework.integration.jdbc.store.channel.MySqlChannelMessageStoreQueryProvider" />
<!-- JDBC message store configuration -->
<bean id="store" class="org.springframework.integration.jdbc.store.JdbcChannelMessageStore">
<property name="dataSource" ref="basicDataSource" />
<property name="channelMessageStoreQueryProvider" ref="queryProvider" />
<property name="region" value="TX_TIMEOUT" />
<property name="usingIdCache" value="true" />
</bean>
My underlying DB is Microsoft SQL Server 2012 and when starting up the server I get the following exception:
nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'LIMIT'.
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:664)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:704)
How can I fix this problem?

The best way to implement SqlServerChannelMessageStoreQueryProvider and don't use MySqlChannelMessageStoreQueryProvider, because those RDBMS vendors use different DML.
Feel free to raise a JIRA ticket and even contribute!

Related

Why error No suitable driver found for jdbc:h2

When I debug my Mule application i have error:
org.springframework.dao.DataAccessResourceFailureException: Error retrieving database metadata; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Could not get Connection for extracting meta data; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: No suitable driver found for jdbc:h2:~/test
my java code:
SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate.getDataSource()).withProcedureName("my_procedure_name").withSchemaName("my_schema");
...
call.execute(in)
my aaplicationContext:
<bean id="dataSource2"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db2.driver}" />
<property name="url" value="${db2.url}" />
<property name="username" value="${db2.user}" />
<property name="password" value="${db2.password}" />
</bean>
my app_name.properties:
db2.url=jdbc:h2:~/test
db2.driver=org.h2.Driver
db2.user=sa
db2.password=
my pom:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
my classpath:
<classpathentry kind="var" path="M2_REPO/com/h2database/h2/1.4.200/h2-1.4.200.jar"/>
log info after run application:
INFO org.springframework.jdbc.datasource.DriverManagerDataSource - Loaded JDBC driver: org.h2.Driver
Also i put h2-1.4.200.jar (when I starting my application from AnypointStudio) to:
c:\...\plugins\org.mule.tooling.server.3.9.0_6.4.0.201908221250\mule\lib\user\
and:
c:\...\plugins\org.mule.tooling.server.3.9.0_6.4.0.201908221250\mule\lib\boot\
and:
c:\...\plugins\org.mule.tooling.server.3.9.0_6.4.0.201908221250\mule\lib\mule\
and when I run application from mule server h2-1.4.200.jar, I put here:
..\mule-standalone-3.9.0\lib\boot
and
..\mule-standalone-3.9.0\lib\user
and:
..\mule-standalone-3.9.0\lib\mule
why application driver h2 not found ? what's the problem ?
Thanks.
You are mixing 3 different ways of managing the JDBC driver dependency, and also duplicating the library in the runtimes. That also makes it more difficult to understand the problem, and to deploy an application.
Let's start with Maven. It looks like you are using the right dependency in the pom, as long as it is in the section.
If the project is using Maven, there should not be any need to look into , unless it is out of sync with Maven. You should not change the class path manually, or edit the build path in Anypoint Studio. These are part of Studio/Eclipse .classpath files and should be left alone. Be sure to update the project so Studio regenerates the classpath.
About MULE_HOME\lib\boot, MULE_HOME\lib\user, MULE_HOME\lib\mule (either in Studio or standalone), you should not put the library in there. The Maven dependency is enough and you are duplicating the versions. Even if you can share a library in lib\user, it is not recommended. It makes more difficult to replicate sanely a deployment and again, there is no need for the JDBC driver. You should not put anything at all in lib\boot nor lib\mule nor the other subdirectories of lib. These are reserved for the runtime.
Try removing all those extras first and see what happens with a clean deployment.
Update:
Once the libraries are cleaned up, take into account that the Spring class may have some classloading issues itself. It is almost always better to use a datasource pool implementation. There are several to choose, like c3p0, dbcp, and others.
One example with c3p0:
<spring:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<spring:property name="driverClass" value="${JDBC.driver}"/>
<spring:property name="jdbcUrl" value="${JDBC.URL}"/>
<spring:property name="user" value="${JDBC.user}"/>
<spring:property name="password" value="${JDBC.password}"/>
<spring:property name="minPoolSize" value="5"/>
<spring:property name="maxPoolSize" value="20"/>
</spring:bean>
See https://help.mulesoft.com/s/article/Spring-based-datasources for more examples.

Hibernate in emeddable websphere container does not find java:comp/websphere/ExtendedJTATransaction

I have a Java EE application which uses Hibernate 4.2.7 as persistence provider executing Junit tests in an embeddable Websphere 8.0.0 container. Database access works fine in a real (i.e. non-embedded) Websphere 8.0.0 instance. The unit tests do work when run with OpenJPA instead of Hibernate. However, running the Junit tests with Hibernate, I get the following exception:
CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getEntity" on bean "BeanId(embeddable#classes#SomeBean, null)". Exception data: org.hibernate.service.jndi.JndiException: Unable to lookup JNDI name [java:comp/websphere/ExtendedJTATransaction]
at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:156)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:152)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124)
at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getStatus(WebSphereExtendedJtaPlatform.java:119)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73)
at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115)
at org.hibernate.service.jta.platform.internal.TransactionManagerBasedSynchronizationStrategy.canRegisterSynchronization(TransactionManagerBasedSynchronizationStrategy.java:56)
... stripped ...
It seems the implementation of WebsphereExtendedJtaPlatform is trying to get the current transaction via a JNDI lookup but fails because that JNDI name does not exist in the embedded container. Here's a snipped from org.hibernate.service.jta.platform.internal.WebsphereExtendedJtaPlatform:
public class TransactionAdapter implements Transaction {
private TransactionAdapter() {
if ( extendedJTATransaction == null ) {
extendedJTATransaction = jndiService().locate( "java:comp/websphere/ExtendedJTATransaction" );
}
}
... stripped ...
The class ExtendedJtaTransaction itself does exist on the class path inside com.ibm.ws.runtime.jar.
The settings in our persistence.xml look like this:
<persistence-unit name="BLA" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/BLA</jta-data-source>
<class>com.some.Entity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="jta.UserTransaction" value="java:comp/UserTransaction" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.jdbc.fetch_size" value="100" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
</properties>
Does anyone have a solution for this?
Thanks!
Transaction strategy configuration
Hibernate requires the configuration of two essential pieces in order to properly run with transactions. The first, hibernate.transaction.factory_class, defines transactional control and the second, hibernate.transaction.manager_lookup_class, defines the mechanism for registration of transaction synchronization so the persistence manager is notified at transaction end when it needs to synchronize changes with the database. For transactional control, both container-managed and bean-managed configurations are supported. The following properties must be set in Hibernate.cfg.xml when using Hibernate with WebSphere Application Server:
for container-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.CMTTransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
for bean-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
<property name="jta.UserTransaction">
java:comp/UserTransaction
</property >
The jta.UserTransaction property configures the factory class to obtain an instance of a UserTransaction object instance from the WebSphere container.
The hibernate.transaction.manager_lookup_class property is supported on the WebSphere platform by WebSphere Application Server V6.x and later, and on WebSphere Business Integration Server Foundation V5.1 and later. This property configures Hibernate to use the ExtendedJTATransaction interface, which was introduced in WebSphere Business Integration Server Foundation V5.1 and WebSphere Application Server V6.0. The WebSphere ExtendedJTATransaction interface establishes a pattern that is formalized in Java EE 5 via the JTA 1.1 specification.

ClassNotFoundException using Spring RMI

I have two projects (client and server) trying to exchange some objects thru Spring RMI in Eclipse Helios. The client only knows their interfaces. A similar program passing Strings works fine.
I'm following Spring In Action's 3rd edition examples, and instead of Spitter preferred Twitter :) The objects work fine at the server, and no one knows the implementations, just Spring. What is odd is that it throws a ClassNotFoundException, seeming that the client is complaining he doesn't know TwitterImpl!
Thanks in advance for any help!
Stack trace:
Exception in thread "main" org.springframework.remoting.RemoteAccessException: Could not access remote service [rmi://localhost/TwitterService];
nested exception is java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: twitter.domain.TwitterImpl (no security manager: RMI class loader disabled)
at org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(RmiClientInterceptorUtils.java:193)
at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:347)
at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:259)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy1.getTwitter(Unknown Source)
at twitter.Retrieve.getTwits(Retrieve.java:31)
at twitter.Main.main(Main.java:30)
Client rmi.xml
<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
id="twitterService">
<property name="serviceUrl"
value="rmi://localhost/TwitterService">
</property>
<property name="serviceInterface"
value="twitter.service.TwitterService">
</property>
</bean>
<bean id="retrieve" class="twitter.Retrieve">
<property name="twitterService" ref="twitterService"></property>
</bean>
Server rmi.xml
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="service" ref="twitterService" />
<property name="serviceName" value="TwitterService" />
<property name="serviceInterface" value="twitter.service.TwitterService" />
</bean>
<bean class="twitter.service.TwitterServiceImpl" id="twitterService">
<property name="twits">
...
</property>
<property name="twitters">
...
</property>
</bean>
I noobily misunderstood the concept of RMI. I thought the client shouldn't even know the class implementation, receiving the bytecodes from the server. In fact, the aim of remoting is accessing a remote object's state, and the client needs to know the implementation. Throwing a ClassNotFound exception is no surprise.

How to configure query timeout threshold for c3p0/hibernate

I have an application that is using Hibernate 3, c3p0, and spring 2.5.6. We have a datasource that is configured to speak with a postgres database. Everything was working great until a firewall was introduced between the application server and the database. We intermittently are getting java.net.SocketTimeoutException: Read Timed Out errors while trying to communicate with the database.
We believe the overhead of the firewall is causing a delayed response from the database. We want to verify this by increasing the thresh hold of how long a query should wait before deemed timed out (if that is even possible). Here is a stacktrace snippet
org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:218)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:451)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:350)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
at org.hibernate.loader.Loader.doQuery(Loader.java:697)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
... 35 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:135)
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:104)
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:259)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1166)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:192)
... 44 more
This has nothing to do with Hibernate or C3P0; you're getting a timeout from JDBC driver.
If you're using version 8.4 or higher, try setting socketTimeout to a higher value (or even zero for disabling it) in your connection string.
Try to configure timeout in jdbc properties, like this:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5433/yourdb"/>
<property name="username" value="some"/>
<property name="password" value=""/>
<property name="connectionProperties">
<props>
<prop key="socketTimeout">1000000</prop>
</props>
</property>
</bean>
Set for socketTimeout property as much value as required

Memcached Provider for NHibernate not working

I've been at this for days. I have configure my web/app config to use the second level cache with a Memcached server and the provider from NHContrib. I don't get any exceptions yet in testing I see that it does not use the cache for my queries that I have set cacheable = true.
If I switch the provider to the NHibernate.Cache.HashtableCacheProvider and test it works as expected.
here are the relevant config sections I am using
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate" />
<section name="memcache" type="NHibernate.Caches.MemCache.MemCacheSectionHandler,NHibernate.Caches.MemCache" />
</configSections>
<memcache>
<memcached host="192.168.215.60" port="11211" />
</memcache>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="dialect">
MT.Core.Persistence.Dialect, MT.Core
</property>
<property name="connection.driver_class">
NHibernate.Driver.SqlClientDriver
</property>
<property name="connection.connection_string">
Server=192.168.1.1;Initial Catalog=Test;User ID=TestUser;Password=fakepassword;
</property>
<property name="show_sql">true</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu</property>
<property name="cache.provider_class">NHibernate.Caches.MemCache.MemCacheProvider,NHibernate.Caches.MemCache</property>
<!--<property name="cache.provider_class">NHibernate.Cache.HashtableCacheProvider</property>-->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.use_query_cache">true</property>
</session-factory>
</hibernate-configuration>
</configuration>
The problem ended up being due to a connectivity problem. I used log4net to log any errors to the console and to the application log. It was then I finally saw the errors regarding connecting to the memcached server. Once the code was promoted to a server in the same location the errors were gone. I should have learned to use log4net ages ago.
For memcache the property is 'default_expiration' not 'expiration'. I am not sure about SysCache. But I have used this property for memcache and it works for me.
Initailly I also faced the same error that CountCet mentioned. The attribute 'expiration' is not recognized by the MemCache provider. Later I checked the code and found that it use the property 'default_expiration' and its default value is 300 sec.
I think that the expiration property should set for the memcache provider on the session factory level and not on the provider configuration like others (SysCache)
<property name="expiration">300</property>

Categories

Resources