【问题标题】:JPA repository saves the wrong type of a field in my entityJPA 存储库在我的实体中保存了错误类型的字段
【发布时间】:2021-07-14 14:23:21
【问题描述】:
  • 数据库:H2
  • 春天,JPA

我有一个名为 Message 的实体,其类型基本上只是一个带有 id 的通用父级:

public class Message {

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL, orphanRemoval = true)
    @NonNull
    List<GenericDTO> records;
}

通用DTO:

@Entity
@Inheritance
public class GenericDTO {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @JsonIgnore
    private int dto_id;

    public String toStringMessage(List<GenericDTO> records){
        return "";
    }
}

ChildDTO:

@Data
@Builder(toBuilder = true)
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class ChildDTO extends GenericDTO{
  // some fields
}

现在,当我尝试保存消息时,记录字段将保存为 GenericDTO 而不是 ChildDTO。

这个问题与H2有关吗?

【问题讨论】:

  • 您的列表是GenericDTO,而不是ChildDTO 的列表。因此对于 JPA,它需要存储一个 GenericDTO
  • @M.Deinum 是的,但是 JPA 应该能够处理这种类型的多态性,不是吗?我也有其他ChildDTOs,这就是GenericDTO 的原因。当我保存 Message 时,我保存的 DTO 是 ChildDTO 而不是 GenericDTO
  • 集合需要具有正确的类型,因为类型将由该类型决定,在本例中为GenericDTOGenericDTO 也不应该是 abstract@MappedSuperclass 而不是 @Entity
  • @M.Deinum 如果我使用@MappedSuperClass 我不能在@OneToMany 中使用GenericDTO

标签: java hibernate jpa spring-data-jpa h2


【解决方案1】:

默认情况下,jpa 将层次结构的所有实体保存在一个表中,该表包含所有可能的实体字段的列。这就是为什么您的孩子被保存到 GENERICDTO 表的原因。要将层次结构中每个类的实体保存到单独的表中,您需要指定继承策略:

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

我建议您查看这篇文章以获取有关该主题的更多信息:https://www.baeldung.com/hibernate-inheritance

【讨论】:

    【解决方案2】:

    解决方案有点棘手,GenericDTOChildDTO 在不同的项目中,发生的情况是项目中存在 ChildDTO 的包没有被扫描,因此对于 spring 是未知的。添加包扫描解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-03
      • 2019-06-23
      • 2012-07-20
      • 2014-06-22
      • 2013-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多