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

Posted

技术标签:

【中文标题】Tomcat/Eclipse:在上下文重新加载期间禁用 HttpSession 序列化【英文标题】:Tomcat/Eclipse: disable HttpSession serialization during context reload 【发布时间】:2012-07-02 01:26:12 【问题描述】:

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

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

如果您尝试序列化断开连接的 Hibernate Session 并在不同的 VM 中反序列化它,或者如果 类加载器已重新启动,例如,在热重新部署期间 您的应用程序服务器或 Web 容器。这个特别明显 在雄猫。在应用服务器中,总是使用 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)  
      ...
    
  

【问题讨论】:

【参考方案1】:

你应该可以通过把它关掉:

<Manager pathname="" />

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

请参阅 Tomcat 文档:配置参考 > 管理器组件 > 禁用会话持久性

Version 7.0 Version 8.0

【讨论】:

是的,我已经尝试过了,异常消失了。但是会话现在没有存储,我每次都必须重新登录,我重新启动了tomcat服务器(请看我更新的问题)...... 如果您不想关闭会话持久性,那么您必须修复会话中的对象,即您必须使它们可序列化(实现 java.io.Serializable)(参见@987654323 @.) 我所有的 bean 都是可序列化的 :( (implements Serializable ... private static final long serialVersionUID = 1L;) 您如何管理会话?您为此使用 JNDI 吗?如果是,切换到使用线程本地存储的会话管理器可能会有所帮助,并使会话工厂远离 Tomcat。 如果您可以发布 InvalidObjectException 的完整堆栈跟踪以更好地诊断导致问题的对象,这可能会有所帮助。你确定它是“current_session_context_class”而不是“hibernate.current_session_context_class”吗?【参考方案2】:

answer by Codo 是正确的。

这是实现上述标签的示例。

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

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

【讨论】:

以上是关于Tomcat/Eclipse:在上下文重新加载期间禁用 HttpSession 序列化的主要内容,如果未能解决你的问题,请参考以下文章

如果在重新加载期间触摸单元格,则重新加载后无法选择 UICollectionView 单元格

在执行Behat上下文期间不会加载Doctrine注释

Tomcat 9/Eclipse 2020-12:HTTP 状态 404

如何在 UITableView 重新加载期间控制过渡动画? [复制]

在搜索期间重新加载 UITableView

Apollo Graphql:避免在重新获取期间加载指示器