标签: hibernate-envers

REVINFO 表缺少序列“revinfo_seq”

我正在迁移到 SpringBoot 3.0.1 并将“hibernate-envers”版本更新为“6.1.6.Final”。我的数据库是 PostgreSQL 13.6。Hibernate 配置为创建数据库模式: spring.jpa.hibernate.ddl-auto:create

启动应用程序后,我收到以下错误:

pim 2022-12-27 12:00:13,715 WARN  C#c7b942ec-33b4-4749-b113-22cbb2946a8d [http-nio-9637-exec-1]     SqlExceptionHelper/133              - SQL Error: 0, SQLState: 42P01
pim 2022-12-27 12:00:13,715 ERROR C#c7b942ec-33b4-4749-b113-22cbb2946a8d [http-nio-9637-exec-1]     SqlExceptionHelper/138              - ERROR: relation "revinfo_seq" does not exist
  Position: 16
Run Code Online (Sandbox Code Playgroud)

revinfo 表如下所示:

create table revinfo
(
    revision           bigint not null
        primary key,
    client_id          varchar(255),
    correlation_id     varchar(255),
    origin             varchar(255),
    request_id         varchar(255),
    revision_timestamp bigint not null,
    timestamp_utc      timestamp with time zone,
    user_name          varchar(255)
);
Run Code Online (Sandbox Code Playgroud)

序列“revinfo_seq”不存在,但在带有 envers 的旧数据库结构中

5.6.8.Final
Run Code Online (Sandbox Code Playgroud)

而 SpringBoot 2.6.6 它也不存在,没有任何问题。我缺少什么?

我尝试切换参数

org.hibernate.envers.use_revision_entity_with_native_id …
Run Code Online (Sandbox Code Playgroud)

postgresql hibernate-envers spring-boot

9
推荐指数
1
解决办法
4625
查看次数

获取特定对象受影响的完整Envers修订版

存储修订数据的方式每个受修订影响的对象在_AUD表中获得单独的记录.所以,当我搜索的修订影响的对象A,我会回来这里的修订是入门3的对象B,但如果对象A和/或C进行改版中也发生了变化3,这些条目都没有回来,给人的印象是B在修改的唯一对象那次修改.我正在尝试做的是每个修订影响对象B,返回受该修订影响的所有对象.

something_AUD     desired     actual

id|REV            id|REV      id|REV
-------------     -------     ------
A|1               B|2         B|2
B|2               B|3         B|3
B|3               C|3
C|3

我一直在尝试通过运行初始查询来查找相关修订:

AuditQuery query = AuditReaderFactory.get(entity.em()).createQuery()
.forRevisionsOfEntity(type, false, true)
.add(AuditEntity.id().eq(entity.id));
Run Code Online (Sandbox Code Playgroud)

然后为每个结果运行以下查询:

int rev_id = ((RevisionData) data[1]).getId();
AuditQuery q = AuditReaderFactory.get(JPA.em()).createQuery()
.forRevisionsOfEntity(type, false, true)
.add(AuditEntity.revisionNumber().eq(rev_id));
List<Object[]> real_data = q.getResultList();
Run Code Online (Sandbox Code Playgroud)

但这导致了QuerySyntaxException:

别名'r'的重复定义[从models中选择e,r,r .AgentShift_AUD e,models.RevisionData r,models.RevisionData r其中e.originalId.REV.id在(:_p0)和e.originalId.REV.id中= r.id和e.originalId.REV.id in(:_p1)和e.originalId.REV.id = r.id order by e.originalId.REV.id asc,e.originalId.REV.id …

jpa hibernate-envers

8
推荐指数
1
解决办法
6323
查看次数

创建Envers自定义修订实体

我正在尝试为我们的项目设置审核.我从默认配置开始工作正常.

下一步是存储已进行更改的用户.按照手册我创建了自定义实体修订:

package com.csbi.samples.utils.audit;

import java.io.Serializable;
import java.text.DateFormat;
import java.util.Date;

import org.hibernate.envers.RevisionNumber;
import org.hibernate.envers.RevisionTimestamp;
import org.hibernate.envers.RevisionEntity;

import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;

@Entity
@Table(name="REVISIONS")
@RevisionEntity(CustomRevisionListener.class)
public class CustomRevisionEntity implements Serializable {
private static final long serialVersionUID = -1255842407304508513L;

@Id
@GeneratedValue
@RevisionNumber
private int id;

@RevisionTimestamp
private long timestamp;

private String username;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

@Transient
public Date getRevisionDate() {
    return new Date(timestamp);
} …
Run Code Online (Sandbox Code Playgroud)

revision entity hibernate-envers

8
推荐指数
1
解决办法
1万
查看次数

使用Hibernate Envers进行集成测试

我正在尝试围绕一些被审计的实体构建一些测试.我的问题是envers只审计事务提交.

我需要创建/编辑一些测试对象,提交事务然后检查修订.

与envers进行集成测试的最佳方法是什么?

更新:这是我想要实现的非常糟糕的,非确定性的测试类.我更愿意这样做,而不依赖于测试方法的顺序

首先在单个事务中创建帐户和account_transaction.两个审计条目均适用于修订版1.

第二次更新了新事务中的account_transaction.经审计的条目为修订版2.

第三,在修订版1中加载审计帐户并对其执行某些操作.

@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/testApplicationContext.xml"})
public class TestAuditing {

    @Autowired
    private AccountDao accountDao;

    @PersistenceContext
    private EntityManager entityManager;

    @Test
    @Rollback(false)
    public void first() {
        Account account = account("Test Account", "xxxxxxxx", "xxxxxx");

        AccountTransaction transaction = transaction(new Date(), Deposit, 100, "Deposit");
        account.setTransactions(newArrayList(transaction));

        accountDao.create(account);
    }

    @Test
    @Rollback(false)
    public void second() {
        Account account = accountDao.getById(1L);
        AccountTransaction transaction = account.getTransactions().get(0);
        transaction.setDescription("Updated Transaction");
        accountDao.update(account);
    }

    @Test
    public void third() {
        AuditReader reader = AuditReaderFactory.get(entityManager);

        List<Number> accountRevisions = reader.getRevisions(Account.class, 1L); …
Run Code Online (Sandbox Code Playgroud)

integration-testing hibernate jpa-2.0 hibernate-envers

8
推荐指数
2
解决办法
4407
查看次数

用envers列出每个实体的最新修订版

我正在尝试检索尚未删除的所有实体的最新版本.使用subselect在SQL中执行此操作非常简单:

select * from article_aud aud1
where rev in
 (select max(rev) from article_aud aud2
  where aud1.id = aud2.id)
and revtype < 2
Run Code Online (Sandbox Code Playgroud)

但我不知道如何通过envers API实现这一点.我从AuditReader开始,但没有找到方法,选择不同的对象

public List<Object[]> findLatestArticleRevisions(){
    List<Object[]> results = (List<Object[]>) getJpaTemplate().execute(new AuditReaderCallback() {
        @Override
        public Object doInAuditReader(AuditReader auditReader) {
            return auditReader.createQuery().forRevisionsOfEntity(Article.class, false, false)
                // TODO select distinct on entities
                .addOrder(new PropertyAuditOrder(new RevisionNumberPropertyName(), false))
                .getResultList();
        }
    });

    return results;
}
Run Code Online (Sandbox Code Playgroud)

重要提示:我想在一个或至少两个查询中执行此操作,因为我有许多文章(实体)有许多修订.

非常感谢!

java sql hibernate hibernate-envers

8
推荐指数
1
解决办法
9110
查看次数

有条件的Envers审计

我有一个要求,我只想在更改状态字段时审核记录.我遵循了文档章节教程"15.8.条件审计".

第1步:关闭自动Envers事件侦听器注册.我有以下内容:

<prop key="hibernate.listeners.envers.autoRegister">false</prop>
Run Code Online (Sandbox Code Playgroud)

第2步:为适当的事件侦听器创建子类.

public class DeleteEnversListener extends EnversPostDeleteEventListenerImpl {   
    private static final long serialVersionUID = 5906427978349712224L;
    private static Log log = LogFactory.getLog(DeleteEnversListener.class);

    public DeleteEnversListener(AuditConfiguration enversConfiguration) {
        super(enversConfiguration);
    }

    @Override
    public void onPostDelete(PostDeleteEvent event) {
        log.info("!!! just logging entity !! "+ event.getEntity());
        super.onPostDelete(event);
    }   
}
Run Code Online (Sandbox Code Playgroud)

以类似的方式,我有

  • InsertEnversListener
  • UpdateEnversListener
  • DeleteEnversListener
  • CollectionRecreateEnversListener
  • PreCollectionRemoveEnversListener
  • PreCollectionUpdateEnversListener

第3步:创建自己的实现 org.hibernate.integrator.spi.Integrator

public class CustomEnversIntegrator extends EnversIntegrator   {

    private static Log log = LogFactory.getLog(CustomEnversIntegrator.class);

    @Override
    public void integrate(Configuration configuration,
            SessionFactoryImplementor sessionFactory,
            SessionFactoryServiceRegistry serviceRegistry) {

        super.integrate(configuration, sessionFactory, serviceRegistry); …
Run Code Online (Sandbox Code Playgroud)

hibernate hibernate-envers jboss7.x

8
推荐指数
2
解决办法
5427
查看次数

Hibernate/Envers无法读取映射的by属性

我无法实现使用连接表(很多到许多关系/sf/answers/532212551/&https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Mapping_a_Join_Table_with_Additional_Columns).当我尝试重现它时,持久性单元无法构建EntityManagerFactory.似乎Envers无法读取映射的属性,尽管它对我来说很好看.我究竟做错了什么?使用额外列(和Envers)实现多对多关系的正确方法是什么?

Product.java

@Entity
@Audited
public class Product extends UserModel {
...
    @OneToMany(mappedBy = "product", orphanRemoval = true, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    public List<ProductForm> forms = new ArrayList<ProductForm>();
...
}
Run Code Online (Sandbox Code Playgroud)

Form.java

@Entity
@Audited
public class Form extends UserModel {
...
    @OneToMany(mappedBy = "form", fetch = FetchType.LAZY)
    public List<ProductForm> products = new ArrayList<ProductForm>();
...
}
Run Code Online (Sandbox Code Playgroud)

ProductForm.java

@Entity
@Table(name = "Product_Form")
@IdClass(ProductForm.ProductFormId.class)
public class ProductForm {
    @Id
    @JoinColumn(name = "product_id")
    @ManyToOne
    public Product product;

    @Id
    @JoinColumn(name = …
Run Code Online (Sandbox Code Playgroud)

hibernate jpa jpa-2.0 hibernate-envers

8
推荐指数
1
解决办法
3373
查看次数

在JPA2/Hibernate中使用重写的equals/hashCode审核@Embeddables的集合

我有JPA2/Hibernate的设置.此外,实体由Hibernate Envers审核.我有以下类来表示只有一个字段的邮政编码,即value.

当只保存任何邮政编码的一个实例时,一切正常Set<PostalCode>.但是,当我尝试添加另一个邮政编码时,审核失败并出现以下异常:

Caused by: javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [PostalCodesAudit#{PostOffice_id=5, revision_id=DefaultRevisionEntity(id = 16, revisionDate = Aug 19, 2013 8:50:05 AM), revisionType=ADD}]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1359)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:513)
... 58 more
Run Code Online (Sandbox Code Playgroud)

这里奇怪的是,它工作正常,当我删除的实现equals,并hashCodePostalCode类,该机制运行良好.此外,如果我将集合更改为Set<String>,类似的映射工作完美.

我不是绝对需要实现equalshashCodePostalCode类,但我不是在下探支撑过于敏锐,无论是.

映射这种情况的正确方法是什么?

实体

@Embeddable
public class PostalCode {
    @Column(name = "postalCode", length = 5)
    @Pattern(regexp = "[0-9}{5}")
    private …
Run Code Online (Sandbox Code Playgroud)

hibernate jpa equals hashcode hibernate-envers

8
推荐指数
1
解决办法
1066
查看次数

我可以更改以及如何更改Hibernate Envers中的REVTYPE值吗?

我是Hiberante和Envers的新人.我在我的应用程序中成功实现了Hibernate Envers并制作了审计表,一切正常,但我想知道是否可以在审计表中更改REVTYPE列中的值.

现在我的值为0(ADD),1(MOD)和2(DEL).我想知道是否可以更改此值,我想将0更改为例如INSERT,1 UPDATE和2 DELETE.

这可能吗?怎么样?

谢谢!

java hibernate hibernate-envers

8
推荐指数
1
解决办法
8432
查看次数

如何使用spring data envers查找实体的所有修订版?

我在Spring启动应用程序中使用spring-data-envers.我可以成功记录我的实体的审核.

现在,我需要在UI中向用户显示审计数据.就像搜索表单一样,用户可以选择持续时间和实体,以便查看审计日志.

string-data-envers提供的RevisionRepository只有以下三种方法.

@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} …
Run Code Online (Sandbox Code Playgroud)

java spring hibernate-envers spring-data-jpa

8
推荐指数
2
解决办法
5540
查看次数