Yes, the reason for that is that you have cascade="all". Now, for a read-only class, cascade="all" makes absolutely no sense - it means that it is possible to delete this object of class. In your case, I think that what is happening is that the update is cascaded to the child, which is an error, because the child is read-only.
Now, this -does- raise an interesting point. It is not unreasonable to have
Code:
<class name="Bar" immutable="true">
<cache usage="read-only"/>
</class>
<class name="Foo">
<many-to-one name="bar" class="Bar" cascade="save-update"/>
<class/>
Because you want new instances of Bar to be saved by cascade, but because they are immutable, an update is unnecessary.
Currently, Hibernate would throw an exception in this case. This is suboptimal, I think. You
should be able to persist immutable objects by cascade. What we need is for update() to degrade gracefully to lock() in the case of an immutable object.
Anyway, regarding your problem, try usage="nonstrict-read-write", if performance is bothering you - though I don't particularly see how it could be such a big difference.