java Hibernate仅在类为final时工作[否则将抛出SingleTableEntityPersister]
我曾尝试使用Hibernate 5.4.1构建非常简单的实体并将其保存在数据库中。最终版本和Java8。为了消除状态突变,跳过“setter”,并使用@Access(AccessType.FIELD)。不幸的是,当Hibernate启动时,会引发以下异常:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'entityManagerFactory' defined in class path resource [application-context.repositories.xml]:
Invocation of init method failed;
nested exception is javax.persistence.PersistenceException:
[PersistenceUnit: default] Unable to build Hibernate SessionFactory;
nested exception is org.hibernate.MappingException:
Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
我发现在制作产品类最终版后,一切正常。问题是,我不明白为什么你能帮我了解发生了什么事吗强>
一点代码。 这不起作用:
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Builder;
import lombok.Getter;
@Entity
@Access(AccessType.FIELD)
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Getter
private String name;
@Getter
private String colour;
protected Product() {
}
@Builder
public Product(String name, String colour) {
this.name = name;
this.colour = colour;
}
}
只要加上最后一个就足够了
public final class Product {
它是有效的
应用程序上下文。存储库。xml仅通知spring存储库的位置
<jpa:repositories base-package="a.b.c.repositories"/>
在调试时,我还发现下面的一个异常是
HibernateException -> Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
你知道为什么需要“最终”吗
//编辑
安德洛尼卡指出了正确的方向:
现在我知道,若类不是final,hibernate会尝试构建一个代理,而异常来自 ByteBuddyProxyHelper。阶级
return byteBuddyState.loadProxy( persistentClass, new TypeCache.SimpleKey(key), byteBuddy -> byteBuddy
.ignore( byteBuddyState.getProxyDefinitionHelpers().getGroovyGetMetaClassFilter() )
.with( new NamingStrategy.SuffixingRandom( PROXY_NAMING_SUFFIX, new NamingStrategy.SuffixingRandom.BaseNameResolver.ForFixedValue( persistentClass.getName() ) ) )
.subclass( interfaces.length == 1 ? persistentClass : Object.class, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING )
.implement( (Type[]) interfaces )
.method( byteBuddyState.getProxyDefinitionHelpers().getVirtualNotFinalizerFilter() )
.intercept( byteBuddyState.getProxyDefinitionHelpers().getDelegateToInterceptorDispatcherMethodDelegation() )
.method( byteBuddyState.getProxyDefinitionHelpers().getHibernateGeneratedMethodFilter() )
.intercept( SuperMethodCall.INSTANCE )
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
.implement( ProxyConfiguration.class )
.intercept( byteBuddyState.getProxyDefinitionHelpers().getInterceptorFieldAccessor() )
);
# 1 楼答案
因此,几天的调试让我想到:
古典喷射器。使用查找。isAvailable()-在Java8上抛出被Hibernate吞没的NoMethodError
# 2 楼答案
不确定,为什么使用
final
关键字它可以工作,也许它与代理生成有关。这里的问题是@Builder
来自龙目岛,我想。有一个bug报告说,添加@Builder
注释将删除hibernate所需的默认构造函数