2017-01-19 12 views
1

У нас есть объект со значением String, который может меняться очень часто, поэтому мы использовали @NotAudited. Но это приводит к тому, что столбец является нулевым в таблице аудита (понятно).Envers - вставить фактическое значение поля @NotAudited

Мы хотим вставить фактическое значение свойства String в таблицу аудита, если сущность (одна из ее проверенных столбцов) изменяется, но не хочет вставлять новую запись в таблицу аудита, если упомянутая Изменяется свойство строки.

Как я могу это сделать?

ответ

2

Опишите, что мы называем условным аудитом, который вы можете найти в документации Envers.

Основной принцип заключается в том, что вы по-прежнему аннотирование свойства с @Audited но определить, скорее всего, изменилось ли любое другое имущество в течение PostUpdateEvent и если ваше специфическое свойство является все, что изменилось, вы бы не делегировать PostUpdateEvent к Включает реализацию прослушивателя по умолчанию.

Некоторые псевдо-код может выглядеть примерно так:

public class CustomEnversPostUpdateEventListener 
     extends EnversPostUpdateEventListenerImpl { 
    public CustomEnversPostUpdateEventListener(EnversService enversService) { 
     super(enversService); 
    } 

    @Override 
    public void onPostUpdate(PostUpdateEvent event) { 
     final String entityName = event.getPersister().getEntityName(); 
     if (getEnversService().getEntityConfigurations().isVersioned(entityName)) { 
     if (MySpecialEntity.class.getName().equals(entityName)) { 
      // Compare event.getState() against event.getOldState() 
      // Determine if only your special String changed or not 
      if (!otherFieldsChangedBesidesSpecialProperty) { 
      return; 
      } 
     } 
     // delegate to default implementation 
     super.onPostUpdate(event); 
     } 
    } 
} 

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

Подложное решение - цель HHH-11326. То, что я хотел бы представить, было бы JPA-подобной концепцией, в которой @AuditListener может быть помещен в проверяемый класс сущностей, а Envers вместо этого делегирует на реализацию listener для этого поведения.

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

public class MyEntityAuditListener extends AbstractAuditListener { 
    @Override 
    public boolean onPostUpdate(EnversPostUpdateEvent event) { 
     // return true = allow the audit operation 
     // return false = veto the audit operation 
     if (event.getPropertyChangeCount() != 1) { 
     return true; 
     } 
     return !event.isPropertyChanged("mySpecialString");  
    } 
} 

@Entity 
@Audited 
@AuditListener(MyEntityAuditListener.class) 
public class MyEntity { 
    // ... 
    private string mySpecialString; 
} 

Приятная часть состоит в том, что EnversPostUpdateEvent позволяет нам абстрагироваться от многих внутренних элементов Envers, предоставляя чистый API, который позволяет пользователям принимать легкие решения о том, налагать ли вето на операцию аудита, не зная о том, как события Hibernate или внутренняя часть Envers работает.

Как указывает JIRA, эта новая концепция @AuditListener - это то, что я планирую представить в следующем выпуске Hibernate Envers 6.0 в ближайшие месяцы.

+0

Мне действительно понравилось бы, если бы это было сделано в выпуске 5.X :) –

+0

Не забудьте проголосовать за JIRA, если вы этого не сделали. – Naros