ClassCastException while using opsForHash.scan() in redis - spring

ClassCastException occurs when I try to scan a large number of keys
using opsForHash.scan() method. I am using Jedis 2.6.2 and I face this
error only when the number of keys to be searched is large(~100,000).
I have read solutions to this problem online and most of them are
suggesting that the problem occurs due to connection pooling.
I am using Spring integration in my project and have set use-pool attribute as true(in JedisConnectionFactory) even though it is the default option.
Since spring is supposed to manage the connections with redis, why am I still having this issue?
Please suggest.
This is the Spring Configuration file I am using :
This is the java code where i am executing scan() :

I had this same problem. After searching a lot on the internet, I found that the problem occurs due to connection pooling problems. As you have mentioned, you have set use-pool to be true in the spring configuration.
I by passed this problem by setting pooling as false. It turned out that I didn't need pooling and after that the problem didn't occur.
You can try this solution if you don't explicitly need pooling.
Here is the code snippet:
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="" p:port="6379" p:usePool="false" />
Hope it helps!

Related

JDBC DatabaseMetaData method not implemented by JDBC(T4SQLMX) driver

I am setting up a Spring-boot application to connect to HP NonStop Tandem's SQL/MX. First I achieved this connection by hard-coding the jdbc parameters like dataSource, URL, etc in the service section of the application and it worked (I was able to access tables by executing query).
Now I am trying to remove the hard coded part and have my database related info in application.properties file, but now I am getting the following error
org.springframework.jdbc.support.MetaDataAccessException: JDBC DatabaseMetaData method not implemented by JDBC driver - upgrade your driver; nested exception is java.lang.AbstractMethodError: Method com/tandem/t4jdbc/SQLMXConnection.isValid(I)Z is abstract
Can someone help me understand the root cause? The same driver jar is being used when hard-coding the datasource details and it worked but not working when having the data source properties in application.properties and needs an upgrade to the jar.
I encountered the same exception when using Spring Data JPA in a Spring Boot application, the JTDS driver and the Hikari connection pool. In my case I discovered that the following fixed the problem:
Examining the class com.zaxxer.hikari.pool.PoolBase, the following can be observed:
this.isUseJdbc4Validation = config.getConnectionTestQuery() == null;
Thus JDBC 4 validation will not be attempted if there is a connection test query configured. In a Spring Boot application, this can be accomplished like this:
spring.datasource.hikari.connection-test-query=select 1;
Regretfully I do not have any experience with the T4SQLMX driver but nevertheless hope this can be of some use.
I recently fought through the same issue, for me I was using a JDBC type 3 driver; but my spring implementation only supported a type 4 driver, thus when the method you linked above was attempted to be called, it caused the error.
I suggest you look for a type 4 driver for your particular database and see if that resolves your issue.

RabbitMQ: ConnectionFactory gives "Connection refused" yet I can write all in one .to()

New Camel user here.
I have a Spring Boot / Camel app and successfully got a route working which polls a REST endpoint, splits the JSON array into custom POJOS, transforms each one into one of our Protobufs, and then writes the protobuf out to our RabbitMQ.
So far so good.
However, it took me quite a bit of work to debug and get that last step working (writing out to the bus). Basically, I could never establish a connection to the bus using ConnectionFactory and instead, eventually figured out how to do it by putting the entire connection/writing to the bus using just the .to() statement in the DSL.
So I'm really, really interested to know what I was doing wrong with ConnectionFactory. Any help would be much appreciated!
Ok, so this is what worked:
(newlines added for clarity)
.to(“rabbitmq://hostname:5672/exchange?
username=user&
password=password&
vhost=sandbox&
exchangeType=topic&
routingKey=routingkey&
durable=false&
autoDelete=false”);
Actually, I have a quick question here: Is doing the above wasteful in the sense that the connection isn't pooled and it's establishing the connection with every single write?
Ok, and this is what didn't work and kept giving me a java.net.ConnectException: Connection refused error:
RabbitMQEndpoint endpoint = new RabbitMQEndpoint();
endpoint.setHostname(“hostname”);
endpoint.setVhost(“sandbox”);
endpoint.setUsername(“user”);
endpoint.setPassword(“password”);
endpoint.setPortNumber(5672);
endpoint.setRoutingKey(“routingkey”);
endpoint.setExchangeName(“exchange”);
endpoint.setExchangeType(“topic”);
endpoint.setDurable(false);
endpoint.setAutoDelete(false);
Connection connectionFactory = new RabbitMQConnectionFactorySupport().createFactoryFor(endpoint);
So what am I missing??
For what it's worth, if the above connection worked, I was going to write the bus with the following .to() statement. Does it look correct? In particular, can I specify anything after the 'rabbitmq:' in place of the 'bogusbus'?
.to(“rabbitmq:bogusbus?exchangeType=topic&exchangeName=exchange&routingKey=routingkey”);
Thank you so much for your help!
According to the documentation you can configure a com.rabbitmq.client.ConnectionFactory and then reference it as follows in your route:
.to("rabbitmq:exchangeName?connectionFactory=#rabbitConnectionFactory&...")
Where rabbitConnectionFactory is the bean name of the connection factory instance in your bean registry (notice the needed #).
Take care that all connection options on the URI are ignored if you reference a connectionFactory!

"Connect timeout" in spring ws and still survive?

Spring 3.2.6
There might be an easy solution for this that I've missed, but I've been scouring the boards for the last couple days, tried a few things and so far nothing - so I thought I'd consult the experts.
My app:
I have 5 JaxWsPortProxyFactoryBean beans configured in my applicationContext.xml that connect to and consume various web services. Everything works fine, very nice!
Problem:
When my app starts there may be 1 or more web services that are either OFF or not accessible. This is fine as my app can run without them; however, is there a way to continue processing other beans in the context after receiving a TimeoutException (or any Exception due to connectivity with the WS)?
I was hoping for a property in JaxWsPortProxyFactoryBean like continueOnError or something similar.
Hope this makes sense.
You can disable the lookup/check of the web service at startup by setting the lookupServiceOnStartup property to false.
<bean id="yourService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="lookupServiceOnStartup" value="false" />
// Other properties
</bean>
Advantage your application starts up a bit faster, drawback the first call to the web service might take a little longer.
You can check the javadoc for more information, the lookupServiceOnStartup property is defined on the JaxWsPortClientInterceptor.
Possible solution is to use setLookupServiceOnStartup and set it to false.
http://static.javadoc.io/org.springframework/spring-web/3.2.6.RELEASE/index.html?org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.html

Spring #Cacheable not working - what's wrong with my config?

I've seen many incarnations of this same issue but I think I've tried all the fixes - my usage is quite straightforward.
I had been using Ehcache which also didn't work. So, to rule out Ehcache issues and help point to something more fundamental, I moved to SimpleCacheManager and ConcurrentMapCacheFactoryBean.
Here's my config:
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="parentAppIds"/>
</set>
</property>
</bean>
Here's my method:
#Cacheable(value="parentAppIds", key="accountNumber")
public Long findApplicationId(String accountNsc, String accountNumber) throws EMSException {
....
}
This is a method on an interface, who's implementing class is Spring managed #Service("foo")
I tried using 'p0' as is suggested here but to no avail. I have no compilation problems and no errors in my server logs so I'm confident that I have all that is necessary on my classpath; and that Namespaces are all fine, since I'm using STS for that - so I left out pom.xml and spring Namespace declarations to block noise.
I'm using Spring 3.1; Java 1.5 and Websphere 6.1
The symptom is that the method is being visited with the same parameters repeatedly.
Please help - I'm hungry and refuse to go for lunch until I nail this.
note: I have simplified my #Cacheable declaration my actual one is
#Cacheable(value="parentAppIds", key="#p0.concat('-').concat(#p1)")
Neither work.
Thanks.
** Edit - I've ruled out Websphere as being a problem by creating a test rig with
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(...)
which mimics what is happening. #Cacheable is simply not working. There must be something blindingly obvious that I am missing. (I've had lunch now)
My issue is resolved. Unfortunately I cannot pinpoint exactly where my issue lay. Certainly, all that is required is that which I have mentioned in my question.
TO fix this, I tidied up my Spring configuration a bit and cleared my browser and application server cache and temp directories. I did a full clean install and cache is now working.
It is possible that I was testing with an earlier version which did not include this important line in the application config:
<cache:annotation-driven/>
I had omitted that at the start. Maybe my adding of that was not picked up until now. Otherwise I am stumped. Thanks for your time.
Did you perhaps change
#Cacheable(value="parentAppIds", key="accountNumber")
to
#Cacheable(value="parentAppIds", key="#accountNumber")
as adding the # that removed one error for me while trying to get caching working.

logging connection pooling for org.apache.commons.dbcp.BasicDataSource with spring

I am trying to log connection pooling for org.apache.commons.dbcp.BasicDataSource using log4j
I am using spring framework for dao layer injection.
When I saw code inside org.apache.commons.dbcp.BasicDataSource, Logger is not used .So it seems impossible to log pooling message for me.
But again I saw this link
http://forum.springsource.org/showthread.php?38306-Connection-Pooling-debug-info.
Some people were saying to put
log4j.category.org.apache.dbcp=DEBUG. But I could not find the right answer.
So my question is, can connection pooling log using log4j for org.apache.commons.dbcp.BasicDataSource?
It seems that BasicDataSource only has a PrintWriter, not a Logger as a member variable. So you'd have to call BasicDataSource.setLogWriter(printWriter) where the printWriter is simply wrapping your log4j logger.
I came across this:
http://www.opensource.apple.com/source/JBoss/JBoss-737/jboss-all/common/src/main/org/jboss/logging/util/LoggerWriter.java
which seems to do exactly that. I don't know of a tool in Apache Commons that does something similar, but the class in the link above seems like it would accomplish what you are looking for.
Its too late since the question was asked but this is how I fixed the issue:
Specify the logger to the driver in JDBC URL
new BasicDataSource().setUrl("jdbc:mysql://localhost/DBName?logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true");

Resources