问题:
我已经将JaVers与现有的Spring Boot应用程序集成在一起,尽管它像一个魅力一样工作,但是在创建新的@TypeName
实体时尝试使用File
注释时遇到了这个异常。
org.javers.common.exception.JaversException: NOT_INSTANCE_OF: JaVers bootstrap error - expected instance of 'File', got instance of 'com.mycompany.model.File'
at org.javers.core.metamodel.type.EntityType.getIdOf(EntityType.java:76)
at org.javers.core.metamodel.type.EntityType.createIdFromInstance(EntityType.java:87)
at org.javers.core.metamodel.object.GlobalIdFactory.createId(GlobalIdFactory.java:57)
at org.javers.core.graph.LiveCdoFactory.create(LiveCdoFactory.java:29)
at org.javers.core.graph.LiveCdoFactory.create(LiveCdoFactory.java:15)
at org.javers.core.graph.ObjectGraphBuilder.buildGraph(ObjectGraphBuilder.java:44)
at org.javers.core.graph.LiveGraphFactory.createLiveGraph(LiveGraphFactory.java:39)
at org.javers.core.commit.CommitFactory.createLiveGraph(CommitFactory.java:96)
at org.javers.core.commit.CommitFactory.create(CommitFactory.java:75)
at org.javers.core.JaversCore.commit(JaversCore.java:82)
at org.javers.spring.jpa.JaversTransactionalDecorator.commit(JaversTransactionalDecorator.java:83)
at org.javers.spring.jpa.JaversTransactionalDecorator$$FastClassBySpringCGLIB$$acb40bd0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at org.javers.spring.jpa.JaversTransactionalDecorator$$EnhancerBySpringCGLIB$$3ab81589.commit(<generated>)
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.lambda$new$0(AbstractSpringAuditableRepositoryAspect.java:33)
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.lambda$onVersionEvent$3(AbstractSpringAuditableRepositoryAspect.java:52)
at java.util.Optional.ifPresent(Optional.java:159)
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.onVersionEvent(AbstractSpringAuditableRepositoryAspect.java:48)
at org.javers.spring.auditable.aspect.springdata.AbstractSpringAuditableRepositoryAspect.onSave(AbstractSpringAuditableRepositoryAspect.java:38)
at org.javers.spring.auditable.aspect.springdatajpa.JaversSpringDataJpaAuditableRepositoryAspect.onSaveAndFlushExecuted(JaversSpringDataJpaAuditableRepositoryAspect.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:626)
at org.springframework.aop.aspectj.AspectJAfterReturningAdvice.afterReturning(AspectJAfterReturningAdvice.java:66)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy196.saveAndFlush(Unknown Source)
at com.mycompany.service.FileServiceImpl.createRecord(FileServiceImpl.java:88)
似乎由于某种原因,方法org.javers.core.metamodel.type.EntityType.getIdOf(EntityType.java:76)
没有使用@TypeName
来确定实例类型:
public Object getIdOf(Object instance) {
Validate.argumentIsNotNull(instance);
if (!isInstance(instance)) {
throw new JaversException(JaversExceptionCode.NOT_INSTANCE_OF, getName(), instance.getClass().getName());
}
Object cdoId = getIdProperty().get(instance);
if (cdoId == null) {
throw new JaversException(JaversExceptionCode.ENTITY_INSTANCE_WITH_NULL_ID, getName(), getIdProperty().getName());
}
return cdoId;
}
我想念什么?
设置:
如果我打印MappingEntityType
,则会得到以下信息:
没有 @TypeName
批注:
Type MappingEntityType{
baseType: class com.mycompany.model.File
typeName: com.mycompany.model.File
managedProperties:
Field Integer id; //declared in File
Field String name; //declared in File
Field byte[] data; //declared in File
Field String mimeType; //declared in File
Field Product product; //declared in File
idProperty: id
}
带有注释:
Type MappingEntityType{
baseType: class com.mycompany.model.File
typeName: File
managedProperties:
Field Integer id; //declared in File
Field String name; //declared in File
Field byte[] data; //declared in File
Field String mimeType; //declared in File
Field Product product; //declared in File
idProperty: id
}
所以映射似乎是正确的,因为baseType相同,但typeName不同。
我的File
实体的定义如下:
@TypeName("File")
@Entity
@Table(name = "file")
public class File implements Model {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, unique = true)
private Integer id;
@Column(name = "name", nullable = false, length = 50)
private String name;
@Lob
@Column(name = "data", nullable = true)
private byte[] data;
@Column(name = "mime_type", nullable = true, length = 50)
private String mimeType;
@JoinColumn(name = "product_id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Product product;
}
注意:我正在使用HibernateUnproxyObjectAccessHook
,因此如果我正确理解Product
的延迟加载应该不会有问题。