views:

250

answers:

4

Which ORM supports a domain model of immutable types?

I would like to write classes like the following (or the Scala equivalent):

class A {
  private final C c; //not mutable

  A(B b) {
     //init c
  }

  A doSomething(B b) {
     // build a new A
  }
}

The ORM has to initialized the object with the constructor. So it is possible to check invariants in the constructor. Default constructor and field/setter access to intialize is not sufficient and complicates the class' implementation.

Working with collections should be supported. If a collection is changed it should create a copy from the user perspective. (Rendering the old collection state stale. But user code can still work on (or at least read) it.) Much like the persistent data structures work.

Some words about the motivation. Suppose you have a FP-style domain object model. Now you want to persist this to a database. Who do you do that? You want to do as much as you can in a pure functional style until the evil sides effect come in. If your domain object model is not immutable you can for example not share the objects between threads. You have to copy, cache or use locks. So unless your ORM supports immutable types your constrainted in your choice of solution.

+2  A: 

Hibernate has the @Immutable annotation.

And here is a guide.

Bozho
As far as I know Hibernate does not support final fields and "constructor injection" of values.
Thomas Jung
do you need `final`? You can just limit it with the lack of setters.
Bozho
Wouldn't be immutable otherwise. I don't like frameworks to restrict my choice of language features.
Thomas Jung
If it is not final and the ORM is not forced to use the constructor to initialize the instance things get more complicated that they should (http://stackoverflow.com/questions/1624392/check-invariants-in-hibernate-mapped-classes).
Thomas Jung
You're wrong about NH: it supports read-only entity semantics, which is different to common definition of immutable object. Think about collections.
Alex Yakunin
just that it's about hibernate, not NH :)
Bozho
A: 

AFAIK, there are no ORMs for .NET supporting this feature exactly as you wish. But you can take a look at BLTookit and LINQ to SQL - both provide update-by-comparison semantics and always return new objects on materialization. That's nearly what you need, but I'm not sure about collections there.

Btw, why you need this feature? I'm aware about pure functional languages & benefits of purely imutable objects (e.g. complete thread safety). But in case with ORM all the things you do with such objects are finally transformed to a sequence of SQL commands anyway. So I admit the benefits of using such objects are vaporous here.

Alex Yakunin
See edit. The problem is not in the persistence part but in the layers that build on the domain objects.
Thomas Jung
A: 

Though not a real ORM, MyBatis may able to do this. I didn't try it though.

http://mybatis.org/java.html

Martin
A: 

You can do this with Ebean and OpenJPA (and I think you can do this with Hibernate but not sure). The ORM (Ebean/OpenJPA) will generate a default constructor (assuming the bean doesn't have one) and actually set the values of the 'final' fields. This sounds a bit odd but final fields are not always strictly final per say.

Rob