Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
378 views
in Technique[技术] by (71.8m points)

jakarta ee - Filter do not initialize EntityManager

I trying to use the Open Session in View pattern, but everytime I try to catch the EntityManager in my ManagedBean the entityManager come NULL here is how I'm doing:

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();
    }

}

And this is my 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;
    }
}

And this is my 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>

Any idea why this is happening ?

UPDATE After searching in every place about JPA, Hibernate and EJB, finally I found a good tutorial about it (follow this order to understand what is been doing, okay ?):

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That will only work if your PlayerBean is also request scoped. If it is view scoped, then any manually created request scoped attributes are ignored and not injected simply because this construct is not allowed. You can only inject a JSF managed property of the same or broader scope than the acceptor.

I know based on your question history that you're using Glassfish 3. Why don't you just use an EJB? This way the container will worry about transactions itself and you don't need to have such a filter at all. You can inject the EntityManager by @PersistenceContext.

It's pretty simple. Just create the following EJB class:

@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));
    }

    // ...
}

(no further configuration is necessary on Glassfish 3)

You can then use it as follows in your JSF managed bean:

@ManagedBean
@ViewScoped
public class PlayerBean {

    private List<Player> players;

    @EJB
    private PlayerService playerService;

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

    // ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...