Error with Spring ldap pooling - spring-data

i build async jersey web services, and now i need to make some operations with ldap.
I have configure Spring beam.xml in this mode:
<bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.url}" />
<property name="base" value="${ldap.base}" />
<property name="userDn" value="${ldap.userDn}" />
<property name="password" value="${ldap.password}" />
<property name="pooled" value="false" />
</bean>
<bean id="contextSource"
class="org.springframework.ldap.pool.factory.PoolingContextSource">
<property name="contextSource" ref="contextSourceTarget" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>
<bean id="ldapTreeBuilder" class="com.me.ldap.LdapTreeBuilder">
<constructor-arg ref="ldapTemplate" />
</bean>
<bean id="personDao" class="com.me.ldap.PersonDaoImpl">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
But when i try to use ldap i have this error:
Error creating bean with name 'contextSource' defined in class path resource [config/Beans.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool/KeyedPoolableObjectFactory
In my project i have commons-pool2-2.2.jar lib, but still i have this error..i try to add commons-pool2-2.2.jar in TOMCAT_PATH/lib but not works..
UPDATE:
If i put commons-pool-1.6.jar it works.. but if i want to use pool2 how i can do? only i must change class inn commons-pool2-2.2.jar?

Updated Answer:
Since at least Spring LDAP 2.3.2 you can now use commons-pool2. Spring LDAP now provides two classes:
For commons-pool 1.x:
org.springframework.ldap.pool.factory.PoolingContextSource
For commons-pool 2.x:
org.springframework.ldap.pool2.factory.PooledContextSource
Details can be found here:
https://github.com/spring-projects/spring-ldap/issues/351#issuecomment-586551591
Original Answer:
Unfortunately Spring-Ldap uses commons-pool and not commons-pool2. As you have found the class org.apache.commons.pool.KeyedPoolableObjectFactory does not exist in commons-pool2 (it has a different package structure), hence the error.
There is a Jira issue for the Spring-ldap project asking them to upgrade/support commons-pool2:
https://jira.spring.io/browse/LDAP-316
Until that has been completed you will have to use commons-pool 1.6.

Related

CrafterCMS: How to use crafter engine properties in an application-context bean?

I am connecting to an external database with a class that extends JdbcTemplate. My problem is that I can't use the globalProperties of the Groovy API because of the Jdbc.
I added these properties I needed in the server-config.properties:
studio.db.driverClassName
studio.db.url
studio.db.username
studio.db.password
I am trying to access them in my application-context.xml with this:
<bean id="jdbc" class="com.dbJdbcTemplate">
<constructor-arg ref="datasource"/>
</bean>
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="${studio.db.url}"/>
<property name="driverClassName" value="${studio.db.driverClassName}"/>
<property name="username" value="${studio.db.username}"/>
<property name="password" value="${studio.db.password}"/>
</bean>
I receive this error:
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not
get JDBC Connection; nested exception
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${studio.db.driverClassName}'
How do I access the properties from my bean correctly?
Add a <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer" parent="crafter.properties"/> in your site application-context.xml, like is shown in here https://docs.craftercms.org/en/3.0/site-administrators/engine/engine-site-configuration.html#id3. That lines gives you access to Engine's global properties.

propagation NOT_SUPPORTED creates failing transaction in JDBC when using ChainedTransactionManager (JDBC + JPA)

I'm working on an existing Spring application that uses JDBC (DAO's extend NamedParameterJdbcDaoSupport). There were four datasources configured, each with it's own DataSourceTransactionManager. (though only one was registered with tx:annotation-driven for some reason)
I've recently added JPA (Spring-data-JPA) into the application and configured two entityManagerFactories (for now I don't need the other two datasources). I also configured two JpaTransactionManagers and removed the corresponding DataSourceTransactionManagers for these dataSources, since the JpaTransactionManagers can also be used for JDBC transactions. (correct me if I'm wrong)
It appears I need to be able to have distributed transactions, since the two datasources (to two different databases) need to be accessed (through JPA) in one service method. Since I did not have all I need to set up JTA (missing XA-driver for one of the databases) I've decided to give the Spring ChainedTransactionManager a try. Sadly this didn't work out as expected. All works fine if I just call a service method that only uses JPA.
Though when I call an existing service method that uses a JDBC find that has a class level #transactional annotation with it's propagation set to NOT_SUPPORTED and call another service method after that with a JPA call and a #transactional, I get an exception:
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#462cf9d9] for key [org.jboss.jca.adapters.jdbc.WrapperDataSource#3fbb4c32] bound to thread [http-/127.0.0.1:8080-5]
at org.springframework.transaction.support.TransactionSynchronizationManager.bindResource(TransactionSynchronizationManager.java:189) [spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:403) [spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
After some debugging, I found out that the transactions in Spring get added to a map on a ThreadLocal in the "TransactionSynchronizationManager.bindResource" method. The problem is that when using a JDBC call with #transactional and propogation NOT_SUPPORTED, a transaction is made anyway and registered through that method. When the JpaTransactionManager tries to bind it's resource, it is already on the map (and not marked as void) which causes the error to occur.
Changing the propagation to the default "REQUIRED" for the service call that encapsulates the JDBC call fixes the problem.
I have no idea why Spring is still creating that transaction when the transactional annotation is NOT_SUPPORTED. And if it creates that transaction, it should not bypass the JpaTransactionManager.
So what I'd like to know is if there is some way to tell Spring to use the JpaTransactionManager also when it creates a transaction itself inside the NamedParameterJdbcDaoSupport. (Well actually the JdbcDaoSupport... Well actually the DataSourceUtils)
We're using Spring 3.2.5, spring-data-jpa 1.6.0 and I've used Hibernate 4.2.0 as JpaVendor.
This problem doesn't occur without the ChainedTransactionManager.
Datasources:
<bean id="dataSourceCompta" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/comptaDS"/>
</bean>
<bean id="dataSourceUnisys" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/insoverDS"/>
</bean>
<bean id="dataSourceInsoverwebMysql" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/insoverWebDS"/>
</bean>
<bean id="dataSourceBatch" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:jboss/datasources/batchDS"/>
</bean>
Single remaining JDBC transaction manager (no JPA counterpart):
<bean id="transactionManagerBatch" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceBatch"/>
</bean>
JPA Transaction Managers:
<bean id="jpaUnisysTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryUnisys"/>
<qualifier value="unisys" />
</bean>
<bean id="jpaMysqlTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryMysql"/>
<qualifier value="mysql" />
</bean>
My ChainedTransactionManager:
<bean id="chainedTransactionManager" class="org.springframework.data.transaction.ChainedTransactionManager">
<constructor-arg>
<list>
<ref bean="jpaUnisysTransactionManager" />
<ref bean="jpaMysqlTransactionManager" />
</list>
</constructor-arg>
</bean>
JPA Entity manager factories:
<bean name="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
<bean id="entityManagerFactoryUnisys" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/some-persistence.xml"/>
<property name="dataSource" ref="dataSourceUnisys"/>
<property name="persistenceUnitName" value="unisysPU"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<!-- properties -->
</property>
</bean>
<bean id="entityManagerFactoryMysql" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/some-persistence.xml"/>
<property name="dataSource" ref="dataSourceCompta"/>
<property name="persistenceUnitName" value="mysqlPU"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<!-- properties -->
</property>
</bean>
For now I've "fixed" this, by changing all the class-level transactional annotations to have propagation.REQUIRED (default) instead of NOT_SUPPORTED. Though I do not really like this solutions, since it might be somebody set those propagations to NOT_SUPPORTED with a good reason. I've also tried SUPPORTED, but using that had the same issue as NOT_SUPPORTED: a transaction was being made anyway by the Spring DataSourceUtils when the query was being executed by the NamedParameterJdbcDaoSupport DAO.
When no transactional annotation is set on the service, all works well too.

Using spring cloud namespace and two DataSources

I have a Spring Integration WAR component that I'm updating to run in private PCF. I have two DataSources and a RabbitMQ connection factory defined in the application.
I see an article from Thomas Risberg on using the cloud namespace and handling multiple services of the same time - https://spring.io/blog/2011/11/09/using-cloud-foundry-services-with-spring-part-3-the-cloud-namespace. This is handled by using #Autowired and #Qualifier annotations.
I'm wondering how this can be achieved though when we're not #Autowired and #Qualifier annotations, e.g. wiring a DataSource into a JdbcTemplate. Here we do not have the ability to specify a #Qualifier annotation.
My application is Spring XML config based. I do have ability to use #Autowired and #Qualifier annotations on one of the DataSources, but the other is JPA entity manager. See code snippet.
Any help is much appreciated.
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<beans profile="cloud">
<cloud:data-source id="dataSource" service-name="actmon-db-service" />
</beans>
Java Build Pack: java_buildpack_offline java-buildpack-offline-v2.4.zip
Spring Auto-reconfiguration version 1.4.0.
UPDATE: This is the full config for both data sources, including PropertySourcesPlaceholderConfigurer with properties loaded from data source using DAO.
<bean id="cic.application.ppc" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="properties" ref="cic.application.properties"/>
<property name="locations" ref="cic.application.propertyLocations"/>
</bean>
<bean id="cic.application.properties" class="java.util.Properties">
<constructor-arg value="#{cicPropertiesService.properties}"></constructor-arg>
</bean>
<bean id="cic.properties.propertiesService" name="cicPropertiesService"
class="com.emc.it.eis.properties.service.DefaultPropertiesService">
<constructor-arg index="0"
ref="cic.properties.propertiesDao" />
</bean>
<bean id="cic.properties.propertiesDao" class="com.emc.it.eis.properties.dao.JdbcPropertiesDao">
<constructor-arg ref="cic.properties.dataSource" />
</bean>
<beans profile="default">
<jee:jndi-lookup id="cic.properties.dataSource"
jndi-name="jdbc/intdb" />
</beans>
<beans profile="cloud">
<cloud:data-source id="cic.properties.dataSource" service-name="oracle-cicadm-db-service" />
</beans>
<beans>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="actmonDataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
<beans profile="default">
<jee:jndi-lookup id="dataSource"
jndi-name="jdbc/actmon" />
</beans>
<beans profile="cloud">
<cloud:data-source id="actmonDataSource" service-name="postgres-actmon-db-service" />
</beans>
<beans profile="default,cloud">
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="POSTGRESQL" />
</bean>
</beans>
Output from CF when I deploy https://gist.github.com/anonymous/3986a1a7cea4f20c096e. Note it is skipping auto re-configuration of javax.sql.DataSources
First of all, the post from Thomas is pretty old, and references a deprecated support library. Instead of the org.cloudfoundry:cloudfoundry-runtime:0.8.1 dependency, you should use Spring Cloud Connectors dependencies instead.
You can then follow the instructions provided for using XML configuration with Spring Cloud Connectors. With multiple services of the same type, you will need to specify the name of the service for each bean. Following your example, and assuming you created two CF database services named inventory-db and customer-db, that might look something like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="inventory-dataSource" />
<property name="persistenceUnitName" value="activity-monitor" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
<beans profile="cloud">
<cloud:data-source id="inventory-dataSource" service-name="inventory-db">
<cloud:data-source id="customer-dataSource" service-name="customer-db">
</beans>
I've managed to resolve the issue by using the factory bean used by the spring cloud:data-source, CloudDataSourceFactory. Creating an instance of this and wiring up the config including the service-name of the CF service. This avoids the issue of our PropertySourcesPlaceholderConfigurer trying to use the data source before our the bean has even been defined.
<!--
configure cloud data source for using CloudDataSourceFactory; this is what spring cloud:data-source is using;
required to manually wire this data source bean as cloud:data-source bean gets defined in a phase after our
PropertySourcesPlaceholderConfigurer bean.
-->
<bean id="cic.properties.dataSource" class="org.springframework.cloud.service.relational.CloudDataSourceFactory">
<constructor-arg value="oracle-cicadm-db-service" />
<constructor-arg>
<!-- configuring minimal data source as it is used only to bootstrap properties on app start-up -->
<bean class="org.springframework.cloud.service.relational.DataSourceConfig">
<constructor-arg>
<bean class="org.springframework.cloud.service.PooledServiceConnectorConfig.PoolConfig">
<constructor-arg value="0" />
<constructor-arg value="2" />
<constructor-arg value="180" />
</bean>
</constructor-arg>
<!-- ConnectionConfig not required for cic.properties.dataSource so setting to null -->
<constructor-arg value="#{ null }" />
</bean>
</constructor-arg>
</bean>

How to disable automatic Bean Validation in JPA entities

I'm using Bean Validation to check constraints on my model, but I don't know how to configure it so it only validates when I want it to. I found on that I could put this tag in my persistence.xml, <validation-mode>NONE</validation-mode> but it doesn't work.
I appreciate any kind of help.
I remember that i also had problems with that, here is my working example:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="punit" />
<property name="jpaPropertyMap">
<map>
<entry key="javax.persistence.validation.mode" value="none"/>
</map>
</property>
</bean>

In-memory Job-Explorer definition in Spring batch

I was trying to share My in-memory jobRepository to the jobExplorer. But it throws an error as,
Nested exception is
org.springframework.beans.ConversionNotSupportedException:
Failed to convert property value of type '$Proxy1 implementing
org.springframework.batch.core.repository.JobRepository,org.
springframework.aop.SpringProxy,org.springframework.aop.framework.Advised'
to required type
Even i tried putting '&' sign before jobRepository when passing to jobExplorer for sharing.But attempt end in vain.
I am using Spring Batch 2.2.1
Is the dependency for jobExplorer is only database not in-memory?
Definition is,
<bean id="jobRepository"
class="com.test.repository.BatchRepositoryFactoryBean">
<property name="cache" ref="cache" />
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobOperator" class="test.batch.LauncherTest.TestBatchOperator">
<property name="jobExplorer" ref="jobExplorer" />
<property name="jobRepository" ref="jobRepository" />
<property name="jobRegistry" ref="jobRegistry" />
<property name="jobLauncher" ref="jobLauncher" />
</bean>
<bean id="jobExplorer" class="test.batch.LauncherTest.TestBatchExplorerFactoryBean">
<property name="repositoryFactory" ref="&jobRepository" />
</bean>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobLauncher" class="com.scb.smartbatch.core.BatchLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<!-- To store Batch details -->
<bean id="jobRegistry" class="com.scb.smartbatch.repository.SmartBatchRegistry" />
<bean id="jobRegistryBeanPostProcessor"
class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
<property name="jobRegistry" ref="jobRegistry" />
</bean>
<!--Runtime cache of batch executions -->
<bean id="cache" class="com.scb.cache.TCRuntimeCache" />
thanks for your valuable inputs.
But I used '&' before the job repository reference, which allowed me to use it for my job explorer as a shared resource.
problem solved.
kudos.
Usually you have to wire interface instead of implementation.
Else, probably, you have to add <aop:config proxy-target-class="true"> to create CGLIB-based proxy instead of standard Java-based proxy.
Read Spring official documentation about that