Hibernate Enver 抛出 Object not found exception for auditReader.find()
Hibernate Enver throws Object not found exception for auditReader.find()
我加入了一个项目,他们实施了 Springboot v.2.0.5
、Hibernate + Envers v5.3.7
。我现在的工作是为一个漂亮的小端点生成日志。
当我尝试通过以下代码利用 auditreader 执行此操作时:
public List<Drug> getDrugAudByID(long drugId) {
try (Session session = hibernateSession.openSession()) {
AuditReader auditReader = AuditReaderFactory.get(session);
List<Number> revisions = AuditReaderFactory.get(session).getRevisions(Drug.class, drugId);
List<Drug> drugVersions = new ArrayList<>();
for (Number rev : revisions) {
Drug drug = auditReader.find(Drug.class, drugId, rev);
drugVersions.add(drug);
}
它适用于普通元素,如 id、name 等。
问题是,每个连接列都没有正确初始化并抛出
'org.hibernate.ObjectNotFoundException' exception. Cannot evaluate classPath.class$HibernateProxy$YUt19z4c.toString()
实体样本如下所示:
@Entity
@Audited
@Table(name = "drugs")
@Check(constraints = "id <> genericDrug")
public class Drug {
public static String genericPrefix = "73019";
public static String specificPrefix = "73010";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "drugId", unique = true)
private BigDecimal drugId;
@Column(name = "partType")
private String partType;
@Column(name = "name")
private String name;
@OneToOne()
@JoinColumn(name = "form", referencedColumnName = "id")
private FormType form;
我没有实现任何自定义 RevisionEntities
,并且表格修订实体由休眠手动生成。这是 DDL。
create table REVINFO
(
REV int auto_increment
primary key,
REVTSTMP bigint null
);
#Only a sample of the true DLL, but encapsulates the problematic form Field
create table drugs_AUD
(
REV int not null,
REVTYPE tinyint null,
id bigint not null,
drugId decimal(11) null,
partType varchar(2) null,
name varchar(30) null,
form bigint null,
substancesComplete bit default b'0' null,
primary key (id, REV),
constraint fk_drugs_REV
foreign key (REV) references REVINFO (REV),
);
类似的问题被问到:
Hibernate Envers: Initializing Envers Proxies
但是使用 modelMapper 并没有解决我的问题。
否则我今天搜索了整个互联网,所以任何帮助将不胜感激。
我找到原因了。
数据是在项目开始时使用 SQL-dumps
插入的,这意味着它绕过了休眠和正常的客户端站点执行。其结果是表单和其他实体的 AUD
table 已过时。
由于以前没有使用过修订历史,我的解决方案是:
- 截断所有
AUD
tables
- 截断
REVINFO
- 将值重新插入
AUD
和 REVINFO
。按照 foreign keys
. 的正确顺序执行此操作
- 使用 https://candrews.integralblue.com/2009/03/hibernate-deep-deproxy/
启动休眠代理
请注意,这将删除所有以前记录的 AUD
历史记录。
下面显示了一个 AUD
table 的示例
SET FOREIGN_KEY_CHECKS=0;
#Step 1 truncate AUD tables. Example of truncating a single AUD table
TRUNCATE TABLE drugs_AUD;
#Step 2 truncate REVINFO
TRUNCATE REVINFO;
SET FOREIGN_KEY_CHECKS=1;
#Step 3 reinsert values into REVINFO and AUD tables.
INSERT INTO REVINFO (REV, REVTSTMP) VALUES (1, UNIX_TIMESTAMP());
#An example of a single AUD table
INSERT INTO drugs_AUD (REV, REVTYPE, id, drugId, partType, name, form, substancesComplete)
SELECT 1, 0, id, drugId, partType, name, form, substancesComplete from drugs;
我加入了一个项目,他们实施了 Springboot v.2.0.5
、Hibernate + Envers v5.3.7
。我现在的工作是为一个漂亮的小端点生成日志。
当我尝试通过以下代码利用 auditreader 执行此操作时:
public List<Drug> getDrugAudByID(long drugId) {
try (Session session = hibernateSession.openSession()) {
AuditReader auditReader = AuditReaderFactory.get(session);
List<Number> revisions = AuditReaderFactory.get(session).getRevisions(Drug.class, drugId);
List<Drug> drugVersions = new ArrayList<>();
for (Number rev : revisions) {
Drug drug = auditReader.find(Drug.class, drugId, rev);
drugVersions.add(drug);
}
它适用于普通元素,如 id、name 等。 问题是,每个连接列都没有正确初始化并抛出
'org.hibernate.ObjectNotFoundException' exception. Cannot evaluate classPath.class$HibernateProxy$YUt19z4c.toString()
实体样本如下所示:
@Entity
@Audited
@Table(name = "drugs")
@Check(constraints = "id <> genericDrug")
public class Drug {
public static String genericPrefix = "73019";
public static String specificPrefix = "73010";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "drugId", unique = true)
private BigDecimal drugId;
@Column(name = "partType")
private String partType;
@Column(name = "name")
private String name;
@OneToOne()
@JoinColumn(name = "form", referencedColumnName = "id")
private FormType form;
我没有实现任何自定义 RevisionEntities
,并且表格修订实体由休眠手动生成。这是 DDL。
create table REVINFO
(
REV int auto_increment
primary key,
REVTSTMP bigint null
);
#Only a sample of the true DLL, but encapsulates the problematic form Field
create table drugs_AUD
(
REV int not null,
REVTYPE tinyint null,
id bigint not null,
drugId decimal(11) null,
partType varchar(2) null,
name varchar(30) null,
form bigint null,
substancesComplete bit default b'0' null,
primary key (id, REV),
constraint fk_drugs_REV
foreign key (REV) references REVINFO (REV),
);
类似的问题被问到: Hibernate Envers: Initializing Envers Proxies 但是使用 modelMapper 并没有解决我的问题。
否则我今天搜索了整个互联网,所以任何帮助将不胜感激。
我找到原因了。
数据是在项目开始时使用 SQL-dumps
插入的,这意味着它绕过了休眠和正常的客户端站点执行。其结果是表单和其他实体的 AUD
table 已过时。
由于以前没有使用过修订历史,我的解决方案是:
- 截断所有
AUD
tables - 截断
REVINFO
- 将值重新插入
AUD
和REVINFO
。按照foreign keys
. 的正确顺序执行此操作
- 使用 https://candrews.integralblue.com/2009/03/hibernate-deep-deproxy/ 启动休眠代理
请注意,这将删除所有以前记录的 AUD
历史记录。
下面显示了一个 AUD
table 的示例
SET FOREIGN_KEY_CHECKS=0;
#Step 1 truncate AUD tables. Example of truncating a single AUD table
TRUNCATE TABLE drugs_AUD;
#Step 2 truncate REVINFO
TRUNCATE REVINFO;
SET FOREIGN_KEY_CHECKS=1;
#Step 3 reinsert values into REVINFO and AUD tables.
INSERT INTO REVINFO (REV, REVTSTMP) VALUES (1, UNIX_TIMESTAMP());
#An example of a single AUD table
INSERT INTO drugs_AUD (REV, REVTYPE, id, drugId, partType, name, form, substancesComplete)
SELECT 1, 0, id, drugId, partType, name, form, substancesComplete from drugs;