Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can I tell Hibernate a class is immutable so it will share the objects to save cost of construction?

I have some classes that represent immutable objects (Quantity, Price, Probability). Is there some way to tell Hibernate that the objects will never change so it can re-use objects rather than creating a new object for every instance of 0 or 1 or Price= $1?

I ended up creating these classes because I discovered that doubles don't do a good job of representing numbers typed by users. Users type numbers in decimal, and if you convert them to doubles, you immediately lose precision (and sometimes correctness). I therefore have replaced all the numbers (other than short-lived ints) with these objects which are based on BigDecimal.

In several previous projects, a major step in performance optimization was caching small numbers, so we weren't creating a new object every time we referred to 0 or 1 or whatever other small numbers were common in the particular project. So I suspect that hibernate would also make sizable savings if it knew it could re-use objects of particular types.

As a matter of clean programming practice, they are pure numbers and immutable, which means the Java code doesn't have to worry about shared objects and side effects. I've defined a few manifest constants for the numbers that are very commonly used in my code, but Hibernate creates a new object for every number it pages in from the DB. (How could it do otherwise? It doesn't know they're immutable, so it can't assume they can be shared.)

At this point I've also turned all these objects into hibernate components, so I don't have to worry about finding and deleting numbers in the database that are no longer used by anything. But that also means there's no longer a Quantity.hbm.xml to put an annotation on, even if hibernate supported such an annotation.

BTW, the most objectionable aspect of this rewrite is that all arithmetic now appears as a.times(b), c.plus(d.minus(e)), etc. But it was a correctness issue more than anything, so I didn't think I had a choice.

like image 330
PanCrit Avatar asked Nov 06 '09 00:11

PanCrit


People also ask

Can we make immutable class in Hibernate?

There's one obstacle on the way of creating immutable entity classes with an ORM framework like Hibernate. Hibernate uses reflection to instantiate entities, it, therefore requires a default, no argument constructor. This means class fields can never be final.

In which way can we obtain an immutable class in Hibernate?

You can tell Hibernate that a specific entity is immutable by using @Entity(mutable=false) or @Immutable annotations.


1 Answers

You can tell Hibernate that a specific entity is immutable by using @Entity(mutable=false) or @Immutable annotations. Note that both are Hibernate extensions to JPA standard.

That would not, however, force Hibernate to re-use the objects - it would merely allow for some minor performance optimizations as far as caching / flushing is concerned. Components can't be annotated this way either.

To do what you want you'd have to write your own custom type; you would then be able to have predefined instances for specific (most common) values and return those instead of creating a new instance.

Another alternative is to define a PreLoadEventListener to do that; however entity is already instantiated by the time your listener is called so you'd only be able to replace it with your instance.

like image 153
ChssPly76 Avatar answered Oct 04 '22 09:10

ChssPly76