I have a custom Dialog defined in a Screen and a Button in the "ActionBar-CustomItems" of an existing Grid that opens that dialog by setting the "PopupPanel" property to the "ID" of the dialog.
Is there a way to control the Visibility of the button based on run-time conditions?
Specifically it's a button in the SOOrderEntry > Transactions grid Custom Items that opens the dialog with custom data related to the current SOLine. If Base.IsTransferOrder I want to hide the button as it is not applicable. There are no custom Actions defined in the graph Extension -- only the View that is referenced within the custom Dialog.
The page extension XML:
<Page path="~/pages/so/so301000.aspx" pageSource="...">
<PXGrid ID="grid" ParentId="phG_tab_Items#0_grid" TypeFullName="PX.Web.UI.PXGrid">
<Children Key="ActionBar.CustomItems">
<AddItem>
<PXToolBarButton TypeFullName="PX.Web.UI.PXToolBarButton">
<Prop Key="PopupPanel" Value="PanelCustomSOLineRelatedRecs" />
<Prop Key="Text" Value="Open Popup" />
</PXToolBarButton>
</AddItem>
</Children>
</PXGrid>
<Content ID="cont3" ParentId="phG" TypeFullName="System.Web.UI.WebControls.Content">
<Children Key="Controls">
<AddItem>
<PXSmartPanel TypeFullName="PX.Web.UI.PXSmartPanel">
<Prop Key="Virtual:ApplyStylesheetSkin" />
<Prop Key="ID" Value="PanelCustomSOLineRelatedRecs" />
<Prop Key="Caption" Value="Dialog with Line related Records" />
<Prop Key="Key" Value="CustomLineRecs" />
<Prop Key="CaptionVisible" Value="True" />
<Prop Key="LoadOnDemand" Value="True" />
<Prop Key="AutoCallBack.Enabled" Value="True" />
<Prop Key="AutoReload" Value="True" />
<Prop Key="AutoRepaint" Value="True" />
<Children Key="Controls">...</Children>
</PXSmartPanel>
</AddItem>
</Children>
</Content>
</Page>
Update:
It was necessary to define a PXAction in the graph extension and bind the button to that Action to control the visibility even though the PopupPanel property could still be used to directly open the Dialog client-side.
So in the graph extension define the Action
public PXAction<SOOrder> openCustomLineRecs;
[PXButton]
[PXUIField(DisplayName = "Open Popup")]
public virtual void OpenCustomLineRecs() { }
Bind the PXToolBarButton to the Action specifying the CommandName, AutoCallBack.Command and AutoCallBack.Target to bind the button to the Action
<PXToolBarButton TypeFullName="PX.Web.UI.PXToolBarButton">
<Prop Key="Text" Value="Open Popup" />
<Prop Key="PopupPanel" Value="PanelCustomSOLineRelatedRecs" />
<Prop Key="CommandName" Value="openCustomLineRecs" />
<Prop Key="AutoCallBack.Target" Value="ds" />
<Prop Key="AutoCallBack.Command" Value="openCustomLineRecs" />
</PXToolBarButton>
The Visibility could be set through the Action
protected virtual void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
if (e.Row == null) return;
this.openCustomLineRecs.SetVisible(!Base.IsTransferOrder);
}
Try this.
protected virtual void SOOrder_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PXRowSelected BaseEvent)
{
BaseEvent?.Invoke(sender, e);
SOOrder row = e.Row as SOOrder;
if (row == null)
return;
if(row.OrderType == SOOrderTypeConstants.TransferOrder)
this.YOURBUTTONNAME.SetVisible(false);
else
this.YOURBUTTONNAME.SetVisible(true);
}
Related
I have my spring integration http outbound gateway something like this.I am using my own rest template for pooling connection with ssl.I was getting 500 with french character hence I am injecting both UTF-8 and supported media type to message converter.Now Before I was injecting my own request factory and default rest template After injecting both then it started accepting french characters.Now when i changed to use my own rest template it don't accept message converter and when i try to inject this to my rest template I get this exception
Cause is - Could not write request: no suitable HttpMessageConverter found for request type [java.lang.String] and content type [text/plain;charset=UTF-8]
This worked for all request
<int-http:outbound-gateway id='batch-http' header-mapper="headerMapper"
request-channel='toHttp'
request-factory="requestFactory"
message-converters="batchHTTPConverter"
url-expression="payload.contains('${filterAttribute}') ? '${url1}' : '${url2}'" http-method="${httpMethod}"
expected-response-type='java.lang.String' charset='${charset}'
reply-timeout='${replyTimeout}' reply-channel='output'>
</int-http:outbound-gateway>
<beans:bean id="batchHTTPConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:constructor-arg index="0" value="UTF-8"/>
<beans:property name="supportedMediaTypes" value = "application/json;UTF-8" />
</beans:bean>
<beans:bean id="requestFactory" class="test.batch.httpclient.CustomClientHttpRequestFactory">
<beans:constructor-arg ref="verifier"/>
</beans:bean>
<beans:bean id="verifier"
class="batch.NullHostnameVerifier">
</beans:bean>
This is not working for french or any input request
<header-filter input-channel="input"
output-channel="inputX" header-names="x-death"/>
<service-activator input-channel="inputX" ref="gw" />
<gateway id="gw" default-request-channel="toHttp" default-reply-timeout="0" error-channel="errors" />
<beans:bean id="inputfields" class="testbatch.httpclient.HTTPInputProperties">
<beans:property name="nonRetryErrorCodes" value="${nonRetryErrorCodes}"/>
</beans:bean>
<beans:bean id="responseInterceptor" class="testbatch.httpclient.ResponseInterceptor">
<beans:property name="inputProperties" ref="inputfields" />
</beans:bean>
<chain input-channel="errors" output-channel="output">
<!-- examine payload.cause (http status code etc) and decide whether
to throw an exception or return the status code for sending to output -->
<header-filter header-names="replyChannel, errorChannel" />
<transformer ref="responseInterceptor" />
</chain>
<int-http:outbound-gateway id='batch-http' header-mapper="headerMapper"
request-channel='toHttp'
rest-template="batchRestTemplate"
url-expression="payload.contains('${filterAttribute}') ? '${url1}' : '${url2}'" http-method="${httpMethod}"
expected-response-type='java.lang.String' charset='${charset}'
reply-timeout='${replyTimeout}' reply-channel='output'>
</int-http:outbound-gateway>
<beans:bean id="batchHTTPConverter" class="org.springframework.http.converter.StringHttpMessageConverter" >
<beans:constructor-arg index="0" value="UTF-8"/>
<beans:property name="supportedMediaTypes" value = "application/json;UTF-8" />
</beans:bean>
<beans:bean id="batchRestTemplate" class="testbatch.httpclient.BatchRestTemplate" >
<beans:property name="batchHTTPConverter" ref="batchHTTPConverter"/>
</beans:bean>
<beans:bean id="requestFactory"
class="testbatch.httpclient.CustomClientHttpRequestFactory">
<beans:constructor-arg ref="verifier"/>
</beans:bean>
<beans:bean id="verifier"
class="testbatch.httpclient.NullHostnameVerifier">
</beans:bean>
<beans:bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper"
factory-method="outboundMapper">
<beans:property name="outboundHeaderNames" value="${mapHeaders}"/>
<beans:property name="userDefinedHeaderPrefix" value=""/>
</beans:bean>
<channel id="output" />
<channel id="input" />
<channel id="inputX" />
<channel id="toHttp" />
</beans:beans>
My rest template
public class BatchRestTemplate extends RestTemplate{
private static final Logger LOGGER = LoggerFactory
.getLogger(BatchRestTemplate.class);
private StringHttpMessageConverter batchHTTPConverter;
public StringHttpMessageConverter getBatchHTTPConverter() {
return batchHTTPConverter;
}
public void setBatchHTTPConverter(StringHttpMessageConverter batchHTTPConverter) {
this.batchHTTPConverter = batchHTTPConverter;
}
public BatchRestTemplate() {
super(createBatchHttpRequestFactory());
List<HttpMessageConverter<?>> messageConverters= new ArrayList<HttpMessageConverter<?>>();
messageConverters.addAll(getMessageConverters());
messageConverters.add(getBatchHTTPConverter());
super.setMessageConverters(messageConverters);
}
private static ClientHttpRequestFactory createBatchHttpRequestFactory() {
CloseableHttpClient httpClient;
HttpComponentsClientHttpRequestFactory httpRequestFactory;
final int timeout = 3000;
SSLConnectionSocketFactory socketFactory;
try {
socketFactory = new SSLConnectionSocketFactory(
SSLContext.getDefault(),
new String[] {"TLSv1"},
null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", socketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
cm.setMaxTotal(700);
cm.setDefaultMaxPerRoute(300);
cm.closeExpiredConnections();
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).build();
httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return httpRequestFactory;
}
catch (Exception e) {
LOGGER.debug("error exception", e);
}
return null;
}
}
You have a bug in your own code:
public BatchRestTemplate() {
..........
messageConverters.add(getBatchHTTPConverter());
..........
}
But... There is no batchHTTPConverter yet!. It will appear there only after setBatchHTTPConverter().
In other words you can't use the property from the constructor because setters are called latter after the object instantiating.
I'm using JPA and Hibernate for persistence, with some autoconfiguration help from Spring Boot. I'm running a JUnit test which saves some record in the JPA Repository. Then it instantiates a new Spring-managed-thread, and it's run by ThreadPoolTaskExecutor. That thread will try to get that previously added record with no success.
Here is the relevant code of the test and the runnable thread:
public class RtmpSpyingTests extends AbstractTransactionalJUnit4SpringContextTests {
#Autowired
ThreadPoolTaskExecutor rtmpSpyingTaskExecutor;
#Autowired
ApplicationContext ctx;
#Autowired
RtmpSourceRepository rtmpRep;
#Test
public void test() {
RtmpSource rtmpSourceSample = new RtmpSource("test");
rtmpRep.save(rtmpSourceSample);
rtmpRep.flush();
List<RtmpSource> rtmpSourceList = rtmpRep.findAll(); // Here I get a list containing rtmpSourceSample
RtmpSpyingTask rtmpSpyingTask = ctx.getBean(RtmpSpyingTask.class,
"arg1","arg2");
rtmpSpyingTaskExecutor.execute(rtmpSpyingTask);
}
}
public class RtmpSpyingTask implements Runnable {
#Autowired
RtmpSourceRepository rtmpRep;
String nameIdCh;
String rtmpUrl;
public RtmpSpyingTask(String nameIdCh, String rtmpUrl) {
this.nameIdCh = nameIdCh;
this.rtmpUrl = rtmpUrl;
}
public void run() {
// Here I should get a list containing rtmpSourceSample, but instead of that
// I get an empty list
List<RtmpSource> rtmpSource = rtmpRep.findAll();
}
}
So, after I have inserted the rtmpSourceSample object, I can check it's been inserted from the test method, it is indeed on the rtmpSourceList list. However, when I do the same from the thread, what I get is an empty list.
Here is the JPA/Hibernate configuration in my spring-context.xml configuration file:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MVCC=true" />
<property name="username" value="user" />
<property name="password" value="user" />
</bean>
<!-- Define the JPA transaction manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<constructor-arg ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="vendorAdaptor" />
<property name="packagesToScan" value="guiatv.persistence.domain" />
</bean>
<bean id="abstractVendorAdaptor" abstract="true">
<property name="generateDdl" value="true" />
<property name="database" value="H2" />
<property name="showSql" value="false" />
</bean>
<bean id="entityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="vendorAdaptor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
parent="abstractVendorAdaptor">
</bean>
<context:annotation-config />
<tx:annotation-driven />
<context:component-scan base-package="guiatv.persistence" />
Note that the persistence-unit.xml is not needed since I'm using Spring Boot.
And finally this is the xml configuration of the taskexecutor bean and the runnable thread:
<bean id="rtmpSpyingTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="5" />
<property name="queueCapacity" value="5" />
</bean>
<bean id="rtmpSpyingTask" class="guiatv.realtime.rtmpspying.RtmpSpyingTask"
scope="prototype">
<constructor-arg ref="rtmpSpyingTaskExecutor" />
</bean>
I've been looking for topics about this problematic Spring's persistence and threading combination. One of the solutions I've found so far is to create some #Service annotated class with a #Transactional method, which I am supposed to call from my run() method. It does not work for me.
Some other solutions involve the use of the EntityManager or some other Hibernate dependent bean, instead of querying the JPA Repository directly. Doesn't work too.
So, any solution that could fit my needs? Thank you!
SOLUTION (from cproinger):
Create a #Service annotated class:
#Service
public class AsyncTransactionService {
#Autowired
RtmpSourceRepository rtmpRep;
#Transactional(readOnly = true)
public List<RtmpSource> getRtmpSources() {
return rtmpRep.findAll();
}
#Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertRtmpSource(RtmpSource rtmpSource) {
rtmpRep.save(rtmpSource);
}
}
Then, I autowire that AsyncTransactionService from both the JUnit test, and the Runnable class. In order to insert the record from JUnit test I invoke insertRtmpSource(), and then I get the records from my thread by calling getRtmpSources().
I tried to do it without the #Service. This is, by putting an annotated insertRtmpSource() method on my JUnit class and a getRtmpSources() method on my Runnable class, but it did not work.
Thank you for you quick response cproinger!
the thread does not see the record because the test runs inside a transaction that is not committed yet. since the transaction is bound to the executing thread the task that is forked does not use the same transaction. in order for this to work the insert must run in a method that is annotated with #Transactional(propagation = REQUIRES_NEW). please note that transactional rollback will not work then though
I have implemented the DynamicFtpChannelResolver found in the spring integration samples in order to allow dynamic FTP locations in my integration app.
As part of the outbound adapter I have added an advice chain. The FtpCompleteAdvice requires access to an existing service bean but at runtime this is not injected presumably because the context is dynamically created.
Is there a way for autowiring to work or another way to get access to this service bean?
Here is an extract of the xml:
<int:channel id="toFtpChannel" />
<bean id="ftpClientFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${host}" />
<property name="port" value="${port}" />
<property name="user" value="${user}" />
<property name="password" value="${password}" />
</bean>
<int-sftp:outbound-channel-adapter id="ftpOutbound" session-factory="ftpClientFactory" channel="toFtpChannel" remote-directory="${remote.directory}" remote-file-separator="/" remote-filename-generator-expression="headers.filename">
<int-sftp:request-handler-advice-chain>
<bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="retryTemplate" ref="retryTemplate" />
</bean>
<bean class="com.bstonetech.ptms.integration.util.FtpCompleteAdvice">
<property name="interfaceType" value="OUTBOUND" />
<property name="interfaceName" value="TEST" />
</bean>
</int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="3" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="maxInterval" value="600000" />
<property name="initialInterval" value="3000" />
<property name="multiplier" value="2" />
</bean>
</property>
</bean>
public class FtpCompleteAdvice extends AbstractRequestHandlerAdvice {
#Autowired
private IEmailUtilities emailUtilities;
#Autowired
private IFileService fileService;
private String interfaceType;
private String interfaceName;
public void setInterfaceType(String interfaceType) {
this.interfaceType = interfaceType;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
#Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
Object result = callback.execute();
String filename = (String)message.getHeaders().get("filename");
//insert ftp row into file_ctl
fileService.insertFtpFile(filename, interfaceName, interfaceType, new Date());
//send email to confirm ftp
emailUtilities.afterFtp(filename, interfaceName);
return result;
}
}
You need to make the new context a child of the main context that has those beans. This is discussed in the forum posts referenced in the sample's README, when using a similar technique for inbound endpoints.
Then, any beans in the parent context are available for wiring.
I am trying to create a generic Error Handling process for All message Handlers that will be used in my SI flow. This will,
1. Retry on Connection Exception.
2. Stop the SI flow using Circuit Breaker.
3. Rollback the failed message to the channel.
I have achieved the Retry and Circuit Break Functionality. But, I am unable to rollback message to the channel.
I tried using transaction advice. But it does not work.
Here is the code.
<bean id="retryAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="retryTemplate">
<bean class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="2000" />
<property name="multiplier" value="2" />
</bean>
</property>
</bean>
</property>
<property name="recoveryCallback">
<bean
class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="recoveryChannel" />
</bean>
</property>
<property name="retryStateGenerator">
<bean
class="org.springframework.integration.handler.advice.SpelExpressionRetryStateGenerator">
<constructor-arg value="headers['uniqueId']" />
</bean>
</property>
</bean>
<int:channel id="recoveryChannel" />
<int:transformer id="defaultTransformer" input-channel="recoveryChannel"
output-channel="loggerChannel" ref="defaultTransformer" method="transform">
</int:transformer>
<int:logging-channel-adapter id="loggerChannel"
level="INFO" log-full-message="true" auto-startup="true">
</int:logging-channel-adapter>
<bean id="defaultTransformer"
class="com.bestbuy.ingestion.foundation.core.util.DefaultTransformer" />
<bean id="circuitBreakerAdvice"
class="org.springframework.integration.handler.advice.RequestHandlerCircuitBreakerAdvice">
<property name="threshold" value="2" /> <!-- close after 2 failures -->
<property name="halfOpenAfter" value="60000" /> <!-- half open after 15 seconds -->
</bean>
<tx:advice id="txansactionAdvice" transaction-manager="transactionManager">
</tx:advice>
What type of Transaction Manager I need to use.
I may be using different message Handlers, on different data source.
Here is how I add these advises to the Message Handlers.
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
logger.error("called for bean id :: "+beanName+" with bean class "+bean.getClass().getName());
if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
logger.error("************ Bean "+beanName+" is instance of AbstractSimpleMessageHandlerFactoryBean **********");
}
if(bean instanceof ConsumerEndpointFactoryBean){
logger.error("Bean is of type ConsumerEndpointFactoryBean");
return populateRequestHandlerAdviceChain((ConsumerEndpointFactoryBean)bean);
}
if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
logger.error("Bean is of type AbstractSimpleMessageHandlerFactoryBean");
return populateRequestHandlerAdviceChain((AbstractSimpleMessageHandlerFactoryBean<?>)bean);
}
return bean;
}
private Object populateRequestHandlerAdviceChain(ConsumerEndpointFactoryBean bean){
ArrayList<Advice> list = new ArrayList<Advice>();
logger.error("Adding Retry Advice");
list.add((Advice)factory.getBean("retryAdvice"));
logger.error("Adding Cricuit Breaker Advice");
list.add((Advice)factory.getBean("circuitBreakerAdvice"));
logger.error("Adding Transactional Advice");
list.add((Advice)factory.getBean("txansactionAdvice"));
bean.setAdviceChain(list);
return bean;
}
If the bean of type ConsumerEndpointFactoryBean I add these advices. I need transaction management in all these Handlers.
First of all: since your txansactionAdvice is nested to the retryAdvice you rollback here the each retry.
From other side it isn't clear why you apply the circuitBreakerAdvice for each retry. I'd say this patter would be better to use 'around' retryAdvice.
And the txansactionAdvice should on top. So, it might look like this:
txansactionAdvice
circuitBreakerAdvice
retryAdvice
And one more point: your transaction won't be rolled back, bacause your use recoveryCallback, which just sends ErrorMessage and strangles the Exception.
HTH and you'll change your mind on the matter.
I was going through following post Spring login form example and many other post of Spring Security to create a login example but I was not able to prepare any simple example.
I was trying to incorporate solution from this post Spring login form example
but problem is that I want Hibernate session factory to be injected in the UserDAO so that I can write query to get userName from table. #Autowire is not working
so I used
<context:annotation-config />
<context:component-scan
base-package="com.tcs.ceg" />
but now i am getting runtime exception as cannot autowire sessionFactory as no matching bean found.
But a bean with this name I have created in my applicationContext.xml .
Can anyone tell me how can I inject sessionFactory?
my application-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
">
<context:annotation-config />
<context:component-scan
base-package="com.tcs.ceg" />
<global-method-security pre-post-annotations="enabled" />
<http pattern="/css/**" security="none"/>
<http pattern="/images/**" security="none"/>
<http pattern="/js/**" security="none"/>
<http pattern="/index.jsp" security="none"/>
<http pattern="/loggedout.jsp" security="none"/>
<http use-expressions="true">
<!--
Allow all other requests. In a real application you should
adopt a whitelisting approach where access is not allowed by default
-->
<intercept-url pattern="/**" access="isAuthenticated()" />
<form-login />
<logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
<remember-me />
</http>
<beans:bean id="myUserService" class="com.tcs.ceg.services.impl.UserServiceImpl" />
<authentication-manager>
<authentication-provider user-service-ref="myUserService" />
</authentication-manager>
</beans:beans>
and my applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" >
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan
base-package="com.tcs.ceg" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
<jee:jndi-lookup id="dataSource1" jndi-name="jdbc/PmdDS"/>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="1000000000000"/>
</bean>
</beans>
Code for UserServiceImpl
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.tcs.ceg.dao.intrface.UserDao;
#Service
public class UserServiceImpl implements UserDetailsService {
#Autowired
private transient UserDao userDao;//userDao is null
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#Override
#Transactional
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// TODO Auto-generated method stub
User user=null;
try{
user = userDao.getUser(username);
}catch(Exception err){
err.printStackTrace();
}
if (user != null) {
// convert roles
// initialize user
return user;
} else {
throw new UsernameNotFoundException("No user with username '" + username + "' found!");
}
}
}
Code for UserDaoImpl
import java.util.ArrayList;
import java.util.Collection;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Repository;
import com.tcs.ceg.dao.intrface.UserDao;
import com.tcs.ceg.util.lib.DbComparisonException;
#Repository
public class UserDaoimpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;//sessionfactory is null
#Override
public User getUser(String username) throws DbComparisonException {
String password = "rajesh";
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new GrantedAuthorityImpl("admin"));
User user = new User(username, password, enabled,
accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
return user;
}
}
Please note i havent written following line in UserDaoimpl because sessionFactory is null
sessionFactory.getCurrentSession().createQuery("from User").list();//throws null pointer exception
I think that the sessionFactory attribute of your DAO must be of type LocalSessionFactoryBean.
EDIT :
In your applicationContext.xml file, you have declared this bean :
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
</props>
</property>
</bean>
which is a org.springframework.orm.hibernate3.LocalSessionFactoryBean.
Then, in your DAO, sessionFactory is a org.hibernate.SessionFactory.
So I think that Spring is unable to autowire your bean in the DAO since it is not the same type.