休眠环境 "cannot evaluate $HibernateProxy$.toString()"
Hibernate envers "cannot evaluate $HibernateProxy$.toString()"
我正在使用 envers 来审计我的实体。我的代码看起来有点像这样
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
@AuditOverride( forClass = Task.class, isAudited = true )
public class Job extends Task
{...}
@Inheritance( strategy = InheritanceType.JOINED )
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
public class Task
{
...
@ManyToOne( fetch = FetchType.LAZY )
@LazyToOne( value = LazyToOneOption.NO_PROXY )
@Fetch( value = FetchMode.SELECT )
@JoinColumn( nam = "id_util" )
@Audited( targetAuditMode = RelationTargetAuditMode.AUDITED )
private Utility utility;
}
@Entity
@DynamicInsert
@DynamicUpdate
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
public class Utility
{
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append( this.getClass().getName() ).append( "@" ).append( getId() );
builder.append( "[" );
appendAttributeValues( builder );
builder.append( "]" );
return builder.toString();
}
public Long getId()
{
return id;
}
}
当我尝试获取某个 job
实体的修订版时,字段 utility
未正确加载。相反,hibernate 给出了一个
Method threw 'org.hibernate.exception.GenericJDBCException' exception. Cannot evaluate Utility$HibernateProxyGVDBIUC.toString()
由字符串和数字组成的其余实体修订加载得很好。在审计和查询没有继承结构的其他实体时,我也没有收到此错误。
实体 Job
、Task
和 Utility
的 _aud
表均已正确填写。可能导致此错误的原因是什么?
在使用链接对象之前,您应该“具体化”proxy-object 由休眠创建的对象,就像这个答案中所说的:
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
或者,例如,使用特殊方法 unproxy
:
Object unproxiedObject = Hibernate.unproxy(proxiedObject);
TLDR原因是审计数据不一致。当您开始审核已经存在的实体及其关系时,就会发生这种情况。
解决方法复制aud
table对应rev = 1
,revtype = 0
中的所有实体数据。将 rev=1
、revtstmp=0
插入 revinfo
table.
另见 Safe Envers queries when the audit history is incomplete
说明因为实体数据在envers集成之前就已经存在,所以审计table最初是空的。当您更新拥有对实体 B 的引用的实体 A 时,会在 A_aud
中创建审计记录,但不会在 B_aud
。当查询 A 的修订时,它会尝试在 emtpy B_aud
中查找引用的实体 B 并产生一个 EntityNotFoundException
,它包含在给定的 GenericJDBCException
.
中
我正在使用 envers 来审计我的实体。我的代码看起来有点像这样
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
@AuditOverride( forClass = Task.class, isAudited = true )
public class Job extends Task
{...}
@Inheritance( strategy = InheritanceType.JOINED )
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
public class Task
{
...
@ManyToOne( fetch = FetchType.LAZY )
@LazyToOne( value = LazyToOneOption.NO_PROXY )
@Fetch( value = FetchMode.SELECT )
@JoinColumn( nam = "id_util" )
@Audited( targetAuditMode = RelationTargetAuditMode.AUDITED )
private Utility utility;
}
@Entity
@DynamicInsert
@DynamicUpdate
@Audited( targetAuditMode = RelationTargetAuditMode.NOT_AUDITED )
public class Utility
{
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append( this.getClass().getName() ).append( "@" ).append( getId() );
builder.append( "[" );
appendAttributeValues( builder );
builder.append( "]" );
return builder.toString();
}
public Long getId()
{
return id;
}
}
当我尝试获取某个 job
实体的修订版时,字段 utility
未正确加载。相反,hibernate 给出了一个
Method threw 'org.hibernate.exception.GenericJDBCException' exception. Cannot evaluate Utility$HibernateProxyGVDBIUC.toString()
由字符串和数字组成的其余实体修订加载得很好。在审计和查询没有继承结构的其他实体时,我也没有收到此错误。
实体 Job
、Task
和 Utility
的 _aud
表均已正确填写。可能导致此错误的原因是什么?
在使用链接对象之前,您应该“具体化”proxy-object 由休眠创建的对象,就像这个答案中所说的:
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
或者,例如,使用特殊方法 unproxy
:
Object unproxiedObject = Hibernate.unproxy(proxiedObject);
TLDR原因是审计数据不一致。当您开始审核已经存在的实体及其关系时,就会发生这种情况。
解决方法复制aud
table对应rev = 1
,revtype = 0
中的所有实体数据。将 rev=1
、revtstmp=0
插入 revinfo
table.
另见 Safe Envers queries when the audit history is incomplete
说明因为实体数据在envers集成之前就已经存在,所以审计table最初是空的。当您更新拥有对实体 B 的引用的实体 A 时,会在 A_aud
中创建审计记录,但不会在 B_aud
。当查询 A 的修订时,它会尝试在 emtpy B_aud
中查找引用的实体 B 并产生一个 EntityNotFoundException
,它包含在给定的 GenericJDBCException
.