我正在迁移到 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) 存储修订数据的方式每个受修订影响的对象在_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 …
我正在尝试为我们的项目设置审核.我从默认配置开始工作正常.
下一步是存储已进行更改的用户.按照手册我创建了自定义实体修订:
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) 我正在尝试围绕一些被审计的实体构建一些测试.我的问题是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) 我正在尝试检索尚未删除的所有实体的最新版本.使用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)
重要提示:我想在一个或至少两个查询中执行此操作,因为我有许多文章(实体)有许多修订.
非常感谢!
我有一个要求,我只想在更改状态字段时审核记录.我遵循了文档章节教程"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)
以类似的方式,我有
第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) 我无法实现使用连接表(很多到许多关系/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) 我有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,并hashCode从PostalCode类,该机制运行良好.此外,如果我将集合更改为Set<String>,类似的映射工作完美.
我不是绝对需要实现equals和hashCode在PostalCode类,但我不是在下探支撑过于敏锐,无论是.
映射这种情况的正确方法是什么?
@Embeddable
public class PostalCode {
@Column(name = "postalCode", length = 5)
@Pattern(regexp = "[0-9}{5}")
private …Run Code Online (Sandbox Code Playgroud) 我是Hiberante和Envers的新人.我在我的应用程序中成功实现了Hibernate Envers并制作了审计表,一切正常,但我想知道是否可以在审计表中更改REVTYPE列中的值.
现在我的值为0(ADD),1(MOD)和2(DEL).我想知道是否可以更改此值,我想将0更改为例如INSERT,1 UPDATE和2 DELETE.
这可能吗?怎么样?
谢谢!
我在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) hibernate-envers ×10
hibernate ×6
java ×3
jpa ×3
jpa-2.0 ×2
entity ×1
equals ×1
hashcode ×1
jboss7.x ×1
postgresql ×1
revision ×1
spring ×1
spring-boot ×1
sql ×1