【问题标题】:Conditional unique constraint using annotations使用注释的条件唯一约束
【发布时间】:2017-01-14 23:50:47
【问题描述】:

我有两个具有两种不同类型(GENERAL 和 CUSTOM)的相关实体,并将其保存在同一个表中。 GENERAL 类型的实体应该具有唯一的字段名称值,并且 CUSTOM 可以为不同的用户重复,而不是重复的 GENERAL 名称。 我正在寻找一种方法来创建条件唯一约束以检查下一个案例:

  • 如果实体的类型为 GENERAL,则名称应该是唯一的
  • 如果实体具有 CUSTOM 类型,则名称可以在表中重复但不能重复 GENERAL 项,并且对于特定用户应该是唯一的(按用户 ID)

    @Entity
    @Table(name = "Purpose", uniqueConstraints = @UniqueConstraint(columnNames = {"purposeId"}))
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    public class GeneralPurpose {
    
    

    @Id @GeneratedValue(strategy=GenerationType.AUTO, generator="purpose_seq_gen") @SequenceGenerator(name="purpose_seq_gen", sequenceName="PURPOSE_SEQ") @Column(name = "purposeId", nullable = false) private long purposeId;

    @Column(name = "type", nullable = false) @Enumerated(EnumType.STRING) private PurposeType type;

    @Column(name = "name", nullable = false) private String name;

    @Entity
    @Table(name = "Purpose")
    public class CustomPurpose extends GeneralPurpose {
    
    

    @ManyToOne() @JoinColumn(name="id") @JsonIgnore private User user;

    public enum PurposeType {
        GENERAL, CUSTOM
    }

【问题讨论】:

    标签: java mysql spring hibernate unique-constraint


    【解决方案1】:

    您可以通过在“用途”表中添加另一列来完成此操作。此列用于存储 GENERAL 记录的常量值和 CUSTOM 记录的用户 ID。对于 GENERAL 记录,该值可以是 0(如果用户 ID 是数字)或“GENERAL”(如果用户 ID 是字符串)。它可以命名为 'userOfRecord' 或 'recordDiscriminator' 之类的。

    然后您可以在 [ type, name, userOfRecord ] 上添加唯一约束。

    【讨论】:

    • 实际上唯一约束必须在 [name, userOfRecord] 上。
    • 这不是我想要的。此解决方案存在一些问题。如果 userOfRecord 将具有唯一约束,我将无法保存一些 GENERAL 项目,因为它具有相同的 id(0)。如果我将唯一约束添加到名称,一些不同的用户将无法保存具有相同名称的项目
    • 约束在两个字段上,包括名称和'userOfRecord'。可能的行:('Tom', 0, 'GENERAL'); ('迪克', 0, '一般'); (“哈利”,500,“自定义”); ('Harry', 600, 'CUSTOM').... 由于这两个字段的组合必须是唯一的,因此您可以拥有两个 'Harry' 行,因为 'userOfRecord' 是不同的。但是你不能有两个 'Tom', 0, 'GENERAL' 行,因为这两行都将 0 作为 'userOfRecord'。
    • 实际上我已经拥有 userOfRecord 字段,并且我向该字段和名称字段添加了唯一约束。现在它在尝试向同一用户添加记录时失败了 ("Item name 1", CUSTOM, 1), ("Item name 2", CUSTOM, 1) @Column(name = "name", nullable = false, unique = true) private String name; @ManyToOne() @JoinColumn(name="id", unique = true) @JsonIgnore private User user;
    • 您是否有两个不同的唯一约束,每个字段一个?或者你对这两个字段都有一个唯一的约束?在实体类上,您应该有这样的注释:@Table(name = "my_table_name", uniqueConstraints = @UniqueConstraint(name="my_constraint_name", columnNames = {"NAME", "userOfRecord"}))。所以,只有一个约束,列出两个字段。实际上我会在 DDL 中单独定义约束,但无论哪种方式都是相同的概念......这两个字段的组合必须是唯一的,而不是单独的。
    猜你喜欢
    • 2011-11-21
    • 2010-10-26
    • 1970-01-01
    • 2013-04-20
    • 2021-07-22
    • 2017-07-07
    • 1970-01-01
    • 2012-07-21
    相关资源
    最近更新 更多