HHH000513:升级到 Hibernate 6 后无法为实体创建 ReflectionOptimizer

问题描述 投票:0回答:2

最近从 Hibernate 5 升级到 6,我在调试级别看到以下错误。

12:36:11.892 [main] DEBUG org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl - HHH000513: Unable to create the ReflectionOptimizer for [abc.def.ghi.OrderEventEntity]
org.hibernate.bytecode.internal.bytebuddy.PrivateAccessorException: private accessor [createdTime]
    at org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl.findAccessors(BytecodeProviderImpl.java:1250) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]

OrderEntity.java

@Data
@Entity
@Table(name = "OMS_ORDER_EVENTS")
public class OrderEventEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "oms_order_events_seq")
    @SequenceGenerator(name = "oms_order_events_seq", sequenceName = "OMS_ORDER_EVENTS_SEQ", allocationSize = 1)
    @Column(name = "ID")
    private Long id;

    @Column(name = "ORDER_ID")
    private Long orderId;

    @Column(name = "VERSION_NUMBER")
    private Integer versionNumber;

    @Column(name = "GENERATED_BY")
    @Enumerated(value = EnumType.STRING)
    private EventGenerator generatedBy;

    @Column(name = "USER_CONTACT_ID")
    private String userContactId;

    @Column(name = "EVENT_TYPE")
    @Enumerated(value = EnumType.STRING)
    private EventType eventType;

    @Column(name = "CREATED_TIME")
    private Date createdTime;
}

在互联网上没有任何与此相关的痕迹。目前我的 Spring Web 应用程序没有出现,我在猜测这是否是问题所在。

编辑:

我想有一个

ClassDefNotFoundException
但它没有打印在日志中。这就是我的应用程序没有出现的原因。

java spring hibernate hibernate-6.x
2个回答
-1
投票

短篇小说

Place

@Access(AccessType.PROPERTY)
annotation over your entity class.

说来话长

当 Hibernate 从 DB 读取数据时,它需要以某种方式实例化实体对象并填充它的字段值,有几个选项可以做到这一点:

  1. 使用反射访问
  2. 生成一些帮助程序类,它将以更优化的方式执行此操作(是的,反射访问仍然很慢)

你观察到的异常

PrivateAccessorException: private accessor [createdTime]

表示以下:Hibernate 试图生成辅助类,但发现特定的

createdTime
字段具有私有访问权限,这反过来又阻止了辅助类的生成。然而,实际的根本原因是 Hibernate 甚至没有考虑实体类中存在的 getter 和 setter 方法(POJO“属性”),只是因为默认情况下 Hibernate 更喜欢使用字段访问来访问属性(请检查 https://thorben-janssen。 com/access-strategies-in-jpa-and-hibernate/)。所以,总的来说,你是对的:这样的异常不是良性的 - 它表明你正在获得 Hibernate 的次优行为。


-2
投票
12:36:11.892 [main] DEBUG 

那是 debug 级别的日志消息。你为什么担心它?

更新

这个帖子的其他回复大错特错,所以让我澄清一下实际情况.

  1. Hibernate 是否如声明的那样默认使用字段访问。 不,它没有。 当映射注释放置在字段上时,Hibernate 使用字段访问,按照 JPA 规范的要求。如果映射注释放在 getter 上,它使用属性访问。
  2. Hibernate 是否应该像声明的那样在这里使用 getter 和 setter,而不是直接访问字段。 不,绝对不应该。那不符合 JPA 规范。
  3. 这是个问题吗?它是否会导致所声称的“次优”性能? 不,不是,也不是。“反射优化器”对性能的影响至多是极其微小的,在大多数情况下是无法衡量的。
  4. 一般来说,当 Hibernate 或任何其他库以
    DEBUG
    级别记录某些内容时,人们应该感到不安和担心吗? 没有人不应该。 如果这真的是值得关注的事情,我们至少会记录一个
    WARN
    。我们假设每个人的日志级别都默认设置为
    INFO
    ,所以当我们在
    DEBUG
    记录一些东西是因为通常不值得关注.
  5. 用户是否应该为了减轻这个非问题,将
    @Access(AccessType.PROPERTY)
    注释分散到他们的实体类中? 请不要。 不要那样做。那是糟糕的。这不是 JPA 的使用方式。

如果您出于某种原因更喜欢属性访问而不是字段访问,则可以将映射注释放在 getter 上。但这不再是我们的建议,也不再是 Hibernate 社区的常见做法。

我希望能有所帮助,我希望它能纠正该线程上其他答案中的 FUD。

备案: 我是 Hibernate 的创建者,最初将“反射优化器”添加到 Hibernate 的人,也是实际编写 JPA 规范(包括规范的相关部分)的人之一。

© www.soinside.com 2019 - 2024. All rights reserved.