RLK.JPA
退出时未关闭 EntityManager
如果资源经过分配,但使用后未得到妥当处置,将报告 RLK(资源泄漏)问题。未能正确处置资源可能导致如下的问题:
- 打开太多文件
- 应用程序无法在需要时访问临时文件
RLK.JPA 警告表明退出时未关闭 JPA 对象。
漏洞与风险
在返回之前必须明确关闭 entityManager 等资源,否则您将无法再访问该资源,保存到注册表的除外。
如果您不关闭资源,那么您的实体会一直保持为附加状态,即使相关实体已使用完毕。即使您已无法再访问您的 EM,您的上下文仍会保持活动状态。
缓解与预防
明确关闭所有具有关闭方法的资源,即使您认为不重要的资源亦应如此。这样将避免未来更改代码时出现这类错误。
漏洞代码示例 1
复制
public class ResourceLeakJpaEntityManager {
public void test() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Books");
}
}
Klocwork 在第 4 行报告 RLK.JPA 缺陷,指出:退出时未关闭 entityManagerFactory 对象。
修正代码示例 1
复制
public class ResourceLeakJpaEntityManager {
public void test() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Books");
entityManagerFactory.close();
}
}
在此示例中,Klocwork 不再报告缺陷,因为第 5 行的实体已关闭。
漏洞代码示例 2
复制
public class ResourceLeakJpaEntityManager {
public void test() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Books");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManagerFactory.close();
}
}
Klocwork 在第 5 行报告 RLK.JPA 缺陷,指出:退出时未关闭 entityManager 对象。
修正代码示例 2
复制
public class ResourceLeakJpaEntityManager {
public void test() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("Books");
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.close();
entityManagerFactory.close();
}
}
在此示例中,Klocwork 不再报告缺陷,因为实体已关闭。