Java EJB3.0托管bean注入和数据库连接关闭
在EJB3.0JBoss6环境中,我有一个名为DBInterface的bean,它被注入到许多dao类中以执行sql查询。DBInterface bean将数据源作为字段变量注入。DBInterface bean中的所有方法都从注入的数据源获取数据库连接,并在处理db调用后关闭连接。在运行应用程序时,经过一段时间后,我收到一个sql异常,表示无法创建db连接。我正在关闭finally块中每个方法调用的连接。我在哪里出错?我在jboss中使用EJB3.0。 当做 五Java EJB3.0托管bean注入和数据库连接关闭,java,jdbc,ejb-3.0,cdi,jboss6.x,Java,Jdbc,Ejb 3.0,Cdi,Jboss6.x,在EJB3.0JBoss6环境中,我有一个名为DBInterface的bean,它被注入到许多dao类中以执行sql查询。DBInterface bean将数据源作为字段变量注入。DBInterface bean中的所有方法都从注入的数据源获取数据库连接,并在处理db调用后关闭连接。在运行应用程序时,经过一段时间后,我收到一个sql异常,表示无法创建db连接。我正在关闭finally块中每个方法调用的连接。我在哪里出错?我在jboss中使用EJB3.0。 当做 五 您应该使用try-catch块
您应该使用try-catch块来关闭任何资源
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
应替换为:
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);
}
}
可以使用AbstractDAO类将其重构为更易于阅读的内容:
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,而这些应用程序不会从缓存中获益。不要将数据源注入静态字段…还要确保在单独的try-catch块中关闭资源。如果你是对的,我不再将静态用于数据源。对不起,我把旧的测试代码粘贴在这里了。你所说的独立试捕块是什么意思?我在这段代码中没有看到任何其他错误?我将把它作为一个答案发布,因为我不能在这里发布代码。我不使用JPA的原因是由于第三方定期更新数据的复杂性。所以我需要在JPA帮不了我的几个地方使用查询,我可能会使用视图,而不是每次表结构改变时更新sql查询。
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);
}
}
}