如何在Spring中使用SQLErrorCodeSQLExceptionTranslator和DAO类与@Repository?

时间:2010-05-08 01:26:05

标签: java spring exception-handling spring-jdbc

我正在使用Spring 3.0.2,我有一个名为MovieDAO的类,它使用JDBC来处理数据库。我已经设置了@Repository注释,我想将SQLException转换为Spring的DataAccessException我有以下示例:

   @Repository
    public class JDBCCommentDAO implements CommentDAO {

        static JDBCCommentDAO instance;
        ConnectionManager connectionManager;

        private JDBCCommentDAO() {
            connectionManager = new ConnectionManager("org.postgresql.Driver", "postgres", "postgres");
        }

        static public synchronized JDBCCommentDAO getInstance() {
            if (instance == null)
                instance = new JDBCCommentDAO();
            return instance;
        }

        @Override
        public Collection<Comment> getComments(User user) throws DAOException {
            Collection<Comment> comments = new ArrayList<Comment>();
            try {
                String query = "SELECT * FROM Comments WHERE Comments.userId = ?";
                Connection conn = connectionManager.getConnection();
                PreparedStatement stmt = conn.prepareStatement(query);
                stmt = conn.prepareStatement(query);
                stmt.setInt(1, user.getId());
                ResultSet result = stmt.executeQuery();
                while (result.next()) {
                    Movie movie = JDBCMovieDAO.getInstance().getLightMovie(result.getInt("movie"));
                    comments.add(new Comment(result.getString("text"), result.getInt("score"), user, result.getDate("date"), movie));
                }
                connectionManager.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
                        //CONVERT TO DATAACCESSEXCEPTION
            }
            return comments;
        }
}

我不知道如何获得翻译器,我不想扩展任何Spring类,因为这就是我使用@Repository注释的原因

3 个答案:

答案 0 :(得分:4)

您必须提供bean-post处理器才能实现目标

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

或使用SQLExceptionSubclassTranslator

private SQLExceptionTranslator sqlExceptionTranslator = new SQLExceptionSubclassTranslator();

catch(SQLException e) {
    throw sqlExceptionTranslator.doTranslate("<WHICH_TASK>", "<WHICH_SQL_QUERY>", e);
}

代替

答案 1 :(得分:1)

JDBC与@Repository和自动异常转换不能很好地协同工作,因为SQLException不是运行时异常。 @Repository-style exception translation仅适用于使用运行时异常的数据访问API,例如Hibernate和JPA。

Spring上下文使用@Repository注释来自动生成DAO周围的代理包装器,在抛出异常时对其进行转换。但这仅适用于运行时异常。具体来说,如果您的DAO实现类方法抛出SQLException,那么您的接口方法签名也必须如此,代理包装器也必须如此,因此客户端代码必须处理该异常,这些异常都会使异常转换失败。

对于JDBC,通常需要通过扩展JdbcDaoSupport和使用getExceptionTranslator()或手动构建自己的SQLExceptionTranslator实例来与Spring API进行一些耦合。无论哪种方式,您都需要在DAO中捕获SQLException并将其转换为DataAccessException

答案 2 :(得分:0)

catch(SQLException e){

                    throw new DataAccessException("some message",e);
        }