过滤器不初始化EntityManager
我尝试在视图模式中使用“打开会话”,但每次我尝试在 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 的各个地方后,终于找到了一个关于它的很好的教程(按照这个顺序来了解正在做什么,好吗?):
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
仅当您的
PlayerBean
也处于请求范围内时,这才有效。如果它是视图范围的,则任何手动创建的请求范围的属性都将被忽略,并且不会注入,仅仅是因为不允许此构造。您只能注入与接受器范围相同或更广的 JSF 托管属性。根据您的问题历史记录,我知道您正在使用 Glassfish 3。为什么不直接使用 EJB?这样容器就会担心事务本身,而你根本不需要这样的过滤器。您可以通过
EntityManager >@PersistenceContext
。这很简单。只需创建以下 EJB 类:
(在 Glassfish 3 上无需进一步配置)
然后您可以在 JSF 托管 bean 中按如下方式使用它:
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:
(no further configuration is necessary on Glassfish 3)
You can then use it as follows in your JSF managed bean: