我正在使用JSF 1.2并尝试使用<a4j:keepAlive beanName="reportController">
,但我继续收到此错误:
HTTP状态500
引起:java.io.NotSerializableException:java.io.ObjectOutputStream.writeObject0中的com.mysql.jdbc.DatabaseMetaData(ObjectOutputStream.java:1183
我正在尝试使用<a4j:keepAlive beanName="reportController">
因为当我搜索特定报告然后尝试对dataTable中的数据进行排序时,它似乎丢失了dataTable中的所有数据。
答案 0 :(得分:2)
引起:java.io.NotSerializableException:com.mysql.jdbc.DatabaseMetaData
当您将java.sql.Connection
或甚至直接DatabaseMetaData
作为可序列化类的实例变量(如下所示)时,会发生这种情况。
public class ReportController implements Serializable {
private Connection connection; // BAD!!
private DatabaseMetaData metadata; // BAD!!
// ...
}
您不应该声明并获取外部资源,例如java.sql.Connection
,Statement
和ResultSet
,也不应将其属性作为类的实例变量。您应该尽快获取,使用和关闭它们,完全在方法本地范围内。从ReportController
bean中删除那些实例变量,将它们移动到方法局部范围,这个问题就会消失。只有DataSource
(服务器管理的连接池)作为实例变量才可以。
public class ReportController implements Serializable {
@Resource("jdbc/someDB")
private DataSource dataSource;
public void someMethod() {
try (Connection connection = dataSource.getConnection()) { // OK.
// ...
}
}
// ...
}
<a4j:keepAlive>
并不是导致此问题的原因。它只是在同一页面上的HTTP回发请求中记住HTTP会话中的bean实例。 HTTP会话属性本质上通常是序列化的。此序列化仅触发并暴露了您隐藏的设计问题。易失性的一次性使用资源,如数据库连接,语句,元数据,输入流,输出流等,绝对不应该是可序列化的,因此这个例外。