2016-03-15 4 views
5

Я использую spring-data-envers в моем приложении загрузки весны. Я могу успешно регистрировать аудиты на своих объектах.Как найти все изменения для объекта с использованием переменных данных весны?

Теперь мне нужно показать проверенные данные пользователю в пользовательском интерфейсе. Подобно форме поиска, где пользователь может выбрать продолжительность и сущность, для которых он хочет видеть журналы аудита.

Редакция Репозиторий, предоставляемый строковыми данными, имеет только три метода.

@NoRepositoryBean 
public interface RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>> { 

    /** 
    * Returns the revision of the entity it was last changed in. 
    * 
    * @param id must not be {@literal null}. 
    * @return 
    */ 
    Revision<N, T> findLastChangeRevision(ID id); 

    /** 
    * Returns all {@link Revisions} of an entity with the given id. 
    * 
    * @param id must not be {@literal null}. 
    * @return 
    */ 
    Revisions<N, T> findRevisions(ID id); 

    /** 
    * Returns a {@link Page} of revisions for the entity with the given id. 
    * 
    * @param id must not be {@literal null}. 
    * @param pageable 
    * @return 
    */ 
    Page<Revision<N, T>> findRevisions(ID id, Pageable pageable); 
} 

Как написать пользовательский запрос, чтобы получить все изменения, для сущности между двумя датами конкретным пользователем.

Обратите внимание, что я добавил дополнительные столбцы в таблицу user_rev_entity, где храню идентификатор пользователя и измененную дату. Если я присоединяюсь к этой таблице с помощью таблицы entity_aud, я могу получить результаты.

Ниже приведены сценарии моих таблиц аудита.

CREATE TABLE `user_rev_entity` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `timestamp` bigint(20) NOT NULL, 
    `created_by` bigint(20) NOT NULL, 
    `created_date` datetime NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 

CREATE TABLE `revchanges` (
    `rev` int(11) NOT NULL, 
    `entityname` varchar(255) DEFAULT NULL, 
    KEY `FK_et6b2lrkqkab5mhvxkv861n8h` (`rev`), 
    CONSTRAINT `FK_et6b2lrkqkab5mhvxkv861n8h` FOREIGN KEY (`rev`) REFERENCES `user_rev_entity` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

CREATE TABLE `roles_aud` (
    `role_id` bigint(20) NOT NULL, 
    `rev` int(11) NOT NULL, 
    `revtype` tinyint(4) DEFAULT NULL, 
    `description` varchar(255) DEFAULT NULL, 
    `description_mod` bit(1) DEFAULT NULL, 
    `display_name` varchar(255) DEFAULT NULL, 
    `display_name_mod` bit(1) DEFAULT NULL, 
    `is_enabled` bit(1) DEFAULT NULL, 
    `enabled_mod` bit(1) DEFAULT NULL, 
    `title` varchar(255) DEFAULT NULL, 
    `title_mod` bit(1) DEFAULT NULL, 
    PRIMARY KEY (`role_id`,`rev`), 
    KEY `FK_pkqm51vsc35w2axvnns4bpas9` (`rev`), 
    CONSTRAINT `FK_pkqm51vsc35w2axvnns4bpas9` FOREIGN KEY (`rev`) REFERENCES `user_rev_entity` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

Итак, в основном я ищу все изменения, сделанные конкретным пользователем в определенное время, когда сущность скажет Роль.

Будет больше таких сущностей.

ответ

1

Spring Data Envers не поддерживает пользовательские запросы, например, для весенних данных jpa. Все это обеспечивает удобный интерфейс RevisionRepository.

Однако вы можете использовать метод Revisions<N, T> findRevisions(ID id) и применять фильтр со своего уровня обслуживания. Вот пример.

@Service 
public UserService { 
    @Resource 
    private UserRepository userRepository; 

    public List<Revision<Integer, User>> findRevisionsBetweenDates(int id, Date startDate, Date endDate){ 
     return userRepository.findRevisions(id).getContent().stream().filter(
      revision -> revision.getEntity().getCreatedDate().getTime() > startDate.getTime() && 
       revision.getEntity().getCreatedDate().getTime() < endDate.getTime() 
     ).collect(Collectors.toList()); 
} 

Это не идеально подходит, так как вы получите все исправления из базы данных. Тем не менее, это самый простой способ сохранить абстракцию из базы данных.

В противном случае вам необходимо пропустить Spring Data Envers и работать с API Envers.

Успехов, С уважением

+0

* не идеально подходит, так как вы будете получать все изменения, из базы данных *. Думаю, вы можете сказать, что дважды, таблица истории должна быть самой тяжелой в базе данных, это окончательно здесь, что вы не хотите отправлять фильтры. – Walfrat

1

Вы смотрели на AuditReaderFactory и AuditReader?

Заканчивать документацию для AuditReader-х createQuery:

творца запрос, связанный с этим AuditReader, например, с помощью которой запросы могут быть созданы, а затем выполняется.

Это возвращает AuditQueryCreator, который можно использовать для создания запроса, например, так:

AuditQuery query = getAuditReader().createQuery() 
.forRevisionsOfEntity(MyEntity.class, false, true); 

Есть несколько вариантов для forRevisionsOfEntity, см AuditQueryCreator документацию.

Запрос должен позволить вам выбрать конкретные изменения, с помощью AuditCriterion

гибернации Envers документации, относящейся к этому: http://docs.jboss.org/hibernate/orm/5.0/userGuide/en-US/html_single/#revisions-of-entity

Вы можете добавить ограничения на этот запрос таким же образом, как в предыдущем , Есть некоторые дополнительные возможности:

  1. с использованием AuditEntity.revisionNumber() можно указать ограничения, прогнозы и порядок на номер ревизии, в которой проверяемое объект был изменен
  2. аналогично, используя AuditEntity.revisionProperty (ИмениСвойства) вы можете указать ограничения, проекция и порядка на свойстве пересмотра объекта, соответствующий пересмотр, в котором было изменен проверяемое лицо
  3. AuditEntity.revisionType() дает доступ как указано выше, тип ревизии (ADD, MOD, DEL).

РЕДАКТИРОВАТЬ я дал выстрел в фактическое решение. У меня мало шансов на переживание и спящий режим, так что это может быть неправильно, но, возможно, это поможет вам начать работу.

AuditQuery query = getAuditReader().createQuery() 
     .forRevisionsOfEntity(MyEntity.class, false, true); 

query.add(AuditEntity.revisionProperty("createdDate").gt(minDate)) 
     .add(AuditEntity.revisionProperty("createdDate").lt(maxDate)) 
     .add(AuditEntity.revisionProperty("createdBy").eq(userId)); 

//the documentation shows getSingleResult returns a number 
//so i'm guessing a resultList also contains numbers 
List<Number> resultList = query.getResultList(); 
1

Еще один вопрос, метод findRevisions внутренне использует SQL В статье, которая будет выполнена, если записи более чем 999.

Смежные вопросы