2013-04-26 2 views
0

ejb 3.0 jboss 6 환경에서 sql 쿼리를 실행하기 위해 많은 DAO 클래스에 주입되는 DBInterface라는 빈을 가지고 있습니다. DBInterface 빈에는 필드 변수로 데이터 소스가 삽입됩니다. DBInterface 빈의 모든 메소드는 삽입 된 데이터 소스로부터 데이터베이스 연결을 가져오고 db 호출을 처리 한 후 연결을 닫습니다. 시간이 좀 걸리면 응용 프로그램을 실행하는 동안 DB 연결을 만들 수 없다는 SQL 예외가 발생합니다. finally 블록의 모든 메서드 호출에서 연결을 닫습니다. 어디에서 오류를 만들고 있습니까? jboss에서 ejb 3.0을 사용합니다. 모든 자원을 닫는 당신은 시도 - catch 블록을 사용한다 관련 VEJB 3.0 Managed Bean 삽입 및 db 연결 닫기

public class DBInterface { 
    @Resource(mappedName = "java:ora.ds", type = DataSource.class) 
    private static DataSource dataSource; 
    protected Connection getConnection(){ 
     try { 
     return dataSource.getConnection(); 
     } catch (SQLException e) { 
     e.printstacktrace(); 
     } 
    } 
    public void method1() { 
     Connection connection = null; 
     try { 
       connection = getConnection(); 
       ............... 
       db codes 
       ................. 
     } catch (SQLException e) { 
     logger.error(e); 
     throw new DBException("sql exception ", e); 
     } finally { 
      try { 
        closeResources(rs, statement, connection); 
      } catch (SQLException e) { 
        logger.error(e); 
        throw new DBException("sql exception ", e); 
      } 
     } 
    } 
    public void closeResources(ResultSet rs, Statement st, Connection con) 
     throws SQLException { 
      if (rs != null) { 
      rs.close(); 
      } 
      if (st != null) { 
       st.close(); 
      } 
      if (con != null) { 
      con.close(); 
     } 

     } 
} 
+1

고정 필드에 데이터 소스를 삽입하지 마십시오 ... –

+0

도 리소스를 별도의 try-catch 블록으로 닫아야합니다. –

+0

네가 맞다. 데이터 소스에 정적을 더 이상 사용하지 않는다. 죄송합니다. 이전 테스트 코드를 붙여 넣었습니다. 별도의 try-catch 블록은 무엇을 의미합니까? 나는이 코드에서 볼 수없는 또 다른 실수가 있습니까? –

답변

1

. 이것은 AbstractDAO 클래스를 사용하여 쉽게 읽을 수 뭔가 리팩토링 할 수

if (rs != null) { 
    try { 
     rs.close(); 
    } catch (Exception exception) { 
     logger.log("Failed to close ResultSet", exception); 
    } 
} 
if (st != null) { 
    try { 
     st.close(); 
    } catch (Exception exception) { 
     logger.log("Failed to close Statement", exception); 
    } 
} 
if (con != null) { 
    try { 
     con.close(); 
    } catch (Exception exception) { 
     logger.log("Failed to close Connection", exception); 
    } 
} 

:

if (rs != null) { 
    rs.close(); 
} 
if (st != null) { 
    st.close(); 
} 
if (con != null) { 
    con.close(); 
} 
를 교체해야합니다

public class DAOException extends RuntimeException { 
    public DAOException(Throwable cause) { 
     super(cause); 
    } 
} 

public abstract class AbstractDAO { 
    private static Logger logger = ...; 
    private DataSource dataSource; 

    protected void setDataSource(DataSource dataSource) { 
     this.dataSource = dataSource; 
    } 

    public Connection getConnection() { 
     try { 
      return dataSource.getConnection(); 
     } catch (SQLException exception) { 
      // There's nothing we can do 
      throw new DAOException(exception); 
     } 
    } 

    public void close(Connection connection) { 
     try { 
      connection.close(); 
     } catch (Exception exception) { 
      // Log the exception 
      logger.log("Failed to close Connection", exception); 
     } 
    } 

    public void close(Statement statement) { 
     try { 
      statement.close(); 
     } catch (Exception exception) { 
      // Log the exception 
      logger.log("Failed to close Statement", exception); 
     } 
    } 

    public void close(ResultSet resultSet) { 
     try { 
      resultSet.close(); 
     } catch (Exception exception) { 
      // Log the exception 
      logger.log("Failed to close ResultSet", exception); 
     } 
    } 
} 

public class MyDAO extends AbstractDAO { 
    @Override 
    @Resource("jdbc/myDS") 
    protected void setDataSource(DataSource dataSource) { 
     super.setDataSource(dataSource); 
    } 

    public void insert(MyObject myObject) { 
     Connection connection = getConnection(); 
     try { 
      PreparedStatement query = connection.createPreparedStatement("INSERT INTO MYOBJECT (ID, VALUE) VALUES (?, ?)"); 
      try { 
       query.setLong(1, myObject.getID()); 
       query.setString(2, myObject.getValue()); 
       if (query.executeUpdate() != 1) { 
        throw new DAOException("ExecuteUpdate did not return expected result"); 
       } 
      } finally { 
       close(query); 
      } 
     } catch (SQLException exception) { 
      // There's nothing we can do 
      throw new DAOException(exception); 
     } finally { 
      close(connection); 
     } 
    } 
} 

내가 궁금하네요 것은 왜 때로 믿을 수 있다는 것입니다 JPA를 사용하고 있습니까? 캐싱의 이점이없는 성능이 중요한 응용 프로그램에만 JDBC를 사용하는 것을 고려할 것입니다.

+0

JPA를 사용하지 않는 이유는 제 3 자에 의해 정기적으로 업데이트되는 데이터 복잡성 때문입니다. 따라서 JPA가 도움이되지 않는 곳에서는 쿼리를 사용해야합니다. –

+0

나는 테이블 구조가 바뀔 때마다 sql-queries를 업데이트하는 대신에 뷰를 사용할 것이다. –