【问题标题】:Can we create a JPA mapping not matching the database constraints?我们可以创建一个不匹配数据库约束的 JPA 映射吗?
【发布时间】:2016-05-11 05:26:11
【问题描述】:

假设我有以下领域模型:

users
----
id (PK)
partitionkey (PK)

在上表中,分区键主要用于分区。 (MySQL 要求 partitionkey 是主键的一部分)。如果我们假设记录只能由 id 字段唯一标识,那么在映射中跳过 partitionkey 是否有任何危害。例如,下面的映射是否有效:

@Entity
@Table(name = "users")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public Long id;

    @Column(name="partitionkey")
    private Long partitionKey;

}

【问题讨论】:

  • 你的桌子叫什么名字?
  • @SKP,如果答案是您想要的,请接受其中一个(至少要支持另一个)。您不能同时接受两者,但您可以对两者都投赞成票。如果答案是您想要的,这是一种公平的做法。如果不是,您能否向我们提供更多您想要的信息? :)
  • @Paulo ,表名是错字(已修复)。对于那个很抱歉。这个问题的主要目的是了解映射是否需要与数据库严格对应。在这种情况下,数据库是否可以定义复合主键,但映射只定义复合主键中的一个字段为@Id,即DB定义id、partitionkey为主键,但只有 id 在映射中用 @Id 标记
  • 是的,映射已经严格对应于数据库。如果您有两列来指示主键,则必须在您的 java 类中指示。

标签: java mysql spring jpa spring-data


【解决方案1】:

是的,它是有效的。 JPA 提供者不知道实体映射到的表中存在的任何约束或其他功能。

但是,这是一种好方法吗,尤其是因为我们在这里讨论的是分区?请记住,实体是通过 id 关联的。因此,对于与User 关联的每个实体,JPA 提供程序将仅按 id 列搜索关联的User 实例,因此查询中不会包含分区列。这可能是也可能不是问题。请参阅this answer 了解更多详情。

另一种方法是在 Hibernate 中使用特定于提供商的扩展,例如 @JoinFormulas,但它们可能不容易做到。

我会说使用复合 ID 是最直接的解决方案。

【讨论】:

  • 谢谢,据我了解,不映射 id 中的分区键的问题是生成的查询可能在 where 子句中没有分区键?这可以通过使用 @Query 注释显式指定查询而不依赖于默认提供的框架生成的查询来抵消吗?
  • @SKP 请查看我编辑的答案。确切地说,自动生成的查询可能不包含 where 子句中的该列。
  • 不幸的是,使用复合键会带来其他问题。 partitionkey 不可为空,因此不适合填充父子实体。从我所看到的它的工作方式来看(对于父和子的新插入),JPA 实现首先对引用的列执行一个带有 null 的插入,然后尝试使用来自父列的正确值来更新它(对于自动在父级中生成的密钥)。如果引用的列不可为空(在这种情况下是分区键),这将失败。因此我的问题是忽略不可为空的列。
  • 如果映射正确,则不应插入空值。请参阅my comment
【解决方案2】:

尝试使用 PK 字段定义一个单独的 @Embeddable 对象,并将其用作 @EmbeddedId 在您的 @Entity 类中,如下所示:

  @Embeddable
  public class MyCompositePK { 

  @Column(name="id")
  private Long id;

  @Column(name="partitionkey")
  private Long partitionKey;
   }

   @Entity
   @Table(name = "users")
   public class User implements Serializable {

    @EmbeddedId
    private MyCompositePK id;
    ...

  }

【讨论】:

  • 这种改变有什么原因吗?这不是 OP 所要求的。
  • 表注解@AleksandrM在db中名称不同
  • 这就是 OP 的要求。正如您在问题标题中看到的那样:“JPA 映射 不匹配 数据库”。由于@Abdelhak 的回答,它不匹配。
  • 如果我们假设记录只能由 id 字段唯一标识,那么在映射中跳过 partitionkey 是否有任何危害。例如,下面的映射是否有效
  • 表名不匹配是一个错字(对此感到抱歉),已修复该问题并添加评论以澄清我的问题。
猜你喜欢
  • 2015-08-27
  • 2011-03-11
  • 2021-03-19
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2015-09-11
  • 2022-01-16
  • 2019-02-27
相关资源
最近更新 更多