java之Hibernate Envers 不使用 SpringMVC 配置在审计表中写入任何内容

birdshome 阅读:25 2023-08-02 22:59:51 评论:0

当我保存、更新或删除数据库中的条目时,我正在尝试使用 Enverse 来审核表。

Envers 配置如下:

pom.xml

        <!-- Spring --> 
        <org.springframework-version>4.1.6.RELEASE</org.springframework-version> 
 
        <!-- Hibernate  --> 
        <hibernate.version>4.3.5.Final</hibernate.version> 
[...] 
 
    <!-- Hibernate --> 
        <dependency> 
            <groupId>org.hibernate</groupId> 
            <artifactId>hibernate-entitymanager</artifactId> 
            <version>${hibernate.version}</version> 
        </dependency> 
        <dependency> 
            <groupId>org.hibernate</groupId> 
            <artifactId>hibernate-envers</artifactId> 
            <version>${hibernate.version}</version> 
        </dependency> 

我的jpa-tx-config.xml

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter"> 
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
    </property> 
    <property name="packagesToScan" value="my.domain"/> 
 
    <property name="persistenceUnitName" value="persistenceUnit"/> 
    <property name="jpaProperties"> 
        <props> 
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> 
            <prop key="hibernate.hbm2ddl.auto">update</prop>  
            <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> 
            <prop key="hibernate.connection.charSet">UTF-8</prop> 
 
            <prop key="hibernate.max_fetch_depth">3</prop> 
            <prop key="hibernate.jdbc.fetch_size">50</prop> 
            <prop key="hibernate.jdbc.batch_size">20</prop> 
            <prop key="hibernate.show_sql">false</prop> 
            <prop key="hibernate.format_sql">true</prop> 
 
            <prop key="org.hibernate.envers.audit_table_suffix">_H</prop> 
            <prop key="org.hibernate.envers.revision_field_name">AUDIT_REVISION</prop> 
            <prop key="org.hibernate.envers.revision_type_field_name">ACTION_TYPE</prop> 
            <prop key="org.hibernate.envers.audit_strategy">org.hibernate.envers.strategy.ValidityAuditStrategy</prop> 
            <prop key="org.hibernate.envers.audit_strategy_validity_end_rev_field_name">AUDIT_REVISION_END</prop> 
            <prop key="org.hibernate.envers.audit_strategy_validity_store_revend_timestamp">True</prop> 
            <prop key="org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name">AUDIT_REVISION_END_TS</prop>                
            <prop key="jadira.usertype.databaseZone">jvm</prop> 
        </props> 
    </property> 
</bean> 

我的每个域类都有 @Audited 注释,但在 DB 中,此字段永远为 null

我不明白哪里出了问题,有什么建议吗?

编辑

作为对评论的回应:每个实体类都扩展了一个实现可审核方式的抽象域。按照代码:

   @SuppressWarnings("serial") 
@MappedSuperclass 
@Audited 
public abstract class AbstractDomain implements Auditable<String, Long>, Serializable { 
 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long id; 
 
    @Version 
    private int version; 
 
    @JsonIgnore 
    @Column(updatable=false) 
    private String createdBy; 
 
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
    @DateTimeFormat(iso=ISO.DATE_TIME) 
    @JsonIgnore 
    @Column(updatable=false) 
    private DateTime createdDate; 
 
    @JsonIgnore 
    private String lastModifiedBy; 
 
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
    @DateTimeFormat(iso=ISO.DATE_TIME) 
    @JsonIgnore 
    private DateTime lastModifiedDate; 

唯一修改的字段是版本,其他字段被忽略。

请您参考如下方法:

据我所见,您实际上不需要 envers根本。 Envers 更多关于存储 revisions您的数据(当然可以用于审计目的)但是如果您只想拥有这些 createdBy , createdDate , lastModifiedBy , lastModifiedDate字段有一个更简单的方法。

因为您已经在使用 spring-data-jpa我建议你启用 JPA auditing@EnableJpaAuditing注释。

然后你可以放下@Audited来自你的 AbstractDomain类并添加 @EntityListeners(AuditingEntityListener.class)这将强制 Hibernate 每次在实体持久化时保存审计信息。

最后但并非最不重要的事情是定义 AuditorAware bean 。它将告诉每个时刻究竟是谁在操纵给定的实体,因此审计监听器将知道应将哪些数据设置为 createdBylastModifiedBy领域。 很简单,举个例子:

@Bean 
AuditorAware auditor() { 
    // return () -> "system";  // Fixed principal 
    // and for spring-security 
    return () -> { 
        Authentication authentication = SecurityContextHolder.getContext() 
                .getAuthentication(); 
        if (authentication == null || !authentication.isAuthenticated()) { 
            return null; 
        } 
        return authentication.getPrincipal().toString(); 
    } 
} 

就是这样。

这是一个完整的例子:

@SpringBootApplication 
@EnableJpaAuditing 
public class So45347635Application { 
    public static void main(String[] args) { SpringApplication.run(So45347635Application.class, args); } 
 
    @MappedSuperclass 
    @EntityListeners(AuditingEntityListener.class) 
    public static abstract class AbstractDomain extends AbstractPersistable<Long> implements Auditable<String, Long> { 
        @Id 
        @GeneratedValue(strategy = GenerationType.IDENTITY) 
        private Long id; 
        @Version 
        private int version; 
 
        @Column(updatable = false) 
        private String createdBy; 
 
        @Temporal(TemporalType.TIMESTAMP) 
        @Column(updatable = false) 
        private Date createdDate; 
 
        private String lastModifiedBy; 
 
        @Temporal(TemporalType.TIMESTAMP) 
        @Column(insertable = false) 
        private Date lastModifiedDate; 
 
        @Override 
        public String getCreatedBy() { 
            return this.createdBy; 
        } 
 
        @Override 
        public void setCreatedBy(String createdBy) { 
            this.createdBy = createdBy; 
        } 
 
        @Override 
        public DateTime getCreatedDate() { 
            return null == this.createdDate ? null : new DateTime(this.createdDate); 
        } 
 
        @Override 
        public void setCreatedDate(DateTime createdDate) { 
            this.createdDate = createdDate.toDate(); 
        } 
 
        @Override 
        public String getLastModifiedBy() { 
            return this.lastModifiedBy; 
        } 
 
        @Override 
        public void setLastModifiedBy(String lastModifiedBy) { 
            this.lastModifiedBy = lastModifiedBy; 
        } 
 
        @Override 
        public DateTime getLastModifiedDate() { 
            return null == this.lastModifiedDate ? null : new DateTime(this.lastModifiedDate); 
        } 
 
        @Override 
        public void setLastModifiedDate(DateTime lastModifiedDate) { 
            this.lastModifiedDate = lastModifiedDate.toDate(); 
        } 
    } 
 
    @Entity 
    @Table(name = "users") 
    public static class User extends AbstractDomain { 
        private String username = "anonymous"; 
 
        public String getUsername() { 
            return username; 
        } 
 
        public void setUsername(String username) { 
            this.username = username; 
        } 
 
        @Override 
        public String toString() { 
            return String.format("User{id=%d, createdBy='%s', createdDate=%s, lastModifiedBy='%s', lastModifiedDate=%s, username='%s'}", 
                    getId(), getCreatedBy(), getCreatedDate(), getLastModifiedBy(), getLastModifiedDate(), username); 
        } 
    } 
 
    @Bean 
    AuditorAware auditor() { return () -> "system"; } 
 
    @Bean 
    CommandLineRunner start(UserRepository userRepository, TransactionTemplate tx) { 
        return args -> tx.execute(ctx -> { 
            final User user = userRepository.save(new User()); 
            user.setUsername("admin"); 
            System.out.println(">>>> " + userRepository.save(user)); 
            return null; 
        }); 
    } 
} 
 
interface UserRepository extends CrudRepository<So45347635Application.User, Long> { 
} 

输出:

create table users (id bigint generated by default as identity, created_by varchar(255), created_date timestamp, last_modified_by varchar(255), last_modified_date timestamp, version integer not null, username varchar(255), primary key (id)); 
insert into users (id, created_by, created_date, last_modified_by, version, username) values (null, 'system', '28-Jul-17', 'system', 0, 'anonymous'); 
update users set last_modified_by='system', last_modified_date='28-Jul-17', version=1, username='admin' where id=1 and version=0; 


标签:springMVC
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号