Tomcat / Eclipse:在上下文重新加载期间禁用HttpSession序列化

时间:2012-07-01 06:19:51

标签: eclipse hibernate jsf tomcat

我重启tomcat服务器后得到InvalidObjectException: Could not find a SessionFactory named: null

我找到了一些可能的解决方案:

  

如果您尝试序列化已断开连接的Hibernate会话并在其他VM中对其进行反序列化,则会发生此异常,或者,如果   例如,在热重新部署期间,classloader已重新启动   您的应用程序服务器或Web容器。这尤其明显   在Tomcat。在应用程序服务器中,始终使用JNDI来存储   SessionFactory,如记录。在Tomcat或其他Web容器中,   在上下文重新加载期间禁用HttpSession序列化。这有副作用,在Web容器的文档中有解释。

我该怎么办?在上下文重新加载期间禁用HttpSession序列化?

注意:我在Eclipse中使用Tomcat7。

更新:

我已尝试在context.xml中启用此标记:

<Manager pathname="" />

是的,异常消失了,但我丢失了持久会话,所以我必须在tomcat服务器重启后再次登录。

我是否理解会话持久性,如果我相信,在tomcat重新启动后,应保留该会话(并且我不能通过登录创建新会话)。 JSF应用程序?

UPDATE2(会话管理员):

@SessionScoped
@ManagedBean(name="userManager")
public class UserManager implements Serializable {
  private static final long serialVersionUID = 1L;
  private transient HttpSession session;
  private String username;
  private String password;
  private User user;

  public String login() {
    // here is seraching for user in database (based on username and password)

    if (user != null) {
      FacesContext context = FacesContext.getCurrentInstance();
      session = (HttpSession) context.getExternalContext().getSession(true);
      session.setAttribute("id", user.getId());
      session.setAttribute("username", user.getName());
      ...
      return "success";
    } 
  }

  public String logout() {
    user = null;
    FacesContext context = FacesContext.getCurrentInstance();
    session = (HttpSession) context.getExternalContext().getSession(true);
    ...     
    session.invalidate();
    return "success";
  }
  // getters and setters ----------------------------------------------------
}

我的hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <session-factory>
  <property name="connection.url">jdbc:sqlserver://localhost;databaseName=RXP</property>
  <property name="connection.username">user</property>
  <property name="connection.password">password</property>
  <property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
  <property name="dialect">org.hibernate.dialect.SQLServer2008Dialect</property>
  <property name="current_session_context_class">thread</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hibernate.hbm2ddl.auto">update</property>

  <mapping class="tables.User"/>

 </session-factory>
</hibernate-configuration>

我的会话工厂

public final class DaoSF implements Serializable {
  private static final long serialVersionUID = 1L;

  private static SessionFactory sessionFactory;
  private static ServiceRegistry serviceRegistry;

  public static SessionFactory getSessionFactory() {
    try {
      Configuration configuration = new Configuration();
      configuration.configure("hibernate.cfg.xml");
      serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        
      sessionFactory = configuration.buildSessionFactory(serviceRegistry);
      return sessionFactory;
    }
    catch (HibernateException he) { 
      ...
    }
  }
}

2 个答案:

答案 0 :(得分:7)

你应该可以通过以下方式来改变它:

<Manager pathname="" />

在Tomcat配置文件的Context部分中。

请参阅Tomcat文档:
配置参考&gt; 经理组件&gt; 禁用会话持久性

答案 1 :(得分:0)

answer by Codo是正确的。

以下是实现上述标记的示例。

在您的网络应用的META-INF文件夹中,在context.xml文件中:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="">
    <Manager pathname=""/>
</Context>