Eclipse显示警告消息“资源泄漏,预备状态未在以下位置关闭”
对我而言,看起来finally块负责关闭preparedstatement和rs对象。知道为什么eclipse仍在抱怨资源泄漏吗?
String ruleGrpId = null;
int finalRuleID = 0;
String saveRule1 = "INSERT INTO ..";
String saveRule2 = "INSERT INTO ";
String saveRule3 = "select ..._name = ?";
PreparedStatement preparedstatement = null;
ResultSet rs = null;
try {
if (objSomeRule.getRule() == 0) {
preparedstatement = con.prepareStatement(saveRule1);
preparedstatement.setString(1, ruleId);
preparedstatement.executeUpdate();
//Eclipse complains here
preparedstatement = con.prepareStatement(saveRule2);
preparedstatement.setInt(1, ruleID_2);
preparedstatement.setString(2, ruleID_3);
rs = preparedstatement.executeQuery();
if(rs.next()){
finalRuleID = rs.getInt(1);
}else{
//complains here
preparedstatement = con.prepareStatement(saveRule3);
preparedstatement.setString(1, ruleID_4);
//complains here
rs = preparedstatement.executeQuery();
if(rs.next()){
finalRuleID = rs.getInt("rulegroup_id");
}
}
objSomeRule.setRuleID(finalRuleID);
}
} finally {
if(preparedstatement != null){
preparedstatement.close();
}
if(rs != null){
rs.close();
}
}
return finalRuleID;
}
答案 0 :(得分:2)
所以,你说当没有记录创建另一个preparedStatement时。
if(rs.next())
{
finalRuleID = rs.getInt(1);
}
else
{
//close here first
if(preparedstatement != null)
{
preparedstatement.close();
}
if(rs != null){
rs.close();
}
preparedstatement = con.prepareStatement(saveRule3);
// your code
但是,你还没有关闭前一个。我不确定,你为什么这样做,但是,假设你需要这样做。然后,你应该先关闭前一个。
答案 1 :(得分:2)
您创建了3个PreparedStatement
的不同实例:
preparedstatement = con.prepareStatement(saveRule1);
preparedstatement = con.prepareStatement(saveRule2);
preparedstatement = con.prepareStatement(saveRule3);
您的变量preparedStatement
仅保留您打开的最后一个变量
而且你没有引用你之前打开的其他人
因此,在finally
部分中,您只能关闭最后一个PreparedStatement
:
preparedstatement.close();
类似的问题在于您的ResultSet
。
您创建了2个实例,但只关闭了其中的一个。
答案 2 :(得分:2)
重用变量preparedStatement
和rs
会阻止对变量的旧对象值调用close()
。 Try-with-resources是一个很好的解决方案,因为close()
会被自动调用,即使抛出异常或在深层嵌套的try中执行返回也是如此。
String ruleGrpId = null;
int finalRuleID = 0;
String saveRule1 = "INSERT INTO ..";
String saveRule2 = "INSERT INTO ";
String saveRule3 = "select ..._name = ?";
if (objSomeRule.getRule() == 0) {
try (PreparedStatement ps1 = con.prepareStatement(saveRule1)) {
ps1.setString(1, ruleId);
ps1.executeUpdate();
}
try (PreparedStatement ps2 = con.prepareStatement(saveRule2)) {
ps2.setInt(1, ruleID_2);
ps2.setString(2, ruleID_3);
try (ResultSet rs2 = ps2.executeQuery()) {
if (rs2.next()) {
finalRuleID = rs2.getInt(1);
} else {
try (Preparedstatement ps3 = con.prepareStatement(saveRule3)) {
ps3.setString(1, ruleID_4);
//complains here
try (ResultSet rs3 = ps3.executeQuery()) {
if (rs3.next()) {
finalRuleID = rs3.getInt("rulegroup_id");
}
}
}
}
}
objSomeRule.setRuleID(finalRuleID);
}
}
如果最后一个SELECT查询打算检索先前INSERT的AUTOINCREMENT ID,那么使用getGeneratedKeys