Java 不可变对象的Hibernate组件映射

Java 不可变对象的Hibernate组件映射,java,hibernate,Java,Hibernate,我有一个不可变对象,它是使用组件映射的Hibernate持久化对象的成员。例如,PinDrop对应于一个表,该表的字段类型为immutablePoint: public class PinDrop { private String name; private Point location; // Getters and setters for name and location } // Immutable Point public class Point {

我有一个不可变对象,它是使用组件映射的Hibernate持久化对象的成员。例如,
PinDrop
对应于一个表,该表的字段类型为immutable
Point

public class PinDrop {
    private String name;
    private Point location;
    // Getters and setters for name and location
}

// Immutable Point
public class Point {
    private final double x;
    private final double y;
    // Getters for x and y, no setters
}
在my
PinDrop.hbm.xml
中:

<property name="name" column="name" type="string"/>
<component name="location" class="Point>
    <property name="x" column="location_x" type="double"/>
    <property name="y" column="location_y" type="double"/>
</component>

你试过注释吗

将实体或集合标记为不可变。无注释意味着 元素是可变的

应用程序不能更新不可变的实体。更新至 将忽略不可变实体,但不会引发异常。 @Immutable只能在根实体上使用

@不可变放置在集合上会使集合不可变, 这意味着不允许对集合进行添加和删除 允许。在这种情况下会引发HibernateException


据我所知,对于在*.hbm.xml中使表不可变,
mutable=“false”
属性会有所帮助。

您可以告诉hibernate使用字段访问(属性
access=field
在您的hbm中),这样hibernate就不会抱怨缺少访问器


Hibernate使用反射来修改最终字段,这样它就可以工作。

Hibernate并不真正喜欢不可变的对象。你最好的选择是

  • 使用不使用
    final
    关键字但没有设置器的伪不可变对象,然后告诉Hibernate通过字段设置值
  • 让hibernate填充可变构建器对象,然后让它将其属性复制到适当的不可变对象中。不幸的是,这意味着每个BO/DTO有两个类

我应该把它放在
hbm.xml
文件中的什么地方?表不是不可变的,而是组件不相信这会起作用,但它确实起作用。显然,可以使用反射修改最终字段。我想知道这对Java内存模型有什么影响,因为最终字段保证是线程安全的,并且对所有线程都正确可见。设置final字段太奇怪了,就像Steve评论的那样,可能会干扰其他有效的线程安全假设。