Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使JPA/Hibernate实体不可变/线程安全的首选方法_Hibernate_Jpa_Thread Safety_Entity_Immutability - Fatal编程技术网

使JPA/Hibernate实体不可变/线程安全的首选方法

使JPA/Hibernate实体不可变/线程安全的首选方法,hibernate,jpa,thread-safety,entity,immutability,Hibernate,Jpa,Thread Safety,Entity,Immutability,我有一个标准化的数据库,其中EntityObject由其他实体组成,我将在会话和应用程序范围内发布根实体,并在java web应用程序的集合中发布根实体。我想知道将根实体对象转换为线程安全且能够在web应用程序环境中发布的不可变对象的最佳方法是什么。我找到的方法是: 1) 使用生成器将实体转换为DAO中的不可变对象。这似乎是最安全的编程,即必须迭代整个实体来设置不可变对象,但对于多线程环境来说,这似乎也是最安全的 2) 使用factory/builder将实体强制转换为由get方法组成的只读接口

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

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

2) 使用factory/builder将实体强制转换为由get方法组成的只读接口,如本问题所述。这看起来很酷,但我从来没有在实践中尝试过,而且它似乎不是完全线程安全的,因为字段不是最终的,对象在某种程度上是可变的,只是任何使用只读版本的应用程序都不能

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

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

A类{
@身份证
私人长id;
@奥内托内
@连接柱
私人B,;
}
B类{
@身份证
私人长id
私人串东西;
@独身癖
@可接合
私人名单;
}
C类{
@身份证
私人长id;
@纵队
私有字符串名称;
@纵队
私有字符串otherName;
}

谢谢您的帮助。

关于我的意见选项:

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

感谢您的回答。为了Java web app环境中的线程安全,我使用了上面的#1。遗憾的是,
@Immutable
注释似乎被用来(从我所看到的所有示例和文档中)防止对实体的修改被推送到备份数据库中。它似乎仍然需要可变字段和默认构造函数。我认为#1真的是你唯一的解决方案,如果你想要不变性和休眠。
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;
}