"org.hibernate.HibernateException: No Session found for current thread" even when method is wrapped in proxy - spring-aop

I'm getting following error:
org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:106)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at com.test.serviceimpl.EbayCredentialImpl.getCredential(EbayCredentialImpl.java:22)
at com.test.serviceimpl.EbayCredentialImpl$$FastClassBySpringCGLIB$$3f81c256.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
at com.test.serviceimpl.EbayCredentialImpl$$EnhancerBySpringCGLIB$$a9d77df8.getCredential(<generated>)
at com.test.jobs.EbayJob_FetchOrders.fetchAndUpdateOrders_Execute(EbayJob_FetchOrders.java:64)
at com.test.jobs.EbayJob_FetchOrders.execute(EbayJob_FetchOrders.java:48)
at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557)
related spring configs:
<bean id="hibernateSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- annotation.AnnotationSessionFactoryBean -->
<property name="dataSource" ref="mysqlDataSource" />
......
with NO hibernate.current_session_context_class.
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
<tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Throwable"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(* com.test.jobs.*.*Job*.*_Execute(..))" advice-ref="transactionInterceptor"/>
</aop:config>
As you can see, the method is wrapped in proxy, still no session found!
The method is run by a scheduler's job, not a controller method, it gets daos etc from spring context. the transaction etc is working good on controller methods, where i'm using #transactional.
Versions: hibernate-4.3.5, spring-4.0.4
Any clue is appreciated.

if you are going to configure your transaction manager as annotation-driven you dont need code below
<tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Throwable"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor pointcut="execution(* com.test.jobs.*.*Job*.*_Execute(..))" advice-ref="transactionInterceptor"/>
</aop:config>
just #Transactional(propagation= Propagation.REQUIRES_NEW) will handle it with
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>
However i think you can set (propagation= Propagation.REQUIRES_NEW) only at function level as
#Service
public class SomeService{
#Autowired
private DataSource dataSource;
#Transactional(propagation=Propagation.REQUIRES_NEW)
public void useDataSource() {
//save record
}
}

Related

Hybris interceptor is not getting triggered

I create ValidateInterceptor in below path and created bean in custombackoffice-backoffice-spring.xml
C:\hybris\bin\custom\custombackoffice\backoffice\src\com\custom\backoffice\interceptor\CustomAppeasementUserValidateInterceptor.java
bean is as below
<bean id="customAppeasementUserValidateInterceptor" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">
<property name="interceptor" ref="customAppeasementUserValidateInterceptor" />
<property name="typeCode" value="Appeasement" />
</bean>
when I modify particular model in backoffice and click on the save button, debugger never goes to interceptor it directly saves the model.
NOTE :- I can't write this interceptor in customcore because we can not import below services in custom core
import com.hybris.cockpitng.core.user.AuthorityGroupService;
import com.hybris.cockpitng.core.user.impl.AuthorityGroup;
Why the interceptor is not getting triggered?
The bean-id and the mapper bean-id are the same. Change either one. Ideally, it should be like-
<bean id="customAppeasementUserValidateInterceptorMapping" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">
<property name="interceptor" ref="customAppeasementUserValidateInterceptor" />
<property name="typeCode" value="Appeasement" />
</bean>
Notice the new id for the mapping bean i.e. customAppeasementUserValidateInterceptorMapping.

Unable to inject Bean properties in Spring Bean BasicDataSource

I'm trying to use in the BasicDataSource the username and password as derived from a Bean class:
<bean class="org.apache.commons.dbcp.BasicDataSource" id="myDataSource">
<property name="driverClassName" value="org.teiid.jdbc.TeiidDriver"/>
<property name="url" value="jdbc:myurl"/>
<property name="username" value="${bean:quickstartConfiguration?method=getQueueUsername}"/>
<property name="password" value="${bean:quickstartConfiguration?method=getQueuePassword}"/>
<property name="maxIdle" value="1"/>
</bean>
In my project I have a Bean class named QuickStartConfiguration with methods getQueueUser and getQueuePassword.
Unfortunately, when the route gets instantiated, it seems that the username and password is not parsed:
The username "quickstartConfiguration?method=getQueueUsername" and/or password and/or payload token could not be authenticated by security domain ldap-security.)
What is weird is that however using the log component, I'm able to retrieve the actual value from the Bean:
<log id="async-queue-cred-log" message="----> Using username '${bean:quickstartConfiguration?method=getQueueUsername}' for the async queue"/>
Is there any limitation in the BasicDataSource class which prevents from evaluate the Bean expression?
Thanks!

Came jmsComponent: what's the difference setting the exception Listener in different beans?

I set up a jms component with spring like this way:
<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
<property name="sessionCacheSize" value="10"/>
<property name="exceptionListener" ref="exceptionListener"/>
</bean>
<bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="cachedConnectionFactory"/>
<property name="concurrentConsumers" value="10"/>
</bean>
I notice that all these 4 beans have exceptionListener property. So I wonder what's the difference setting exceptionListener in different beans.
During my test, only setting in CachingConnectionFactory can work, it can go into my ExceptionListener, while in other cases, the exception will be logged somewhere else, but can't go into my code, the exception is like below.
WARN CachingConnectionFactory.onException(322) - Encountered a JMSException - resetting the underlying JMS Connection
javax.jms.JMSException: java.io.EOFException
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:54)
at org.apache.activemq.ActiveMQConnection.onAsyncException(ActiveMQConnection.java:1983)
at org.apache.activemq.ActiveMQConnection.onException(ActiveMQConnection.java:2002)
at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:101)
at org.apache.activemq.transport.ResponseCorrelator.onException(ResponseCorrelator.java:126)
at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:101)
at org.apache.activemq.transport.TransportFilter.onException(TransportFilter.java:101)
at org.apache.activemq.transport.WireFormatNegotiator.onException(WireFormatNegotiator.java:160)
at org.apache.activemq.transport.AbstractInactivityMonitor.onException(AbstractInactivityMonitor.java:314)
at org.apache.activemq.transport.TransportSupport.onException(TransportSupport.java:96)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:200)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:392)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:275)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:221)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:213)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)
... 1 more
I can't understand how this works, please give some explanation or hint.
org.springframework.jms.connection.CachingConnectionFactory.exceptionListener set the org.apache.activemq.ActiveMQConnectionFactory.exceptionListener , so this is the same.
org.apache.camel.component.jms.JmsConfiguration.exceptionListener set up the org.springframework.jms.listener.AbstractMessageListenerContainer.exceptionListener
Set the JMS ExceptionListener to notify in case of a JMSException
thrown by the registered message listener or the invocation infrastructure.
so it is nearly the same use of that listener at any level but it is better to set it at the org.apache.camel.component.jms.JmsConfiguration.exceptionListener level to be managed by the spring Container.

output is getting repeated , should be printed only once

It is a simple select statement from mysql server and showing output on console. Somehow the result is getting printed in loop though I haven’t used any timer as such.
<beans>
<context:component-scan base-package="com.java"/>
<bean destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource" id="dataSource">
<property value="com.mysql.jdbc.Driver" name="driverClassName"/>
<property value="jdbc:mysql://localhost:3306/world" name="url"/>
<property value="root" name="username"/>
<property value="mysql" name="password"/>
</bean>
<!-- configure the Camel SQL component to use the JDBC data source -->
<bean class="org.apache.camel.component.sql.SqlComponent" id="sql">
<property name="dataSource" ref="dataSource"/>
</bean>
<camel:camelContext>
<camel:route>
<camel:from uri="sql:select id from city where countryCode='AFG' and district ='Kabol' "/>
<camel:log message="${body[id]}"/>
<camel:to uri="stream:out"/>
</camel:route>
</camel:camelContext>
</beans>
Client code is:
public static void main(String rgs[]) throws InterruptedException{
PropertyConfigurator.configure("C:/Users/payal.bansal/workspace/CamelOneProject/src/resources/log4j.properties");
//AbstractApplicationContext ctx= new ClassPathXmlApplicationContext("resources/camel-configThree.xml");
AbstractApplicationContext ctx= new ClassPathXmlApplicationContext("resources/camel-configEight.xml");
Thread.sleep(5000);
ctx.close();
}
The from SQL will repeat the SQL call every 500 milli seconds by default (its scheduled).
http://camel.apache.org/sql-component.html
If you want the SQL to fire only once, then use a timer
from timer
to sql
And configure the timer to only run once.
http://camel.apache.org/timer

cxf-rs-ws authorization under karaf

I'm trying to configure a cxf soap webservice with authorization and authentication to be deployed on Servicemix.
I configured the LDAP authentication module as follows:
<!-- Bean to allow the $[karaf.base] property to be correctly resolved -->
<ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]"/>
<jaas:config name="myRealm">
<jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required">
connection.url = ldap://srv-ldap:389
user.base.dn = ou=people,dc=intranet,dc=company,dc=com
user.filter = (uid=%u)
user.search.subtree = false
role.base.dn = ou=groups,dc=intranet,dc=company,dc=com
role.filter = (member:=uid=%u,ou=people,dc=intranet,dc=company,dc=com)
role.name.attribute = cn
role.search.subtree = true
authentication = simple
</jaas:module>
</jaas:config>
<service interface="org.apache.karaf.jaas.modules.BackingEngineFactory">
<bean class="org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory"/>
</service>
And here is the beans.xml file
<jaxws:endpoint id="myService"
implementor="com.myorg.services.impl.MyServiceWSImpl"
address="/myService">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="UsernameToken" />
<entry key="passwordType" value="PasswordText" />
</map>
</constructor-arg>
</bean>
<ref bean="authenticationInterceptor" />
<ref bean="authorizationInterceptor" />
</jaxws:inInterceptors>
<jaxws:properties>
<entry key="ws-security.validate.token" value="false" />
</jaxws:properties>
</jaxws:endpoint>
<bean id="authenticationInterceptor"
class="org.apache.cxf.interceptor.security.JAASLoginInterceptor">
<property name="contextName" value="myRealm" />
</bean>
<bean id="authorizationInterceptor"
class="org.apache.cxf.interceptor.security.SecureAnnotationsInterceptor">
<property name="securedObject" ref="securedBean"/>
</bean>
Finally, in my WebService implementation I annotated a method with #RolesAllowed.
#RolesAllowed("Role1")
public Department get(String name) throws IdMException {
return service.get(name);
}
The authentication interceptor is retrieving the user, authenticating it and retrieving the groups as RolePrincipal instances.
Then, in the authorization interceptor (SecureAnnotationsInterceptor), the method configuration is read, the expectedRoles are "Role1", but the SimpleAuthorizingInterceptor.isUserInRole method returns false.
I haven't found any example trying to do more or less the same and the few information I found was from the CXF documentation page http://cxf.apache.org/docs/security.html#Security-Authorization
I have to be missing something important, hope somebody could help me.
Thanks in advance and kind regards.
Your problem is because of Karaf's RolePricipal do not implements Group as CXF expected. Instead of it, it implements Pricipal so CXF thinks that 1st role name is a username. That is why "SimpleAuthorizingInterceptor.isUserInRole method returns false".
A solution is to wait for fixed versions of CXF (2.7.11 and 3.0.0).
If not possible to update to newer version, then an odd and temporary solution (simply workaround) is to add more than one role to a user in LDAP and to method.
You can find more about that bug here: CXF-5603

Resources