Подтвердить что ты не робот

Таблица аудита с использованием "Envers" в Spring Hibernate java project

Нам нужно провести аудит существующей таблицы с помощью envers. у нас нет hibernate.xml, а мы используем application-context.xml. И мы создаем схему через "Liquibase-changeet", затем как я могу создавать аннотации, такие как @Entity и @Audited.

Как решить эту проблему?

Я добавил настройки конфигурации спящего режима

<property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.ejb.event.post-insert">org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-update">org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-delete">org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.pre-collection-update">org.hibernate.envers.event.AuditEventListener</prop>
                <!-- <prop key="hibernate.ejb.event.pre-collection-remove">org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-collection-recreate">org.hibernate.envers.event.AuditEventListener</prop> -->
                <prop key="org.hibernate.envers.revision_field_name">REV</prop>
                <prop key="org.hibernate.envers.revision_type_field_name">REVTYPE</prop>
                <prop key="org.hibernate.envers.auditTablePrefix"></prop>
                <prop key="org.hibernate.envers.auditTableSuffix">_HISTORY</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>

Добавлена ​​@Аудированная аннотация в моем классе домена

@Entity
@Audited
@Table(name="user")
public class User implements Serializable {

Но эта конфигурация удалила мои существующие таблицы

например

Mydatabase
-----------

user
product
order_details
user_role
login

У меня есть 5 таблиц в моей базе данных. После запуска моего приложения он отображает 3 таблицы. Вместо создания таблицы "аудита" она удаляет существующую таблицу.

 Mydatabase
  -----------

  user
  product
  order_details

Как создать таблицу аудита (_HISTORY), не касаясь существующих таблиц???

4b9b3361

Ответ 1

В наборе изменений Liquibase определите определение таблицы аудита, как и для любой другой таблицы.

Пропустите свойство hibernate.hbm2ddl.auto в spring -hibernate ocnfiguration.That будет инструктировать спящий режим ничего не делать с этой схемой.

Сохраняя остальную часть вашей конфигурации, она должна работать.

Просто убедитесь, что имена таблиц аудита в схеме и в соответствии с конфигурацией.

Ссылка на документ, подробно описывающий, как его сделать, если схема сгенерирована с помощью ant

Ответ 2

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

  • изменить:

    <prop key="hibernate.hbm2ddl.auto">create</prop>
    

в

    <prop key="hibernate.hbm2ddl.auto">update</prop>
  1. Если вы работаете с ENVERS Hibernet-envers 3.5.5 или +, вы должны иметь эту конфигурацию в контексте приложения:

    <property name="eventListeners">
    <map>
    <entry key="post-insert" >
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>
    <entry key="post-update">
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>
    <entry key="post-delete">
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>
    <entry key="pre-collection-update">
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>
    <entry key="pre-collection-remove">
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>
    <entry key="post-collection-recreate">
    <bean class="org.hibernate.envers.event.AuditEventListener" />
    </entry>  
    </map>
    </property>
    
  2. Вы должны определить объект ревизии, такой как этот:

    @Entity    
    @Table(name = "MY_REVINFO")    
    @RevisionEntity(MyRevisionListener.class)//@see next class   
    public class MyRevisionEntity {            
        private static final long serialVersionUID =1L;
    
        @Id
        @GeneratedValue
        @RevisionNumber
        private int id;
    
        @RevisionTimestamp
        private long timestamp;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Transient
        public Date getRevisionDate() {
            return new Date(timestamp);
        }
    
        @Column(name = "USER_NAME")
        private String userName;
    
        @Column(name = "DATE_OPER")
        private Date dateOperation;
    
        public long getTimestamp() {
            return timestamp;
        }
    
        public void setTimestamp(long timestamp) {
            this.timestamp = timestamp;
        }
    
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof DefaultRevisionEntity)) return false;
    
            DefaultRevisionEntity that = (DefaultRevisionEntity) o;
    
            if (id != that.getId()) return false;
            if (timestamp != that.getTimestamp()) return false;
    
            return true;
        }
    
        public int hashCode() {
            int result;
            result = id;
            result = 31 * result + (int) (timestamp ^ (timestamp >>> 32));
            return result;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public Date getDateOperation() {
            return dateOperation;
        }
    
        public void setDateOperation(Date dateOperation) {
            this.dateOperation = dateOperation;
        }
    
        public String toString() {
            return "DefaultRevisionEntity(id = " + id + ", revisionDate = " + DateFormat.getDateTimeInstance().format(getRevisionDate()) + ")";
        }
    }
    
  3. Добавьте сопоставление этого нового объекта в свой application-context.xml как:

    <value>mypackage.MyRevisionEntity</value>
    
  4. Создайте слушателя (очень полезно, если вы хотите сохранить имя пользователя и время работы):

    public class MyRevisionListener implements RevisionListener {       
    public void newRevision(Object revisionEntity) {
    
        MyRevisionEntity revision = (MyRevisionEntity) revisionEntity;
    
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
    
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        String userName="---";
        if (userDetails != null) {
            userName=userDetails.getUsername();
        } else {
            userName="UNKNOWN";
        }
    
        revision.setUserName(userName);
        revision.setDateOperation(new Date(revision.getTimestamp()));
    }
    }
    
  5. Очистите, установите и запустите приложение.

  6. Если проблема не устранена, попробуйте обновить версию Envers (Hibrenate-envers и Hibernate-core)

Надеюсь на эту помощь.

Ответ 3

Попробуйте изменить стратегию DDL:

<prop key="hibernate.hbm2ddl.auto">create</prop>

в

<prop key="hibernate.hbm2ddl.auto">update</prop>

Стратегия генерации обновлений DDL не должна удалять существующую таблицу.

Ответ 4

Я работаю над проектом, использующим JPA с внедрением Hibernate, и нам удалось сделать работу без особых проблем, используя только конфигурацию на основе контекста x w760 > (мы не используем persistence.xml).

Наша конфигурация основана на поддержке JPA Spring JPA, но вы можете найти аналогичное решение:

    <bean id="projectEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
      </bean>
    </property>
    <property name="packagesToScan">
      <list>
        <value>com.teimas.myproject.bo</value>
        <value>com.teimas.myproject.bo.commons</value>
        <value>com.teimas.myproject.bo.util</value>
      </list>
    </property>
    <property name="persistenceUnitName" value="projectPU" />
    <property name="jtaDataSource" ref="projectDataSourceTarget" />
    <!-- Other ptops for hibernate config -->
    <property name="jpaProperties" ref="jpaHibernateProperties" />
  </bean>
  <util:properties id="jpaHibernateProperties">
    <prop key="hibernate.transaction.jta.platform">
      org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform
    </prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    <!-- validate | update | create | create-drop -->
    <prop key="hibernate.hbm2ddl.auto">validate</prop>
    <prop key="hibernate.show_sql">false</prop>
    <prop key="hibernate.format_sql">false</prop>
    <prop key="javax.persistence.transactionType">JTA</prop>
    <prop key="javax.persistence.validation.mode">AUTO</prop>
  </util:properties>

Ключ состоит в том, что мы используем в качестве поставщика JPA объект спящего режима: org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter и добавляем свойство packagesToScan, чтобы сообщить hibernate для сканирования аннотаций в этих пакетах. Таким образом, Hibernate находит Envers и Validation anotations, и все работает нормально.

Надеюсь, что это поможет.