jakarta-ee - 过滤器不初始化 EntityManager

标签 jakarta-ee jpa jsf-2 jpa-2.0 servlet-filters

我尝试在 View 模式中使用 Open Session,但每次我尝试在我的 ManagedBean 中捕获 EntityManager 时,entityManager 都会出现 NULL 这是我的做法:

package filters;

// imports..    


public class JPAFilter implements Filter {

    private EntityManagerFactory factory;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        EntityManager entityManager = this.factory.createEntityManager();
        request.setAttribute("entityManager", entityManager);
        entityManager.getTransaction().begin();

        chain.doFilter(request, response);

        try {
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            throw new ServletException(e);
        } finally {
            entityManager.close();
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.factory = Persistence.createEntityManagerFactory("copadomundo");

    }

    @Override
    public void destroy() {
        this.factory.close();
    }

}

这是我的 ManagedBean:

package managedbeans;

// imports ..

@ManagedBean
public class PlayerBean {

    @ManagedProperty(value = "#{entityManager}")
    private EntityManager entityManager;

    private Player player = new Player();

    private Long teamID;

    private List<Player> players = new ArrayList<Player>();

    public void add() {
        TeamRepository selecaoRepository = new TeamRepository(this.entityManager);
        Team selecao = selecaoRepository.search(this.teamID);
        this.player.setTeam(selecao);

        PlayerRepository playerRepository = new PlayerRepository(this.entityManager);
        playerRepository.adiciona(this.player);

        this.player = new Player();
        this.players = null;
    }

    public void remove(Player player) {
        PlayerRepository repository = new PlayerRepository(this.entityManager);
        repository.remove(player);
        this.players = null;
    }

    // GETTERS AND SETTERS
    public List<Player> getPlayeres() {
        if (this.players == null) {

            PlayerRepository repository = new PlayerRepository(
                    this.entityManager);
            this.players = repository.getPlayeres();
        }
        return this.players;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public Player getPlayer() {
        return player;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    public Long getTeamID() {
        return teamID;
    }

    public void setTeamID(Long teamID) {
        this.teamID = teamID;
    }

    public void setPlayeres(List<Player> players) {
        this.players = players;
    }
}

这是我的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>WorldCup</display-name>
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>jpa.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <filter>
        <filter-name>JPAFilter</filter-name>
        <filter-class>jpa.JPAFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>JPAFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <error-page>
        <exception-type>java.lang.Exception</exception-type>
        <location>/error.xhtml</location>
    </error-page>
</web-app>

知道为什么会这样吗?

更新 在到处搜索有关 JPA、Hibernate 和 EJB 的内容后,我终于找到了一个很好的教程(按照这个顺序来了解正在做什么,好吗?):

Install and Configure MySQL for Eclipse and Oracle Glassfish 3.1

Building a User Registration Form using JSF 2.0

Validation and Conversion of Data Using JSF 2.0

Using EJB 3.0 and JPA 2.0 for Database Persistence

最佳答案

这只有在您的 PlayerBean 也是请求范围的情况下才有效。如果它是 View 范围的,那么任何手动创建的请求范围的属性都会被忽略并且不会被注入(inject),因为这个构造是不允许的。您只能注入(inject)与接受器范围相同或范围更广的 JSF 托管属性。

根据您的问题历史,我知道您正在使用 Glassfish 3。您为什么不直接使用 EJB?这样容器就会担心事务本身,你根本不需要有这样的过滤器。您可以通过 @PersistenceContext 注入(inject) EntityManager .

这很简单。只需创建以下 EJB 类:

@Stateless
public class PlayerService {

    @PersistenceContext
    private EntityManager em;

    public Player find(Long id) {
        return em.find(Player.class, id);
    }

    public List<Player> list() {
        return em.createQuery("SELECT p FROM Player p", Player.class).getResultList();
    }

    public void create(Player player) {
        em.persist(player);
    }

    public void update(Player entity) {
        em.merge(player);
    }

    public void delete(Player player) {
        em.remove(em.contains(player) ? player : em.merge(player));
    }

    // ...
}

(在 Glassfish 3 上无需进一步配置)

然后您可以在 JSF 托管 bean 中按如下方式使用它:

@ManagedBean
@ViewScoped
public class PlayerBean {

    private List<Player> players;

    @EJB
    private PlayerService playerService;

    @PostConstruct
    public void init() {
        players = playerService.list();
    }

    // ...
}

关于jakarta-ee - 过滤器不初始化 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7934447/

相关文章:

jsf-2 - 如何在三秒后自动关闭 PrimeFaces 对话框

java - 不要在 servlet 中硬编码 jsp 链接

java - 如果没有 wtpwebapps 文件夹,则无法在 Tomcat 7 上部署 WAR 文件

java - 如何设置/配置 JBoss?

java - 如何通过 Sort 和 Pageable 使用 Spring data JPA 开箱即用地查询数据?

java - 如何在使用新生成的实体标识符时深度复制 Hibernate 实体

jsf-2 - PrimeFaces Mobile 请求 undefined/undefined.css 和 undefined/undefined.js,导致 JSF1064 警告和 404 错误

java - Spring中抛出404并重定向到自定义错误页面

java - Spring Snake 大小写转换不适用于外键列

parameters - 如何将具有相同键的多个参数提取到 JSF 托管 bean 中