12

我需要为我的 Java Web App创建一个审计模块。我使用 EclipseLink,而不是 Hibernate(不能使用 Envers)。我搜索了很多方法来获取 JPA 正在执行的 SQL 或 JPQL,所以我可以记录如下内容:

System.out.println("User " + user + " from " + ip_address + " executed " + jpa_statement + " at " + new Date());

实际上,我会将这些信息保存到历史数据库的表中。因此,我可以随时轻松检索此信息。这就是为什么“ SHOW SQL ”参数对我来说还不够。我真的需要 SQL 字符串,所以我可以在我的源代码中操作它。

我在 JPA 规范中发现了EntityListener功能,并认为这是放置我的日志记录代码的理想场所。例如,postUpdate 方法可以记录对象的更新时间。但我的问题是我无法执行 SQL。

这是我的意思的一个例子:

public class AuditListener {    
  @PostUpdate
  public void postUpdate(Object object) {
    User user = (User)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
    String ip_address =  (User)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("ip_address");
    String jpa_statement = object.getSQL();
    System.out.println("User " + user + " from " + ip_address + " executed " + jpa_statement + " at " + new Date());
  }

}

但是“object.getSQL()”不存在。那么如何获取 SQL 语句呢?

如果有人能指出我正确的方向,我将不胜感激!

4

3 回答 3

13

EclipseLink 完全支持历史跟踪。

见, http://wiki.eclipse.org/EclipseLink/Examples/JPA/History

JPA 事件不包含更改的内容,仅包含对象。

EclipseLink 还支持 DesriptorEvents(请参阅 DescriptorEventListener),它还定义了一个 postUpdate,但包含一个描述更改的 ObjectChangeSet,您还拥有包含 SQL 和 DatabaseRecord 的 UpdateObjectQuery。

于 2011-10-13T14:50:17.317 回答
6

用于审计的 Envers 很棒,但我认为,可以有更好的审计解决方案。Envers 有一些缺点: 每个表有两个 db 表。但是第二张表很少使用。对于我们有 600 多张表的大型企业项目来说,这是个问题。Envers 仅适用于数据库更改。当我需要解决其他应用程序组件的审计时,我需要不同的审计解决方案。对集合的审计并不理想。何时更改数据库架构我也必须更改审计表。我可能会丢失一些审计信息,或者我有很多工作需要将旧审计信息更新到新模式。将审计信息保存到同一个数据库既费时又费空间。

我开始研究小型审计库,其中信息存储在 MongoDB 数据库中: 对所有休眠对象使用一个集合。存储对象的每个值。审计在不同的线程中完成。集合(ID 列表)也被存储。相同的 MongoDB 数据库用于其他应用程序日志。

有人对这个或类似的解决方案有一些经验吗?

于 2013-06-04T07:21:17.733 回答
3

我通常建议把应用服务器做成审计,很多都有审计能力。例如,我最近做了一个项目,其中审计数据存储在单独的应用程序服务器上的单独数据库中。我们使用 Glassfish 审计模块功能。将审计的关注点从应用程序中分离出来。

于 2017-09-22T16:59:21.220 回答