gpt4 book ai didi

java - 使用 Hibernate Envers 审核可嵌入实体

转载 作者:行者123 更新时间:2023-12-02 09:43:04 27 4
gpt4 key购买 nike

我正在尝试使用 Hibernate Envers 将审核支持添加到存储实体关系的表中。

我正在使用 Spring Boot 2.1.5 和 Hibernate 5.3.10。

以下是我的类(class):

审计实体

import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.envers.Audited;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;

@Getter
@Setter
@Audited
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditEntity {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(
name = "uuid",
strategy = "org.hibernate.id.UUIDGenerator",
parameters = {
@Parameter(
name = "uuid_gen_strategy_class",
value = "org.hibernate.id.uuid.CustomVersionOneStrategy"
)
}
)
private String id;

@Column(name = "created_date", updatable = false, nullable = false)
@CreatedDate
private long createdDate;

@Column(name = "modified_date")
@LastModifiedDate
private long modifiedDate;

@Column(name = "created_by")
@CreatedBy
private String createdBy;

@Column(name = "modified_by")
@LastModifiedBy
private String modifiedBy;

@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}

if (!(o instanceof AuditEntity)) {
return false;
}

AuditEntity r = (AuditEntity) o;

return this.getId().equals(r.getId());
}
}

角色

import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Getter
@Setter
@Audited
@Entity
@Table(name = "role")
public class Role extends AuditEntity {
@Column(name = "name")
private String name;

@NotAudited
private String dontAudit;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.role")
private Set<UserRole> userRoles = new HashSet<>(0);
}

用户

import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.Audited;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.HashSet;
import java.util.Set;

@Getter
@Setter
@Audited
@Entity
@Table(name = "user")
public class User extends AuditEntity {
private String sso;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user")
private Set<UserRole> userRoles = new HashSet<>(0);
}

用户角色

import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.Audited;

import javax.persistence.*;

@Getter
@Setter
@Audited
@Entity
@Table(name = "user_roles")
@AssociationOverrides({
@AssociationOverride(name = "pk.user", joinColumns = @JoinColumn(name = "USER_ID")),
@AssociationOverride(name = "pk.role", joinColumns = @JoinColumn(name = "ROLE_ID"))
})
public class UserRole extends AuditEntity {
@EmbeddedId
private UserRoleId pk = new UserRoleId();

public User getUser() {
return getPk().getUser();
}

public void setUser(User user) {
getPk().setUser(user);
}

public Role getRole() {
return getPk().getRole();
}

public void setRole(Role role) {
getPk().setRole(role);
}
}

用户角色ID

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
import java.io.Serializable;

@Getter
@Setter
@Embeddable
@EqualsAndHashCode
public class UserRoleId implements Serializable {
@ManyToOne
private User user;
@ManyToOne
private Role role;
}

当我运行该应用程序时,它会抛出以下错误。但是,当我不从 AuditEntity 扩展 UserRole 时,应用程序会成功启动,但 user_role 表上没有审核列。

错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.5.RELEASE.jar:2.1.5.RELEASE]
at com.ercancelik.hibernate.envers.DemoApplication.main(DemoApplication.java:11) [classes/:na]
Caused by: org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType
at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addIdProperties(IdMetadataGenerator.java:120) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.configuration.internal.metadata.IdMetadataGenerator.addId(IdMetadataGenerator.java:200) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.configuration.internal.metadata.AuditMetadataGenerator.generateFirstPass(AuditMetadataGenerator.java:642) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.configuration.internal.EntitiesConfigurator.configure(EntitiesConfigurator.java:95) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.boot.internal.EnversServiceImpl.doInitialize(EnversServiceImpl.java:154) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.boot.internal.EnversServiceImpl.initialize(EnversServiceImpl.java:118) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl.produceAdditionalMappings(AdditionalJaxbMappingProducerImpl.java:101) ~[hibernate-envers-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:297) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 16 common frames omitted

最佳答案

问题具体在于您如何映射UserRole。如果您发现您已定义 UserRole 来包含 @EmbeddedId,但您还扩展了 AbstractEntity 类,该类还基于uuid。你根本不能把这两个问题混为一谈。

说实话,我很惊讶你提供的映射实际上并没有抛出 ORM 异常,而不是你一路进入 Envers,因为 ORM 必须在最初应该抛出的地方解析它们关于如何解析标识符的异常。

作为旁注,除非有特定的业务目的来捕获主数据表中创建或修改实体的人员/时间,否则您实际上可以将其捕获为每个事务中的 Envers 修订实体的一部分审计数据,这将减少每条记录存储的数据。

看看 Envers 提供的自定义修订实体;您可以使用 spring-bean 挂接在那里,并使用最新的 Spring 框架与 Hibernate 5.3+ 相结合来收集您需要的任何信息。

关于java - 使用 Hibernate Envers 审核可嵌入实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56901899/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com