Hibernate / JPA中注释字段或getter方法的性能差异

8
我想知道使用私有字段与使用公共getter方法注释实体之间性能差异的确切数字。有人说字段调用“通过反射”所以较慢,但是getter方法也是如此,不是吗?Hibernate需要将字段的可访问性设置为true,然后才能尝试读取它,这可能会带来一些轻微的开销。但是,这是否会在会话范围内的类级别或仅在读取配置并构建SessionFactory时执行一次呢?
我只是好奇这是否是一个神话,还是真的有道理;个人认为注释字段更易读。
3个回答

9

已将5000条记录加载到一个简单的三列表中。将两个类映射到该表,一个使用注释的私有字段,另一个使用注释的公共getter方法。运行了30次Spring的HibernateTemplate.loadAll()方法,然后是HibernateTemplate.clear()方法来清除Session缓存。以下是结果(以毫秒为单位)...

方法总数:6510,平均值:217

字段总数:6586,平均值:219

也许我应该在每个类中添加更多属性后再进行一次尝试,但现在差异似乎没有统计学意义。


3
5000条记录不具备统计学意义。您可以尝试使用更复杂的实体结构(需要连接操作),并增加到100倍的记录数量。对于小数据集,您始终会获得良好的性能。 - Justin Standard
1
对于任何对未来感兴趣的人。我已经在IMDb数据集上运行了非常相似的测试。我一共获取了演员表(超过800k行)以及他们的角色(1.3kk行)。 平均结果如下: 基于字段的访问:17720毫秒。 基于属性的访问:17914毫秒。 - Aramka

1

好的,哈哈我不能给出数字,但我猜通过反射访问字段不会只发生一次。每个对象都有自己的私有成员。

老实说我不太懂反射,但是 getter / setter 应该很简单。事实上,您可以将其中一个方法设置为私有方法,我认为它不起作用,因为无法找到所需的方法。

还有其他问题,例如代理,这将影响 getter 方法,具体取决于如何加载实体。

这是文档中所有内容:

access 属性允许您控制 Hibernate 在运行时访问属性的方式。 默认情况下,Hibernate 将调用属性 get/set 对。如果您指定 access="field",Hibernate 将绕过 get/set 对并直接访问该字段,使用反射。您可以通过命名实现 org.hibernate.property.PropertyAccessor 接口的类来指定自己的属性访问策略。

我猜反射总的来说成本会更高,但抱歉...没有数字 :(


1
需要使用反射来调用get/set方法。在编译时,Hibernate无法知道哪些get/set对需要在类上调用。关于设置可访问性的观点是,在java.lang.reflect.Field实例的类级别上完成的... - cliff.meyers
啊,是的,我猜这是有道理的,因为它必须查找实际名称。 - Arthur Thomas
1
@cliff.meyers 始终是编译时.... Hibernate使用类生成,并将助手类放入实体包中,因此除了私有成员(包私有也可以)之外,不需要反射。 - maaartinus

0
通常在getter方法上方使用注释,因为当类在JVM中加载时,如果您在字段或属性上方使用注释,则它将仅在每个请求的时间执行一次。而如果您将其放置在getter上方,则在反射或任何其他层调用此类时,getter方法将被调用,这将非常有用。

2
你能否改进一下你的回答措辞?我认为这并没有提供任何新的内容,因为已经在现有的回答中涵盖了,所以最好作为对已标记答案的评论。 - Dutts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接