【问题标题】:SimpleJdbcTemplate not serializableSimpleJdbcTemplate 不可序列化
【发布时间】:2011-09-13 04:30:48
【问题描述】:

我使用 JSF 和 Spring。 JSF bean 在设计上必须是可序列化的。 JSF bean 被注入处理数据库访问的 Spring bean。因此,这些 bean 也必须是可序列化的。但是 simpleJdbcTemplate 是不可序列化的,因此在重新启动 servlet 时我会得到堆栈跟踪,并且会话丢失。如果我声明 simpleJdbcTemplate 是瞬态的,我不会得到关于“不可序列化”的堆栈跟踪,但是 simpleJdbcTemplate 有时在重新启动后为 NULL,这更糟。

那么,当 servlet 重新启动时,我该怎么做才能让 spring bean 注入一个“新鲜的”simpleJdbcTemplate?

类如下所示:

@Repository
public class Users implements Serializable
{
    @Autowired
    private SimpleJdbcTemplate simpleJdbcTemplate;

    // ...
}


@ManagedBean
@SessionScoped
public class ThisBean implements Serializable
{
    @ManagedProperty(value = "#{users}")
    private Users users;
    public void setUsers(Users users)
    {
        this.users = users;
    }

    // ...
}

现在是一些配置文件,只是为了让您看到我没有遗漏一些标准。

web.xml 有这个:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
    <listener-class>Listeners.SessionListener</listener-class>
</listener>

applicationContext.xml 有这个:

<context:annotation-config />
<context:component-scan base-package="SpringDB"/>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/mysql"/>
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
    <constructor-arg>
        <ref bean="dataSource"/>
    </constructor-arg>
</bean>

faces-config.xml 有这个:

<application>
    <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
    <application>
        <message-bundle>jsf</message-bundle>
    </application>
</application>

【问题讨论】:

    标签: spring jsf


    【解决方案1】:

    为什么不尝试传入 DataSource 引用而不是 JdbcTemplate。常见的做法是注入数据源并在数据源的 setter 中创建 JdbcTemplate。您将在 spring 文档中找到以下示例:

    
    public class JdbcCorporateEventDao implements CorporateEventDao {
    
        private JdbcTemplate jdbcTemplate;
    
        public void setDataSource(DataSource dataSource) {
            this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
    
        // JDBC-backed implementations of the methods on the CorporateEventDao follow...
    }
    

    如果您不想使用 XML 设置 bean,也可以在 setDataSource 方法上使用 @Autowired。有关更多详细信息,请查看优秀 spring 文档的JdbcTemplate best practices 部分。

    【讨论】:

    • 谢谢... 可悲的是,很难判断它是否有效 - 问题已转移到另一个“黑暗”区域:SCHWERWIEGEND: 来自持久存储的异常加载会话 java.lang.ClassNotFoundException: SpringDB.xxxxxxDAO$ $EnhancerByCGLIB$$6882b86f 这与我使用 @Transactional 和 cglib 代理有关:-(
    • 我在没有 @Transactional 的情况下进行了测试,得到了 NullPointerException。跟踪显示未调用 setDataSource() :-(
    【解决方案2】:

    为 simpleJDBCTemplate bean 添加 scope="prototype" 定义。然后 Spring Framework 将为每个 servlet 实例创建新实例。有关 bean 范围的更多信息:http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      相关资源
      最近更新 更多