You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSF 2.2整合Spring 4+Spring Data JPA遇Target Unreachable异常

解决JSF 2.2 + Spring 4 + Spring Data JPA集成时的PropertyNotFoundException问题

这个异常Target Unreachable, identifier [registerEmployee] resolved to null的核心原因是JSF无法找到你定义的registerEmployee Bean,本质是JSF和Spring的Bean生命周期管理冲突,加上一些配置和注解使用错误导致的。下面是一步步的解决方案:

1. 统一Bean管理方式:把JSF托管Bean交给Spring管理

你现在混合使用了JSF的@ManagedBean和Spring的@Autowired,这会导致Bean的管理混乱。推荐把所有业务相关的Bean都交给Spring管理,这样能更好地集成Spring Data JPA。

修正RegisterEmployee类

替换JSF的注解为Spring的注解,同时移除@ManagedProperty改用Spring的@Autowired:

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.SessionScope;

@Component("registerEmployee") // 用Spring的@Component定义Bean,指定名称对应JSF中的EL
@SessionScope // Spring的会话作用域,替代JSF的@SessionScoped
public class RegisterEmployee implements Serializable {

    @Autowired
    private EmployeeService employeeService;

    // 注意:不要用@Autowired注入Employee实体!实体类是JPA映射对象,不是Spring管理的Bean
    private Employee employee = new Employee(); // 直接实例化,或者用@ModelAttribute

    // Getters & Setters
    public EmployeeService getEmployeeService() { return employeeService; }
    public void setEmployeeService(EmployeeService employeeService) { this.employeeService = employeeService; }

    public Employee getEmployee() { return employee; }
    public void setEmployee(Employee employee) { this.employee = employee; }

    public String register() {
        employeeService.register(employee);
        FacesContext.getCurrentInstance().addMessage(null, 
            new FacesMessage("The Employee "+this.employee.getEmployeeName()+" Is Registered Successfully"));
        // 注册完成后重置Employee对象,避免下次复用旧数据
        this.employee = new Employee();
        return "";
    }
}

修正Employee实体类

实体类是JPA用来映射数据库的对象,不需要添加@Component注解,去掉这个错误的配置:

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "EMP_ID")
    private long employeeId;

    @Column(name = "EMP_NAME")
    private String employeeName;

    @Column(name = "EMP_HIRE_DATE")
    private Date employeeHireDate;

    @Column(name = "EMP_SALARY")
    private double employeeSalary;

    // 保留原有的Getters和Setters
    public long getEmployeeId() { return employeeId; }
    public void setEmployeeId(long employeeId) { this.employeeId = employeeId; }
    public String getEmployeeName() { return employeeName; }
    public void setEmployeeName(String employeeName) { this.employeeName = employeeName; }
    public Date getEmployeeHireDate() { return employeeHireDate; }
    public void setEmployeeHireDate(Date employeeHireDate) { this.employeeHireDate = employeeHireDate; }
    public double getEmployeeSalary() { return employeeSalary; }
    public void setEmployeeSalary(double employeeSalary) { this.employeeSalary = employeeSalary; }
}

2. 配置JSF从Spring获取Bean

在faces-config.xml中添加Spring的EL解析器,让JSF能够识别Spring管理的Bean:

<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
              version="2.2">
    <application>
        <!-- 配置Spring的EL解析器,让JSF能找到Spring管理的Bean -->
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>

3. 检查Spring核心配置

确保你的Spring配置类(或XML)包含以下关键配置:

  • 开启组件扫描,覆盖RegisterEmployee、EmployeeService所在的包:
@Configuration
@ComponentScan(basePackages = "com.your.package") // 替换成你的实际包路径
@EnableJpaRepositories(basePackages = "com.your.package.repository") // 开启Spring Data JPA
@EnableTransactionManagement // 开启事务管理
public class SpringConfig {
    // 配置DataSource、LocalContainerEntityManagerFactoryBean、PlatformTransactionManager等Bean
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("com.your.package.entity"); // 指定JPA实体类所在包
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        // 可选:添加Hibernate属性配置
        Properties props = new Properties();
        props.setProperty("hibernate.hbm2ddl.auto", "update");
        props.setProperty("hibernate.show_sql", "true");
        em.setJpaProperties(props);
        return em;
    }

    // 其他必要配置:DataSource、TransactionManager等
}

为什么之前的方案无效?

  • 混合JSF和Spring的Bean管理:JSF的@ManagedBean默认不会识别Spring的@Autowired,必须配置Spring EL解析器才能打通两者
  • Employee实体加@Component是错误的:实体类是JPA的映射对象,不需要被Spring作为单例Bean管理,注入会导致复用同一个实例,数据混乱
  • 仅替换@Autowired为@ManagedProperty没用:JSF的@ManagedProperty只能注入JSF托管的Bean,无法直接获取Spring的Bean

内容的提问来源于stack exchange,提问作者Norman87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:23:50