gpt4 book ai didi

hibernate - Envers 查询 - 返回 REVTYPE 以及修改的字段

转载 作者:行者123 更新时间:2023-12-01 12:21:42 25 4
gpt4 key购买 nike

我需要在 UI 上显示实体的修改历史。像这样的 -

    |-------------------------------------------------------------------------------------------------------------------------------------|    |Entity name  |  Entity ID  |  Action by  |  Action on           |  Action Type  |  Old value               |  New value              |    |-------------|-------------|-------------|----------------------|---------------|--------------------------|-------------------------|    |Person       |     1       |   John Doe  | 2017-04-12 12:00:00  |   Add         |                          | name: Lily, Role: Admin |    |Person       |     1       |   John Doe  | 2017-04-15 12:00:00  |   Update      |name: Lily                | name: Lily Smith        |    |Subject      |     5       |   Mary      | 2017-04-17 12:00:00  |   Update      |name: Maths               | name: Mathematics       |    |Subject      |     6       |   Mary      | 2017-04-17 12:00:00  |   Delete      |name: Science, credits: 5 |                         |    |-------------------------------------------------------------------------------------------------------------------------------------|

我使用 Hibernate envers 来存储我需要的所有数据。但是我在读取所有数据以显示上面我需要的内容时遇到问题。我在互联网上搜索了很多博客、问题文章、文档、javadoc,但没有一个显示如何执行此操作。它们都展示了如何根据修订或返回修订检索实体。除了返回的实体之外,这些实体都没有以下信息 -

  1. 谁做了改变
  2. 这种变化是什么时候发生的
  3. 它是什么类型的变化。添加/更新/删除

请注意,我希望尽可能少的查询来加快历史 API 响应。

我正在使用 hibernate 和 envers 版本:'5.2.9.Final'

非常感谢任何帮助。

谢谢!

更新

这是代码-

每个实体类上面的注解-

    @Audited(withModifiedFlag = true)

自定义修订监听器 -

    public class CustomRevisionListener implements RevisionListener {        private static final Logger logger =         LogManager.getLogger(CustomRevisionListener.class);        public void newRevision(Object revisionEntity) {            logger.info("newRevision, starts revisionEntity="+revisionEntity);            CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity;            String name = "unknown";            try{                //user custom userdetails.User to store id and name both?                 //or just store id in string format here?                org.springframework.security.core.userdetails.User springUser =                         (org.springframework.security.core.userdetails.User)  SecurityContextHolder                        .getContext().getAuthentication().getPrincipal();                name = springUser.getUsername(); //get logged in username            }catch(Exception e){                logger.error("error getting username", e);            }            logger.info("newRevision, name="+name);            User user = new User();            user.setName(name);            revision.setUser(user); //for testing            logger.info("newRevision, setting userId="+user.getId());        }    }

自定义修订实体 -

    @Entity    @Table(name="REVISIONS")    @RevisionEntity(CustomRevisionListener.class)    public class CustomRevisionEntity extends DefaultRevisionEntity {        private static final long serialVersionUID = -6113123831136684807L;        @ManyToOne        @JoinColumn(name="USER_ID")        private User user;        public User getUser() {            return user;        }        public void setUser(User user) {            this.user = user;        }    }

envers 配置 -

    org.hibernate.envers.track_entities_changed_in_revision=true    org.hibernate.envers.global_with_modified_flag=true    org.hibernate.envers.store_data_at_delete=true    org.hibernate.envers.audit_strategy=org.hibernate.envers.strategy.ValidityAuditStrategy    org.hibernate.envers.audit_strategy_validity_store_revend_timestamp=true

阅读审核 -

        public List getAllAudits() {            logger.debug("getAllAudits starts");            //HERE IS WHERE I NEED HELP.            //below code is just for trials. I need something which will read all audits and relevant info I described above            ArrayList list = (ArrayList) AuditReaderFactory.get(entityManager)                     .createQuery()                     .forRevisionsOfEntity(Organization.class, true, true)     //              .add(AuditEntity.id().eq(bitacoraControlId))                     .addOrder(AuditEntity.revisionNumber().asc())                     .getResultList();            for(int i=0; i  revisions = reader.getRevisions(Organization.class, 2);            for(Number revNum:revisions){                Organization article =reader.find(Organization.class, 2, revNum);                System.out.println("Revision No: " + revNum);                System.out.println("Title: " + article.getId());                System.out.println("Content: " + article.getName());                    }            logger.debug("getAllAudits list size="+list.size());            return list;        }

最佳答案

好的,所以我找到了答案。这是我必须分别阅读每种类型的实体的审计并将它们合并到一个列表中的方法 -

    AuditQuery query = AuditReaderFactory.get(entityManager)
.createQuery()
.forRevisionsOfEntity(clazz, false /*IMP*/, true)
.addOrder(AuditEntity.revisionNumber().desc());

//This return a list of array triplets of changes concerning the specified revision.
// The array triplet contains the entity, entity revision information and at last the revision type.
ArrayList<Object[]> list = (ArrayList) query.getResultList();

for(int i=0; i < list.size(); i++){
Object[] triplet = list.get(i);

BaseEntity entity = (BaseEntity) triplet[0];
CustomRevisionEntity revisionEntity = (CustomRevisionEntity) triplet[1];
RevisionType revisionType = (RevisionType) triplet[2];

...//populate DTO
}

如果 RevisionType 是“MOD” 要仅使用已更改的字段获取旧值和新值,我必须获取以前的版本并逐个字段进行比较。虽然Envers确实在表格中记录了这个字段的修改信息,但是并没有提供很好的读取方式。

 public BaseEntity getPreviousVersion(BaseEntity entity, int current_rev) {

AuditReader reader = AuditReaderFactory.get(entityManager);

Number prior_revision = (Number) reader.createQuery()
.forRevisionsOfEntity(entity.getClass(), false, true)
.addProjection(AuditEntity.revisionNumber().max())
.add(AuditEntity.id().eq(entity.getId()))
.add(AuditEntity.revisionNumber().lt(current_rev))
.getSingleResult();

if (prior_revision != null)
return reader.find(entity.getClass(), entity.getId(), prior_revision);
else
return null;
}

关于hibernate - Envers 查询 - 返回 REVTYPE 以及修改的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43580238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com