views:

109

answers:

4

I'm very new to Java but I've been developing a habit to use final wherever possible declaring immutability which i think is a good thing. (Consider f#)

I've read that JPA does not support final fields. Hibernate, TopLink? I'm not sure about these but i prefer JPA for now.

Is that even possible theoretically - let's say through reflection - to modify final fields after creation? My guess would be... NO :)

What would be certainly possible for a persistence solution is to support constructors with parameters. At least i see no reason that would make this impossible. Mapping would be a little tricky i guess. This is an alternative solution.

Suggestions?

EDIT: I'm not familiar with the exact definition for immutable so i used it in this post intuitively. Declaring Immutability here means declaring that a field cannot be changed. Sorry for the misunderstanding.

A: 

This is honestly a strange idea.

By making fields final, you tell the compiler they'll never change after object creation. As a consequence, it is a reasonable assumption to not persist them, since they will never change. Well, by writing this, I assume you have the java culture, but the question you ask precisely tells the contrary.

In Java, persisted obejcts are "always" assumed to be POJO (in other words, Java Beans). A Java Bean must have (to be considered as such) an empty constructor that will allow persistance frameworks and so on to construct it using its empty constructor, by indirectly calling it through Class.newInstance()/.

There are fields where non empty constructors are used (like IoC containers - Guice, Spring and Tapestry IoC), but it is out of the scope of Java Beans, which have to be considered as data objects.

Riduidel
What about a read-only database? BTW i'm just exploring possibilities.
naeron84
Other use cases: multiple entity for one table. Or creating those entities through a factory method.
naeron84
+5  A: 

Object immutability (note the difference between an immutable object, and declaring a field final - an object is ONLY immutable if ALL fields are final, thus the object's state can't change after creation) is a very sensitive topic. I like them myself, and hibernate supports them through @Immutable.

Don't know about it's status in JPA 2, but to answer the question about final fields: you CAN change their values using reflection - but reflection is severly limited in a Java EE environment.

To enlighten the main problem: if your POJOs are immutable, then how would a persistent solution recreate the objects? Let's say you have two final int fields, and a ctor to initialize them. The persistence layer cannot have any about their order, or their names (as field and parameter names are erased during compiling).

Koshuke posted a blog about this (in relation to JAXB supporting immutable beans), but can't find it right now.

Zoltan
I've found this blog: http://weblogs.java.net/blog/kohsuke/archive/2005/02/jaxb_20_and_imm_1.html
naeron84
+1  A: 

This may not be exactly what you're striving for, but the immutability principle can easily be supported by non-final private fields having only a getter. The compiler in fact recognizes this and generates code which is pretty much identical to what you'd get with fields declared as final.

This will require you to be conscientious and not change your fields from within the containing class (whereas final would enforce that), but I think this is not a big price to pay for the flexibility you gain.

Carl Smotricz
+1  A: 

Final fields can't be modified after creation by design. Doing otherwise is a very bad idea, because somebody can rely on standard behavior.

In general, persistence frameworks deal with hierarchies of "normal" objects. You have objects, that can be only created and removed, not modified. That's very odd, because when you create an entity, you create some kind of ID for it. Through this ID you connect entity to others. When you remove old entity and create another, you (in general) get an entity with another ID. So, all connections (foreign keys) are broken. Is it target behaviour?

Alexander Babaev
You make some valid points; +1.
Carl Smotricz