Spring DAO没有注入到JSF托管bean中 [英] Spring DAO is not injected in JSF managed bean

查看:115
本文介绍了Spring DAO没有注入到JSF托管bean中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在演示应用程序中使用JSF2 + Spring3.1 + Hibernate4,我将使用批注创建会话工厂,但是我的DAO类未在Jsf Managed Bea类中初始化,因此我得到Null指针异常。
My applicationContext.xml

 < beans xmlns =http:// www .springframework.org / schema / beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xmlns:tx =http://www.springframework .org / schema / tx
xmlns:context =http://www.springframework.org/schema/context
xsi:schemaLocation =http://www.springframework.org/schema / beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http: //www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/模式/上下文/弹簧上下文3.0.xsd>

< context:annotation-config>< / context:annotation-config>



<! - 数据源声明 - >
< bean id =DataSourceclass =com.mchange.v2.c3p0.ComboPooledDataSource>
< property name =driverClassvalue =org.postgresql.Driver/>
< property name =jdbcUrlvalue =jdbc:postgresql:// localhost:5432 / postgres/>
< property name =uservalue =postgres/>
< property name =passwordvalue =hariom/>
< property name =maxPoolSizevalue =10/>
< property name =maxStatementsvalue =0/>
< property name =minPoolSizevalue =5/>
< / bean>

<! - 会话工厂声明 - >
< bean id =SessionFactoryclass =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =DataSource/>
< property name =annotatedClasses>
< list>
< value> com.otv.model.User< / value>
< / list>
< / property>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> org.hibernate.dialect.PostgreSQLDialect< / prop>
< prop key =hibernate.show_sql> true< / prop>
< /道具>
< / property>
< property name =packagesToScanvalue =com.otv.user>< / property>
< / bean>


<! - 事务管理器已定义 - >
< bean id =txManagerclass =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =SessionFactory/>
< / bean>


<! - 启用基于注释的事务行为配置 - >
< tx:annotation-driven transaction-manager =txManager/>

< / beans>

UserDAO.java class

  package com.otv.user.dao; 

import java.util.List;

import com.otv.model.User;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/ **
*
*用户DAO
*
* @author onlinetechvision.com
* @since 2012年3月25日
* @version 1.0.0
*
* /

@Repository
@Transactional
public class UserDAO {

@Autowired
private SessionFactory sessionFactory;
$ b $ **
*获取Hibernate会话工厂
*
* @return SessionFactory - Hibernate会话工厂
* /
/ * public SessionFactory getSessionFactory(){
return sessionFactory;
}

* // **
*设置Hibernate会话工厂
*
* @param SessionFactory - Hibernate会话工厂
* / / *
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
} * /



/ **
*添加用户
*
* @param用户用户
* /
public void addUser(User user){
sessionFactory.getCurrentSession()。save(user);
}

/ **
*删除用户
*
* @param用户用户
* /
public void deleteUser (用户用户){
sessionFactory.getCurrentSession()。delete(user);

$ b $ **
更新用户
*
* @param用户用户
* /
public void updateUser (用户用户){
sessionFactory.getCurrentSession()。update(user);
}

/ **
*获取用户
*
* @param int用户标识
* @return用户
* /
public User getUserById(int id){
List list = sessionFactory.getCurrentSession()
.createQuery(from User where id =?)
.setParameter(0 ,id).list();
return(User)list.get(0);

$ b / **
*获取用户列表
*
* @return列表 - 用户列表
* /
公开列表<用户> getUsers(){
List list = sessionFactory.getCurrentSession()。createQuery(from User)。list();
返回列表;
}

}

AND my managedBean class

  package com.otv.managed.bean; 

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;

import com.otv.model.User;
import com.otv.user.dao.UserDAO;
import com.otv.user.service.IUserService;

/ **
*
*用户管理的Bean
*
* @author onlinetechvision.com
* @since 25 Mar 2012
* @version 1.0.0
*
* /
@ManagedBean(name =userMB)
@RequestScoped
public class UserManagedBean implements Serializable {

private static final long serialVersionUID = 1L;
private static final String SUCCESS =success;
private static final String ERROR =error;

// Spring User Service被注入...


List< User>用户列表;

private int id;
私人字符串名称;
私人字符串姓氏;

@Autowired
private UserDAO userDAO;
/ **
*添加用户
*
* @return字符串 - 响应消息
* /
public String addUser(){
尝试{
User user = new User();
user.setId(getId());
user.setName(getName());
user.setSurname(getSurname());
userDAO.addUser(user);
返回SUCCESS;
} catch(DataAccessException e){
e.printStackTrace();
}

return ERROR;

$ b / **
*重置字段
*
* /
public void reset(){
this。 SETID(0);
this.setName();
this.setSurname();

$ b / **
*获取用户列表
*
* @return列表 - 用户列表
* /
公开列表<用户> getUserList(){
userList = new ArrayList< User>();
userList.addAll(userDAO.getUsers());
返回userList;
}

/ **
*获取用户服务
*
* @return IUserService - 用户服务
* /

/ **
*设置用户列表
*
* @param列表 - 用户列表
* /
public void setUserList(List< User> userList ){
this.userList = userList;

$ b / **
*获取用户标识
*
* @return int - 用户标识
* /
public int getId(){
return id;

$ b $ **
*设置用户标识
*
* @param int - 用户标识
* /
public void setId(int id){
this.id = id;
}

/ **
*获取用户名
*
* @return字符串 - 用户名
* /
public String getName(){
return name;

$ b / **
*设置用户名
*
* @param字符串 - 用户名
* /
public void setName(String name){
this.name = name;
}

/ **
*获取用户姓氏
*
* @return字符串 - 用户姓氏
* /
public String getSurname(){
return surname;

$ b $ **
*设置用户姓名
*
* @param字符串 - 用户姓名
* /
public void setSurname(String surname){
this.surname = surname;
}

}

现在在Managedbean方法中DAO对象是null和我得到空指针异常


警告:#{userMB.addUser}:java.lang.NullPointerException
javax。 faces.FacesException:#{userMB.addUser}:

处的java.lang.NullPointerException com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)$ java
。 faces.component.UICommand.broadcast(UICommand.java:315)at
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at
javax.faces.component。 UIViewRoot.processApplication(UIViewRoot.java:1259)维持在com.sun.faces.lifecycle
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)

。 Phase.doPhase(Phase.java:101)at
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServl et.java:593)在
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
。在
org.apache.catalina.core.ApplicationFilterChain.doFilter(

org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at
org.apache.catalina.core。 StandardContextValve.invoke(StandardContextValve.java:123)
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at
org.apache。 catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at
org.apache.catalina.connector.CoyoteAdapter.servic e(CoyoteAdapter.java:407)
at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at
org.apache.coyote。 AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:585)
at
org.apache.tomcat.util.net.JIoEndpoint $ SocketProcessor.run(JIoEndpoint.java:312)
at
java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)$ b $ java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886)
at

在java.lang.Thread.run(Thread.java:662)引起:
javax.faces.el.E​​valuationException:java.lang.NullPointerException在
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke (MethodBindingMethodExpressionAdapter.java:102)
at
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 23 more引起:java.lang。 NullPointerException在
com .otv.managed.bean.UserManagedBean.addUser(UserManagedBean.java:57)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)at
$ or $ $ b $ org.apache.el.parser.AstValue.invoke(AstValue.java:264)org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at
com在
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
.. 。24 more


解决方案

简而言之,您的bean应该完全由JSF管理或者Spring。

有很多证据到这一点。请在这里和/或网上寻找JSF + spring integartion。



现在让我想一想这个问题,以加深您的理解。



许多Web应用程序由多个'层'组成,也称为应用程序的'层':Web层或表示层,用于查看应用程序,业务层或中间层的页面以执行逻辑和应用程序和数据层的业务规则,或者用于向/从数据库传输数据的持久层。这些层可能具有以下配置:


  1. 实体从你的数据库中,并最合理地用于像Hibernate这样的ORM框架;

  2. DAO 将用于访问数据库的类,至少对数据库执行CRUD操作,最重要的是为您的Web部件返回您的Web层的实体类;

  3. Service 类将反映您应用程序提供的业务操作;
  4. Bean 将备份您的视图并最可能包含数据,操作方法和转换的类等等。

下一步是为您的web应用程序选择框架。


  1. 您为所有图层选择Spring,这意味着您的DAO将是 @Repository 类,您的服务将是 @Service 类和您的Bean将会是 @Component 类。你很可能会使用像Hibernate这样的ORM框架来处理数据库,所以你的实体将会是在Hibernate风格下正确配置的JPA @Entity 类。您的视图技术很可能是Spring MVC,它已经与Spring核心协同工作。例如, Mkyong 有很多关于使用Spring的简单教程。


  2. 您为所有图层选择本地JSF + EJB框架,这意味着您的DAO和服务将 @EJB c> @ManagedBean 类。您很可能也会使用Hibernate作为ORM解决方案和JPA提供程序,并将通过 EntityManager 执行数据库访问。您的视图技术将成为JSF,因为它本来就是用于上述技术的。例如, BalusC 有许多有关使用JSF的启发性教程。


两种选择都有其支持者和反对者。有人说,为什么选择一些非本机的东西来解决Sun的Oracle解决方案,另一些人则说这太复杂和混乱,并且缺乏从中学习的经验。



因为这不是技术选择上的争议,所以我不会在这里详细讨论,但是会指出Spring是一个轻量级的容器,它可以运行在像Tomcat这样的简单servlet容器上,而EJB需要像Glassfish这样的应用服务器来运行。我认为这是将JSF作为基于组件的Web框架与Spring作为轻量级依赖注入和业务层框架相结合的主要推动力。



当我们决定将这两个框架集成在一起,我将解释整合是如何工作的以及NPE为什么会出现。


  1. 实体类可以是JPA / Hibernate注释类或通过xml配置简单的POJO。
    DAO将实现基本接口以避免紧耦合。 它们将由Spring框架管理。

  2. 服务也将是 @Service 也实现基本接口。他们也将由Spring框架管理。请注意,如果使用 @Transactional 标记服务方法,Spring框架将为您提供开箱即用的事务管理。

  3. 因此,Bean必须是 @Component @Scope(value),并且必须由Spring管理将其用作依赖注入框架,允许通过 @Autowired 访问您的服务和其他bean。

因此,NPE源于误解您的bean作为视图的逻辑部分应由JSF管理(注意 @ManagedProperty 也不会工作)。该bean被JSF实例化,但是你的服务驻留在JSF知道注意的Spring上下文中,使注入变得不可能。另一方面,如果bean保持在Spring上下文中,它的生命周期和依赖将由Spring注入。

因此,为了使它工作,将bean标记为

  @Component 
@Scope(request)
public class SpringManagedBeanToBeUsedByJSF {

...

@Autowired
私人SpringService springService;

...

}

和使JSF使用Spring的所有先决条件。如果您失败,请参阅这个出色的示例进行设置。这样,所有bean将由Spring管理,并且在faces-config.xml中连接EL-resolver(允许JSF'查看'Spring bean)以及web.xml中必要的侦听器时,JSF视图中将显示这些bean。当你这样做时,所有的Spring bean都可以在.xhtml文件中被引用,并且如果你需要把JSF动作放到bean中,那么就把它们放在(Spring)托管的bean中,或者让它们实现至关重要到JSF接口等。整合只能通过这种方式实现。当然,您也可以在应用程序中使用JSF托管bean, @FacesConverter @FacesValidator 类,不要互相干扰,但是使用两个依赖注入框架和一个应用程序至少是令人困惑的。



希望这可以帮助您更好地理解情况。



您的代码也存在一些问题,我不会在这个通用答案中强调一下。


I am using JSF2+Spring3.1+Hibernate4 in my demo application and i will want to use annotation to create session factory but my DAO class is not initialize in Jsf Managed Bea class so i am getting Null pointer Exception. My applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/tx 
                http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                http://www.springframework.org/schema/context 
                http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config></context:annotation-config>

    <context:component-scan base-package="com.otv"></context:component-scan>


    <!-- Data Source Declaration -->
    <bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  >
        <property name="driverClass" value="org.postgresql.Driver" />   
        <property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/postgres" />   
        <property name="user" value="postgres" />   
        <property name="password" value="hariom" /> 
        <property name="maxPoolSize" value="10" />
        <property name="maxStatements" value="0" />
        <property name="minPoolSize" value="5" /> 
    </bean>

    <!-- Session Factory Declaration -->
    <bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean ">
        <property name="dataSource" ref="DataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.otv.model.User</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
          <property name="packagesToScan" value="com.otv.user"></property>
    </bean>


    <!-- Transaction Manager is defined -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
       <property name="sessionFactory" ref="SessionFactory"/>
    </bean>


  <!-- Enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="txManager"/>

</beans>

UserDAO.java class

package com.otv.user.dao;

import java.util.List;

import com.otv.model.User;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * User DAO
 * 
 * @author onlinetechvision.com
 * @since 25 Mar 2012
 * @version 1.0.0
 *
 */

@Repository
@Transactional
public class UserDAO   {

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * Get Hibernate Session Factory
     * 
     * @return SessionFactory - Hibernate Session Factory
     */
/*  public SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    *//**
     * Set Hibernate Session Factory
     * 
     * @param SessionFactory - Hibernate Session Factory
     *//*
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }*/



    /**
     * Add User
     * 
     * @param  User user
     */
    public void addUser(User user) {
        sessionFactory.getCurrentSession().save(user);
    }

    /**
     * Delete User
     * 
     * @param  User user
     */
    public void deleteUser(User user) {
        sessionFactory.getCurrentSession().delete(user);
    }

    /**
     * Update User
     * 
     * @param  User user
     */
    public void updateUser(User user) {
        sessionFactory.getCurrentSession().update(user);
    }

    /**
     * Get User
     * 
     * @param  int User Id
     * @return User 
     */
    public User getUserById(int id) {
        List list = sessionFactory.getCurrentSession()
                                            .createQuery("from User where id=?")
                                            .setParameter(0, id).list();
        return (User)list.get(0);
    }

    /**
     * Get User List
     * 
     * @return List - User list
     */
    public List<User> getUsers() {
        List list = sessionFactory.getCurrentSession().createQuery("from User").list();
        return list;
    }

}

AND my managedBean class

package com.otv.managed.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;

import com.otv.model.User;
import com.otv.user.dao.UserDAO;
import com.otv.user.service.IUserService;

/**
 * 
 * User Managed Bean
 * 
 * @author onlinetechvision.com
 * @since 25 Mar 2012
 * @version 1.0.0
 *
 */
@ManagedBean(name="userMB")
@RequestScoped
public class UserManagedBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final String SUCCESS = "success";
    private static final String ERROR   = "error";

    //Spring User Service is injected...


    List<User> userList;

    private int id;
    private String name;
    private String surname;

      @Autowired
      private UserDAO userDAO;
    /**
     * Add User
     * 
     * @return String - Response Message
     */
    public String addUser() {
        try {
            User user = new User();
            user.setId(getId());
            user.setName(getName());
            user.setSurname(getSurname());
            userDAO.addUser(user);
            return SUCCESS;
        } catch (DataAccessException e) {
            e.printStackTrace();
        }   

        return ERROR;
    }

    /**
     * Reset Fields
     * 
     */
    public void reset() {
        this.setId(0);
        this.setName("");
        this.setSurname("");
    }

    /**
     * Get User List
     * 
     * @return List - User List
     */
    public List<User> getUserList() {
        userList = new ArrayList<User>();
        userList.addAll(userDAO.getUsers());
        return userList;
    }

    /**
     * Get User Service
     * 
     * @return IUserService - User Service
     */

    /**
     * Set User List
     * 
     * @param List - User List
     */
    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    /**
     * Get User Id
     * 
     * @return int - User Id
     */
    public int getId() {
        return id;
    }

    /**
     * Set User Id
     * 
     * @param int - User Id
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * Get User Name
     * 
     * @return String - User Name
     */
    public String getName() {
        return name;
    }

    /**
     * Set User Name
     * 
     * @param String - User Name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get User Surname
     * 
     * @return String - User Surname
     */
    public String getSurname() {
        return surname;
    }

    /**
     * Set User Surname
     * 
     * @param String - User Surname
     */
    public void setSurname(String surname) {
        this.surname = surname;
    }

}

Now in Managedbean method DAO object is null and i am getting Null Pointer exception

WARNING: #{userMB.addUser}: java.lang.NullPointerException javax.faces.FacesException: #{userMB.addUser}: java.lang.NullPointerException at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) at javax.faces.component.UICommand.broadcast(UICommand.java:315) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) ... 23 more Caused by: java.lang.NullPointerException at com.otv.managed.bean.UserManagedBean.addUser(UserManagedBean.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.el.parser.AstValue.invoke(AstValue.java:264) at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) ... 24 more

解决方案

To put it short, your beans should be completely managed either by JSF or by Spring.

There is much evidence to this point. Just look for "JSF + spring integartion" here and/or on the web.

Now let me contemplate on the issue to enhance your understanding.

Many web applications consist from several 'layers' also called as 'tiers' of the application: web tier, or presentation tier for viewing pages of your application, business tier, or middle tier for executing logic and business rules of your appication and data tier, or persistece tier for tranferring data to/from your database. These tiers might have the following configuration:

  1. Entity classes that will hold data derived from your database and most plausibly used by an ORM framework like Hibernate;
  2. DAO classes that will be used to access database and at least perform CRUD operations on the database and most importantly for your web part return Entity classes for your web tier;
  3. Service classes that will reflect business operations you application provides for;
  4. Bean classes that will back up your views and will most probably contain data, action methods, transformations etc. used in your web pages.

The next step is the choice of framework for your web application.

  1. You choose Spring for all layers which means that your DAOs will be @Repository classes, your Services will be @Service classes and your Beans will be @Component classes. You will most probably use an ORM framework like Hibernate to deal with the database, so your Entities will be JPA @Entity classes properly configurated in Hibernate style. Your view technology will most probably be Spring MVC that was elaborated to work with Spring core. For example, Mkyong has many simple tutorials on using Spring.

  2. You choose native JSF+EJB framework for all layers which means that your DAOs and Services will be @EJB classes your beans will be @ManagedBean classes. You will most probably also use Hibernate as ORM solution and JPA provider and will do database access via EntityManager. Your view technology will be JSF as it was naturally intended to be used with the abovementioned technologies. For example, BalusC has many enlightening tutorials on using JSF.

Both choices has its advocates and opponents. Some say that why choose something not native to Sun's Oracle's solution, others say that it is too complex and confusing and lacks sources to learn from.

As this is not a dispute on technology choice I will not go into details here, but will point out that Spring is a lightweight container that will run on simple servlet containers like Tomcat whereas EJBs need an application server like Glassfish to run on. I think that this is the major driving force for combining JSF as a component-based web framework and Spring as a lightweight dependency injection and business tier framework.

As we decided to integrate both frameworks together, I will explain how the integration works and why NPEs occur.

  1. Entity classes will either be JPA/Hibernate annotated classes or simple POJOs configured by xml.
  2. DAOs will be @Repository implementing base interfaces to avoid tight coupling. They will be managed by the Spring framework.
  3. Services will be @Service also implementing base interfaces. They will also be managed by the Spring framework. Note that Spring framework will provide for out-of-the-box transaction management for you if you mark service methods with @Transactional.
  4. Beans therefore must be @Component and @Scope("value") and must be managed by Spring if you want to use it as a dependency injection framework, allowing to access your services and other beans via @Autowired.

So, the NPE stems from misunderstanding that your beans, as a logical part of the view, should be managed by JSF (note that @ManagedProperty wouldn't work as well). The bean gets instantiated by JSF, but your service resides in Spring context that JSF knows noting about, making injection not possible. On the other hand, if the bean remains within Spring context, its lifecycle and dependencies will be injected by Spring.

So, to make it work, mark the bean as

@Component
@Scope("request")
public class SpringManagedBeanToBeUsedByJSF {

    ...

    @Autowired
    private SpringService springService;

    ...

}

and make all the prerequisites of using Spring with JSF. Consult this excellent example for settings if you lose track. This way, all of the beans will be managed by Spring and will be visible in JSF views when you attach EL-resolver in faces-config.xml (allowing JSF to 'see' Spring beans) and necessary listeners in web.xml. When you do it like this, all of the Spring beans can be referenced in .xhtml files and if you need to put the JSF action in the bean, just go ahead and place them in the (Spring) managed beans or make them implement vital to JSF interfaces, etc. The integration can be achieved only this way. Of course, you can also use JSF managed beans, @FacesConverter and @FacesValidator classes in the application as well, just do not interfere them with each other, but using two dependency injection frameworks withing one application is at least confusing.

Hope this helps you in understanding the situation better.

There are also some problems with your code I would not stress out in this general answer.

这篇关于Spring DAO没有注入到JSF托管bean中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆