代码之家  ›  专栏  ›  技术社区  ›  PanCrit

我能告诉Hibernate一个类是不可变的吗?这样它就可以共享对象以节省构建成本。

  •  4
  • PanCrit  · 技术社区  · 15 年前

    我有一些类表示不变的对象(数量、价格、概率)。有什么方法可以告诉Hibernate对象永远不会改变,这样它就可以重用对象,而不是为0或1的每个实例或price=$1创建一个新对象?

    我最终创建了这些类,因为我发现double不能很好地表示用户键入的数字。用户键入的数字是十进制的,如果您将其转换为双精度,您将立即失去精度(有时甚至是正确性)。因此,我用这些基于bigdecimal的对象替换了所有的数字(除了短期整数)。

    在前面的几个项目中,性能优化的一个主要步骤是缓存较小的数字,因此我们不会每次引用0或1或在特定项目中常见的其他较小的数字时都创建新的对象。所以我怀疑,如果Hibernate知道它可以重用特定类型的对象,那么它也可以节省大量的成本。

    作为一个干净的编程实践,它们是纯数字和不可变的,这意味着Java代码不必担心共享对象和副作用。我已经为代码中非常常用的数字定义了一些清单常量,但是Hibernate为它从数据库中调出的每个数字创建了一个新对象。(不然怎么办?它不知道它们是不变的,所以不能假定它们是可以共享的。)

    此时,我还将所有这些对象转换为休眠组件,因此不必担心在数据库中查找和删除不再被任何对象使用的数字。但这也意味着不再有quantity.hbm.xml来放置注释,即使hibernate支持这样的注释。

    顺便说一句,这种重写最令人反感的方面是,所有的算术现在都显示为 a.times(b), c.plus(d.minus(e)) 等等,但这是一个比任何事情都重要的正确性问题,所以我认为我没有选择。

    2 回复  |  直到 15 年前
        1
  •  7
  •   ChssPly76    15 年前

    你可以告诉Hibernate 实体 通过使用不可变 @Entity(mutable=false) @Immutable 注释。注意,两者都是 Hibernate extensions 符合JPA标准。

    那将 但是,强制Hibernate重新使用对象-就缓存/刷新而言,它只允许进行一些较小的性能优化。组件也不能以这种方式进行注释。

    要想做你想做的事情,你必须编写自己的自定义类型;然后你就可以为特定的(最常见的)值预先定义实例,并返回这些实例,而不是创建一个新的实例。

    另一种选择是定义 PreLoadEventListener 但是实体 已经在调用侦听器时实例化,因此只能用实例替换它。

        2
  •  0
  •   Rob Smith    15 年前

    利用休眠二级缓存。对于像您描述的那样的不可变对象,您将希望使用只读缓存策略。我在一些应用程序中使用了第二级缓存,它大大提高了性能。花时间真正了解缓存的影响是值得的,因此我强烈建议您阅读二级缓存上的Hibernate文档:

    Hibernate Second level cache