Jsf java.io.NotSerializableException:com.microsoft.sqlserver.jdbc.SQLServerConnection

Jsf java.io.NotSerializableException:com.microsoft.sqlserver.jdbc.SQLServerConnection,jsf,serialization,jdbc,Jsf,Serialization,Jdbc,我正在使用Microsoft SQL Server和JSF 我一直收到这个例外: IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.microsoft.sqlserver.jdbc.SQLServerConnection java.io.WriteAbortedException: w

我正在使用Microsoft SQL Server和JSF

我一直收到这个例外:

IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.microsoft.sqlserver.jdbc.SQLServerConnection
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.microsoft.sqlserver.jdbc.SQLServerConnection
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1587)
    at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1060)
    at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:284)
    at org.apache.catalina.session.StandardManager.load(StandardManager.java:204)
    at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:470)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5169)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:774)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:726)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:620)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:303)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:431)
Caused by: java.io.NotSerializableException: com.microsoft.sqlserver.jdbc.SQLServerConnection
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:1663)
    at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1077)
    at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:411)
    at org.apache.catalina.session.StandardManager.unload(StandardManager.java:353)
    at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:497)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:225)
    at org.apache.catalina.core.StandardContext$4.call(StandardContext.java:5391)
    at org.apache.catalina.core.StandardContext$4.call(StandardContext.java:5374)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
例如,我将与SQL Server相关的Java Bean设置为
实现可序列化的

@ManagedBean
@SessionScoped
public class SqlBean implements Serializable {

    private Connection  conn = null;

    public SqlBean() {
        super();
        System.out.println("Starts to read!");
        String dbName = "//some dbName";
        String serverip="//some serverip";
        String serverport="//some serverport";
        String url = "jdbc:sqlserver://"+serverip+"\\SQLEXPRESS:"+serverport+";databaseName="+dbName+"";
        String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        String databaseUserName = "//some user";
        String databasePassword = "//some password";
        try {
            Class.forName(driver).newInstance();
            conn = DriverManager.getConnection(url, databaseUserName, databasePassword);
            if(conn!=null) System.out.println("Connection Successful!");
        }catch(Exception e){
            e.printStackTrace();
            System.out.println("Error Trace in getConnection() : " + e.getMessage());
        }
    }
}

连接总是成功的。完全迷失在这一点上。任何帮助都将不胜感激。

这在两个方面是非常错误的:

//resource injection
private Connection  conn = null;
  • 这绝对不是资源注入
  • 保持一个连接打开那么长时间并在HTTP会话中跨多个请求共享它是一种糟糕的设计,而且不是线程安全的
  • 您应该重写所有JDBC代码,以便在同一try finally块的最短可能范围内获取并关闭所有数据库资源
    连接
    (准备好的)语句
    结果集

    您的具体问题是由于DB连接没有实现可序列化,原因很简单,TCP/IP连接不能序列化

    另见:
    • (与您的设计问题非常相似)


    请注意,这个问题与JSF完全无关。您应该将所有JDBC代码放进去,并确保所有JSF管理的bean都完全没有
    java.sql
    imports。为了更进一步,开始学习EJB和JPA。这样,所有数据库交互都可以在一行程序中完成,而不需要所有原始连接/语句/结果集。如果您想使用Java EE,这也是您应该遵循的路径。

    使用瞬态是一种不好的做法吗?取决于它是否被用作解决方案或解决方法。如果作为一种解决办法,那肯定是不好的。我的回答描述了解决方案。如果您使用
    transient
    而不是应用我的答案,那么这将是一个解决方法。你只是推迟/移动/隐藏真正的问题,而不是真正解决它。为什么它不好?我使用它作为解决办法,因为我的答案中描述的问题仍然存在。