【问题标题】:JPA single table inheritance with abstract generics and collection具有抽象泛型和集合的 JPA 单表继承
【发布时间】:2017-11-27 16:50:29
【问题描述】:

我有如下 JPA 映射的类:

@Entity
@Inheritance
public abstract class FieldValue<T> {
   @Id @GeneratedValue
   private Long id;

   public abstract T getValue();
}

@Entity
public class TextFieldValue extends FieldValue<String> {
   @Column(name = "TEXT_VALUE")
   private String value;

   public String getValue() { return value; }
}

@Entity
public class NumberFieldValue extends FieldValue<Double> {
   @Column(name = "NUMBER_VALUE")
   private Double value;

   public Double getValue() { return value; }
}

@Entity
public class SelectFieldValue extends FieldValue<ValueOption> {
   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "SELECT_VALUE")
   private ValueOption value;

   public ValueOption getValue() { return value; }
}

我使用的是单表继承类型,这会导致每个值字段映射到不同的列。在 SelectFieldValue 中,该值是对另一个实体的引用,但映射仍然正常工作,使用 ValueOption 的 id 填充 SELECT_VALUE 列。

但是,我还想添加带有实体列表的类:

@Entity
public class MultipleSelectFieldValue extends FieldValue<List<ValueOption>>{
   @ManyToMany // ??
   private List<ValueOption> value;

   public List<ValueOption> getValue() { return value; }
}

我似乎找不到合适的映射来处理此类实体列表。这甚至可以通过单表继承策略实现吗?例如,它可以使用连接表中单行的 id 填充 MultipleSelectFieldValue 的列,这将存储从 MultipleSelectFieldValue 到 ValueOption 的多对多映射。

我尝试了以下映射:

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "field_value_value_option",
        joinColumns = @JoinColumn(name = "field_value_id"),
        inverseJoinColumns = @JoinColumn(name = "value_option_id"))
private List<ValueOption> value;

但奇怪的是,它没有向 FieldValue 表添加新列,因此无法正常工作。

【问题讨论】:

  • @ManyToMany 关系需要一个额外的表来存储关系。所以你的映射应该工作。为什么你认为这行不通?
  • 我也有同感,但是这样的映射不会为表中的 MultipleSelectFieldValue 生成额外的列。我已经用代码更新了我的问题。
  • 为什么是SINGLE_TABLE?使用JOINED,您可以摆脱所有@Column(name = "XXXX_VALUE")

标签: java list hibernate jpa inheritance


【解决方案1】:

但奇怪的是,它并没有向 FieldValue 表添加新列, 因此无法正常工作。

我认为它可以正常工作。

未添加列,因为不需要新列。连接表做的事情。我有一些不同的实体名称,但请看一下这些数据

  id  |      dtype       | number_value | string_value 
------+------------------+--------------+--------------
 1551 | StringValue      |              | hi!
 1552 | NumberValue      |           55 | 
 1553 | MultiStringValue |              |
 1554 | StringValue      |              | s1
 1555 | StringValue      |              | s2
 1556 | MultiStringValue |              | 

那就看看映射表

 field_value_id | value_option_id 
----------------+-----------------
           1553 |            1554
           1553 |            1555
           1556 |            1554
           1556 |            1555

比较id可以看到Value通过映射表引用了自己。所以MultiStringValues 和两个相同的StringValues 都有关系,所以ManyToMany 在没有新列的情况下工作。

【讨论】:

  • 你说得对。我没有好好想清楚。实际上,我的代码中有一个不同的错误导致测试失败。 JPA 映射的行为正确。
猜你喜欢
  • 2023-04-03
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 2010-10-13
  • 2011-12-28
相关资源
最近更新 更多