【问题标题】:Preferred way to make JPA / Hibernate Entities Immutable / Thread-safe使 JPA / Hibernate 实体不可变 / 线程安全的首选方法
【发布时间】:2012-08-14 14:28:16
【问题描述】:

我有一个有点标准化的数据库,其中实体对象由其他实体组成,我将在会话和应用程序范围内单独发布根实体,并在 Java Web 应用程序的集合中发布。我想知道将根 Entity 对象转换为线程安全且能够在 Web 应用程序环境中发布的不可变对象的最佳方法是什么。我找到的方法是:

1) 使用构建器将实体转换为 DAO 中的不可变对象。这似乎是最编程的方式,即必须遍历整个实体来设置不可变对象,但对于多线程环境来说,这似乎也是最安全的。

2) 使用工厂/构建器将实体转换为由 get 方法组成的只读接口,对此问题 here 进行了描述。这看起来很酷,但我从未在实践中尝试过,而且它似乎不是完全线程安全的,因为字段不是最终的,并且对象在某种程度上是可变的,只是不是任何使用 read- 的应用程序唯一的版本。

3) 使用特定于供应商的东西,例如 Hibernate 的 @Immutable 注释。起初这听起来不错,但在确保没有集合返回不可变值之后,它开始看起来像上面的选项 1,我只是通过迭代所有值并将它们转换为原始实体的不可变副本构建一个不可变的版本。此外,我找不到在 Web 应用程序中使用和发布 @Immutable 实体的任何示例。有没有人有这方面的经验,它是线程安全的吗?

示例实体关系(不完整且无功能,仅用于显示嵌套特性):

class A {
    @Id
    private long id;

    @OneToOne
    @JoinColumn
    private B b;
}

class B {

    @Id
    private long id

    private String something;

    @OneToMany
    @JoinTable
    private List<C> cs;
}

class C {
    @Id
    private long id;

    @Column
    private String name;

    @Column
    private String otherName;
}

感谢您的帮助。

【问题讨论】:

  • 遗憾的是,@Immutable 注释似乎被用于(从我看到的所有示例和文档中)来防止对实体的修改被推送到支持数据库。它似乎仍然需要可变字段和默认构造函数。如果您既想要不变性又想要休眠,我认为 #1 确实是您唯一的解决方案。

标签: hibernate jpa thread-safety entity immutability


【解决方案1】:

我的意见选项:

创建私有默认构造函数(hibernate需要的默认构造函数)。 为所有字段创建完整的构造函数并将它们定义为私有。

【讨论】:

  • 感谢您的回答。我在 Java Web 应用程序环境中使用了上面的 #1 来保证线程安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多