Фильтр не инициализирует EntityManager
Я пытаюсь использовать шаблон Open Session in View, но каждый раз, когда я пытаюсь поймать EntityManager
в моем ManagedBean
EntityManager
come 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>
Любая идея, почему это происходит?
UPDATE
После поиска в каждом месте о JPA, Hibernate и EJB, наконец, я нашел хороший урок об этом (следуйте этому порядку, чтобы понять, что делает, хорошо?):
Установить и настроить MySQL для Eclipse и Oracle Glassfish 3.1
Создание формы регистрации пользователя с использованием JSF 2.0
Проверка и преобразование данных с использованием JSF 2.0
Использование EJB 3.0 и JPA 2.0 для сохранения базы данных
Ответы
Ответ 1
Это будет работать только в том случае, если ваш PlayerBean
также имеет область запроса. Если это область видимости, то любые атрибуты, созданные вручную вручную, игнорируются и не вводятся просто потому, что эта конструкция не разрешена. Вы можете только ввести управляемое свойство JSF той же или более широкой области действия, что и акцептор.
Я знаю, основываясь на вашей истории вопроса, что вы используете Glassfish 3. Почему бы вам просто не использовать EJB? Таким образом, контейнер будет беспокоиться о самих транзакциях, и вам совсем не обязательно иметь такой фильтр. Вы можете ввести EntityManager
на @PersistenceContext
.
Это довольно просто. Просто создайте следующий класс 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();
}
// ...
}