DefaultPreparedStatement启动Tomcat时不可序列化

问题描述:

我使用Cassandra 3.10,Datastax驱动程序3.1.4和Apache Lucerne索引生成器和Spring 4.3.2构建一个webapp以在Tomcat 7.0.57中运行。 我准备所有我用预处理的成弹簧的Singleton StatementFactory像:DefaultPreparedStatement启动Tomcat时不可序列化

selectLikeShortnameStmt = cassandraDatasource.getSession().prepare(" select id, parent_id, ultimate_parent_id, internal_ref, short_name, long_name, controlling_team, " + 
               " country_incorp, country_operate, company_reg, relationship_manager, credit_rating, rating_source, pd, lgd, review_date, sector, defaulted, own_bank_entity " + 
               " from counterparty where short_name like ?"); 

selectByReviewDateAndRmQuery  = " select id, parent_id, ultimate_parent_id, internal_ref, short_name, long_name, controlling_team, " + 
              " country_incorp, country_operate, company_reg, relationship_manager, credit_rating, rating_source, pd, lgd, review_date, sector, defaulted, own_bank_entity " + 
              " from counterparty where filter_column = '{ " 
                 + " filter : {type:\"range\", field:\"review_date\", lower:\"01-01-2000\", upper: \"%s\" }," 
                 + " query : {type:\"contains\", field:\"relationship_manager\", values:[ \"%s\" ]}," 
                 + " refresh:true" 
                 + " }'"; 

在第一示例中,可以使用简单的BIND方法,但对于第二实施例中,绑定方法的状态没有定义绑定变量,所以我使用String.format方法,但是当我启动Tomcat时,出现错误,指出DefaultPreparedStatement不可序列化:

Caused by: java.io.NotSerializableException: com.datastax.driver.core.DefaultPreparedStatement 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
at java.util.HashMap.internalWriteEntries(HashMap.java:1785) 
at java.util.HashMap.writeObject(HashMap.java:1362) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
at java.util.HashMap.internalWriteEntries(HashMap.java:1785) 
at java.util.HashMap.writeObject(HashMap.java:1362) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333) 
at java.util.HashMap.writeObject(HashMap.java:1362) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) 
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441) 
at java.util.Collections$SynchronizedMap.writeObject(Collections.java:2691) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:498) 
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028) 
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496) 
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) 
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) 
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) 
at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:1695) 
at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1101) 
at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:430) 
at org.apache.catalina.session.StandardManager.unload(StandardManager.java:351) 
at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:516) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) 
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5683) 
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) 
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1591) 
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1580) 
... 4 more 

虽然代码根本不使用DefaultPreparedStatement。

在DAO对象,这些都是例子:

PreparedStatement pStmt = statementFactory.getSelectLikeShortnameStmt(); 
    BoundStatement bStmt = pStmt.bind("%" + name + "%"); 
    ResultSet rs = cassandraDatasource.getSession().execute(bStmt); 

String query = statementFactory.getSelectByReviewDateAndTeamQuery(); 

    query = String.format(query, upperDate, controllingTeamCode); 

    ResultSet rs = cassandraDatasource.getSession().execute(query); 
+0

为了缩小字段,我重写了代码,以便所有DAO对象都像第一个示例中那样使用PreparedStatement结构,而不像第二个示例中那样使用查询字符串,但它没有区别。查看javadoc,DefaultPreparedStatement是实现PreparedStatement接口的唯一类,但没有提到它是可序列化的。 – simteq

由于DefaultPreparedStatement是实现该接口的PreparedStatement唯一的类,它没有实现Serializable接口似乎有除了在Tomcat中禁用会话持久性之外没有别的选择,这可以通过编辑tomcat conf目录中的context.xml来实现