Can't get view scope working for my ManagedBeans - spring

I'm using JSF 2 with Spring 3 in my project and until now, I'm just using request and session scopes. I want to use view scope for some of my JSF beans (for multiple reasons).
The problem is that the JSF ManagedBean have to implement Serializable interface, and all of its properties.
I have some difficulty to get the Spring beans Serializables (ex. : VilleService...) because it continue to ask for more classes to be serializable even if it's not possible (hibernate classes or mysql ...).
Here is an example :
public class VilleBean extends BaseBean implements Serializable {
private Ville ville;
private List<Ville> villes;
private VilleService villeService;
private PaysService paysService;
private Pays pays;
private List<Pays> payss;
private PojoConverter<Pays> paysConverter = null;
public VilleBean() {
ville = new Ville();
pays = new Pays();
}
public void setVilleService(VilleService villeService) {
this.villeService = villeService;
}
public void setPaysService(PaysService paysService) {
this.paysService = paysService;
}
// getters and setters for attributes : ville, pays, villes, payss
public void addVilleAction() {
ville.setPays(pays);
villeService.create(ville);
}
public void deleteVilleAction(Ville ville) {
villeService.delete(ville);
villes = villeService.readAll();
}
public void updateVilleAction() {
ville.setPays(pays);
villeService.update(ville);
}
public PojoConverter<Pays> getPaysConverter() {
this.paysConverter = new PojoConverter<Pays>(getPayss());
return this.paysConverter;
}
}
public abstract class BaseBean {
protected FacesContext context = FacesContext.getCurrentInstance();
protected MessageFactory msg;
protected static final Logger log = Logger.getLogger(BaseBean.class);
}
POJO :
public class Ville implements Serializable {
private int id;
private String intitule;
private Pays pays;
// setters and getters
}
public class Pays implements Serializable {
private int id;
private String intitule;
// setters and getters
}
Service interface :
public interface VilleService extends ICrud<Ville> {
}
Service Impl :
public class VilleServiceBase implements VilleService {
private IDao<Ville> dao;
// getter and setter for dao
#Override
public List<Ville> readAll() throws Exception {
return dao.readAll();
}
#Override
public void create(Ville entity) throws Exception {
dao.create(entity);
}
//****
Util :
public interface ICrud<T> {
public java.util.List readAll() throws Exception;
public void create(T entity) throws Exception;
public void update(T entity) throws Exception;
//****
public interface IDao<T> {
public java.util.List<T> readAll();
public T create(T entity);
//****
public class DaoBase<T> extends org.springframework.orm.hibernate3.support.HibernateDaoSupport implements IDao<T> {
private final Class<T> type;
public DaoBase(Class<T> type) {
this.type = type;
}
#Override
public T load(int id) {
return (T) this.getHibernateTemplate().get(this.type, new Integer(id));
}
#Override
public T create(T entity) {
//****
this.getHibernateTemplate().save(entity);
return entity;
}
Spring beans : spring.xml :
<!-- Ville Service Implementation -->
<bean id="villeServiceBase" class="commun.ref.crud.VilleServiceBase">
<property name="dao">
<ref bean="villeDao"/>
</property>
</bean>
<!-- Ville Service Proxy -->
<bean id="villeService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="villeServiceBase"/>
</property>
<property name="proxyInterfaces">
<value>commun.ref.crud.VilleService</value>
</property>
<property name="interceptorNames">
<list>
<value>manageableServiceTransactionInterceptor</value>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
<bean id="villeDao" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="smile.util.DaoBase">
<constructor-arg>
<value>commun.ref.Ville</value>
</constructor-arg>
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
</property>
<property name="proxyInterfaces">
<value>smile.util.IDao</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
JSF configuration : faces-config.xml :
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
******
<managed-bean>
<managed-bean-name>villeBean</managed-bean-name>
<managed-bean-class>commun.ref.ui.VilleBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
<managed-property>
<property-name>villeService</property-name>
<value>#{villeService}</value>
</managed-property>
<managed-property>
<property-name>paysService</property-name>
<value>#{paysService}</value>
</managed-property>
</managed-bean>
Can you tell me please, what to do to get this to work.

On fields which you don't want to be serialized or they can't be serialized use transient modifier. For example:
private transient VilleService villeService;
As you are using MyFaces add this parameter to web.xml:
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>false</param-value>
</context-param>
As I know this parameter is default false in Mojarra. This will disable serialization of state in session.

If you don't use session passivation you may use transient attribute for non-serializable fields.
For example:
private transient Connection connection;

Related

Annotation #Transactional does not working

I am trying to use the annotation #Transactional to access my MySQL using Hibernate, Spring and JSF. My problem is:
When I use the annotation #Transactional at my managedBean to make a query I got this error:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:65)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at br.com.rpg.DAO.AbstractDAO.getCurrentSession(AbstractDAO.java:14)
at br.com.rpg.DAO.CountryDAO.findAll(CountryDAO.java:14)
at br.com.rpg.managedBeans.SignupBean.init(SignupBean.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
I don't know what I'm doing wrong. My code and xml config is:
application-config.xml
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="br.com.rpg.DO" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<context:component-scan base-package="br.com.rpg" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My MB
#Named
#Scope("request")
public class SignupBean implements Serializable {
private static final long serialVersionUID = 1787096549063029840L;
#Inject
private CountryDAO country;
#Inject
private UserDAO user;
private Map<String, Integer> countries;
private Integer selected;
private String username;
private String password;
#PostConstruct
#Transactional
public void init() {
List<CountryDO> findAll = country.findAll();
countries = new HashMap<String, Integer>();
for (CountryDO countryDO : findAll) {
countries.put(countryDO.getName(), countryDO.getId());
}
}
public Map<String, Integer> getCountries() {
return countries;
}
public void setCountries(Map<String, Integer> countries) {
this.countries = countries;
}
public Integer getSelected() {
return selected;
}
public void setSelected(Integer selected) {
this.selected = selected;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
My Country DAO has the #Named annotation. Someone could help me?
Thx.
you have applied #PostConstruct and #Transactional on init method. init method would be called before applying any AOP Proxy interceptor is applied because of #PostConstruct. Hence at the time of invoking init there is no transaction proxy applied. if you need to call init method on Application startup use ApplicationEvent

Spring autowiring not working, getting `applicationDao` as null

Below are my classes and xml:
#Component
#Service("ApplicationService")
public class ApplicationServiceImpl implements ApplicationService{
public ApplicationDao getApplicationDao() {
return applicationDao;
}
public void setApplicationDao(ApplicationDao applicationDao) {
this.applicationDao = applicationDao;
}
#Autowired
private ApplicationDao applicationDao;
// some methods..
}
#Service
public interface ApplicationService {
// methods...
}
#Component
#Repository("ApplicationDao")
public class ApplicationDaoImpl implements ApplicationDao {
#Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// other methods...
}
public interface ApplicationDao {
// methods...
}
xml file:
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven/>
<context:component-scan base-package="com" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- <property name="dataSource" ref="dataSource" /> -->
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<bean id="ApplicationDao" class="com.dao.impl.ApplicationDaoImpl"/>
<bean id="ApplicationService" class="com.service.impl.ApplicationServiceImpl"/>
Here autowiring is not working.in ApplicationServiceImpl, I am getting applicationDao as null. Have not tested sessionFactory in ApplicationDaoImpl.
I know that if I am using #Component then bean declaration in xmnl is not required.
You should not instantiate service like that..
At the time of application loading, spring container will create all instances defined in spring.xml or annotated classes and it's dependencies..
So you have to access them with the following example code..
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
ApplicationService applicationService = (ApplicationService) applicationContext.getBean("ApplicationService");
Since ApplicationService is having property that is ApplicationServiceDAOImpl, it's already been created by spring container and will return you..
But in case of directly instantiating manually by you, you are just creating instance of ApplicationService but not for ApplicationServiceDAOImpl.. so it obviously returns null
I'm currently using this approach only to access beans or services..
update for comment
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
applicationContext = arg0;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
Hope it helps,
try a change like this:
import org.springframework.beans.factory.annotation.Qualifier;
#Autowired
#Qualifier("ApplicationDao")
private ApplicationDao applicationDao;
this give spring a hint.
If you are using annotations in your application, you should denote it using a tag :
<mvc:annotation-driven />
Add this line in application context xml above component scan tag.
Also, if you are using annotations, remove ApplicationDao and ApplicationService bean declarations from xml.
And don't mark you service and dao classes with both #Component and #Service or #Repository annotations. No need to mark them #Component there. Remove it.

UsernameTokenValidator Can not #Autowired Dao

I have a Spring-ws and i am using Apahce-wss4j for spring-ws authentication. I want to use my Dao class in my custom TokenValidator class. But there was an exception can not #Autowired my Dao class. Here is my code
applicationContext.xml
<bean id="myWssConfig" class="tr.com.xxx.services.MyWssConfig"/>
<bean id="kepDBDAO" class="tr.com.xxx.dao.KepDBDAOImpl"/>
<bean id="ssha" class="tr.com.xxx.utils.SSHA"/>
<bean id="memberStatusService" class="tr.com.xxx.services.MemberStatusServiceImpl"/>
<bean id="myUsernameTokenValidator" class="tr.com.xxx.services.MyUsernameTokenValidator">
<property name="kepDBDAO" ref="kepDBDAO"/>
</bean>
<sws:interceptors>
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="UsernameToken"/>
<property name="validationCallbackHandler" ref="callbackHandler"/>
<property name="wssConfig">
<ref bean="myWssConfig"/>
</property>
</bean>
</sws:interceptors>
Here is MyWssConfig.java
#Component("myWssConfig")
public class MyWssConfig extends WSSConfig {
public MyWssConfig() {
setValidator(WSSecurityEngine.USERNAME_TOKEN, MyUsernameTokenValidator.class);
setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
}
}
And here is MyUsernameTokenValidator.java
#Component
public class MyUsernameTokenValidator extends UsernameTokenValidator {
private static final Logger LOGGER = LoggerFactory
.getLogger(MyUsernameTokenValidator.class);
#Autowired
private KepDBDAO kepDBDAO;
#Transactional
protected void verifyPlaintextPassword(UsernameToken usernameToken, RequestData data) throws WSSecurityException {
if (usernameToken != null && usernameToken.getPassword() != null) {
byte[] saltValue = null;
kepDBDAO.getWsUsers("basvuru");
String hashPassword = null;
try {
hashPassword = SSHA.calculateSSHA256(saltValue, usernameToken.getPassword());
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.toString(), e);
} catch (IOException e) {
LOGGER.error(e.toString(), e);
}
usernameToken.setPassword(hashPassword);
super.verifyDigestPassword(usernameToken, data);
}
}
public KepDBDAO getKepDBDAO() {
return kepDBDAO;
}
public void setKepDBDAO(KepDBDAO kepDBDAO) {
this.kepDBDAO = kepDBDAO;
}
}
Couldn't #Autowired my KepDBDAO when I call webservice in SOAPUI.
Help me please.. THank you all guys.
Try this:
1. In applicationContext:
<context:component-scan base-package="tr.com.xxx.dao"/>
<context:component-scan base-package="package for MyUsernameTokenValidator"/>
remove these beans:
kepDBDAO, myUsernameTokenValidator
2. Remove setter and getter for KepDBDAO in MyUsernameTokenValidator
3. Make sure KepDBDAOImpl is marked as #Service
I solved my problem.
#Component("myWssConfig")
public class MyWssConfig extends WSSConfig {
#Autowired
private MyUsernameTokenValidator myUsernameTokenValidator;
//
#PostConstruct
public void myInit() {
setValidator(WSSecurityEngine.USERNAME_TOKEN, myUsernameTokenValidator);
setRequiredPasswordType(WSConstants.PASSWORD_TEXT);
}
}

Spring not dynamic Switch DataSource

Why use AbstractRoutingDataSource can not dynamic switch DataSource
This is the configuration information
public class DynamicSwitch {
public static final ThreadLocal<String> local=new ThreadLocal<String>();
public static void setDB(String id){
local.set(id);
}
public static String getDB(){
return local.get();
}
public static void removeDB(){
local.remove();
}
}
public class DynamicSource extends AbstractRoutingDataSource implements InitializingBean{
#Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return DynamicSwitch.getDB();
}
}
<bean id="dynamic" class="com.aware.DynamicSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="1" value-ref="dataSource"></entry>
<entry key="2" value-ref="localdataSource"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource"></property>
</bean>
<bean id="methodService" class="com.test.service.MethodServiceImpl">
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
<bean id="test" class="com.test.Test" scope="prototype"></bean>
public class Test2 extends ActionSupport{
public String execute() throws Exception {
// TODO Auto-generated method stub
DynamicSwitch.setDB("2");
MethodService methodService=(MethodService)ApplicationAware.getBean("methodService");
Map<String, String> map=new HashMap<String, String>();
List list=methodService.testList("Service_ks_missionSpace.getService_ks_missionList", map);
System.out.println(list.size());
return SUCCESS;
}
Invoke DynamicSwitch.setDB("2") find can not Switch DataSource.
DataSource or to default dataSource
Why

Create spring beans, based on a comma-separated list of classes

Is there a way in Spring to create a collection, or array, of beans, based on a comma-separated list of classes. For example:
package mypackage;
public class Bla {
private Set<MyBean> beans;
public void setBeans(Set<MyBean> beans) {
this.beans = beans;
}
}
With the application context:
<bean id="bla" class="mypackage.Bla">
<property name="beans">
<set>
<bean class="mypackage.Bean1, mypackage.Bean2" />
</set>
</property>
</bean>
Preferably the beans are all initialized and wired from the context, leaving the code as simplistic as possible, is this possible?
Use a combination of ApplicationContextAware and ApplicationListener:
public class BeanInitializer implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
private ApplicationContext context;
private List<Class<?>> beanClasses;
public void onApplicationEvent(final ContextRefreshedEvent event) {
final AutowireCapableBeanFactory beanFactory = this.context.getAutowireCapableBeanFactory();
for (final Class<?> beanClass : this.beanClasses) {
beanFactory.autowire(beanClass, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
}
}
public void setApplicationContext(final ApplicationContext context) throws BeansException {
this.context = context;
}
public void setBeanClasses(final List<Class<?>> beanClasses) {
this.beanClasses = beanClasses;
}
}
in your spring config, do this:
<bean class="com.yourcompany.BeanInitializer">
<property name="beanClasses">
<list>
<value>com.yourcompany.Type1</value>
<value>com.yourcompany.Type2</value>
<value>com.yourcompany.Type3</value>
</list>
</property>
</bean>
Edited: Actually, if you want comma separated, it will probably be more like this:
<bean class="com.yourcompany.BeanInitializer">
<property name="beanClasses"
value="com.yourcompany.Type1,com.yourcompany.Type2,com.yourcompany.Type3" />
</bean>
I don't know if there is a built-in property editor that converts a comma delimited string to a list of classes but if not you can either create one yourself or change your setter method to accept a string and parse the string yourself

Resources