【问题标题】:Is JPA Embeddable a Value Object and Why Can't it Represent a TableJPA 是否可嵌入一个值对象,为什么它不能表示一个表
【发布时间】:2019-11-27 10:56:58
【问题描述】:

问题:我的表中有只读数据。它的行没有 id - 只有复合键定义了它的身份。我希望它作为我的应用程序中的值对象(在 DDD 术语中)。

研究:但是如果我在@Id id 字段中添加@Embeddable 注释而不是@Entity,那么javax.persistence.metamodel 看不到它并在Metamodel metamodel.embeddable(MyClass.class); 上显示Not an embeddable。我可以用@Entity 类包装它并自动生成 id,但这不是我在架构上想要实现的目标。

问题:JPA 可嵌入值对象吗? Embeddable 可以在没有父实体的情况下存在并表示一个表吗?

【问题讨论】:

    标签: jpa entity domain-driven-design value-objects embeddable


    【解决方案1】:

    许多文章表明这是一个真正的 JPA 不便:

    他们中的大多数建议基于规范化关系数据库的解决方案,将标头实体作为一个表,将其值对象作为其他单独的表。

    与非规范化只读表集成的必要性加剧了我的挫败感。 表没有 id 字段,用于存储对象值。没有与标题实体表的绑定。用 JPA 映射它是一个问题,因为只有具有 id 的实体被映射。

    解决方案是用 MyEntity 类包装 MyValueObject 类,使 MyValueObject 成为其复合键:

    @Data
    @Entity
    @Table(schema = "my_schema", name = "my_table")
    public class MyEntity {
    
      @EmbeddedId MyValueObject valueObject;
    }
    

    作为一个小技巧,为了绕过 JPA 对默认空构造函数的要求并且不破坏值对象的不变性,我们将其添加为私有并牺牲字段的 final 修饰符。隐私和 setter 的缺失符合 DDD 最初的 Value Object 理念:

    // @Value // Can't use, unfortunately.
    @Embeddable
    @Immutable
    @AllArgsConstructor
    @Getter
    @NoArgsConstructor(staticName = "private") // Makes MyValueObject() private.
    public class MyValueObject implements Serializable {
    
      @Column(name = "field_one")
      private String myString;
    
      @Column(name = "field_two")
      private Double myDouble;
    
      @Transient private Double notNeeded;
    }
    

    还有一些 Lombok 的 @Value 注释来配置值对象。

    【讨论】:

      猜你喜欢
      • 2019-07-22
      • 1970-01-01
      • 2021-08-22
      • 2021-02-12
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      相关资源
      最近更新 更多