两列之间的JPA一对一关系(不是PK而不是FK)

时间:2016-09-25 13:41:43

标签: java hibernate jpa

我有两个表,一个名为“Category”,另一个“Rule”逻辑上与一对一关系使用不同于表的主键(PK)的字段(代码)而不是使用外键(FK):


CATEGORY
    ID (PK) NUMBER
    COD_RULE VARCHAR
    NAME VARCHAR
    .....

RULE
    ID (PK) NUMBER
    CODE VARCHAR
    TYPE VARCHAR
    .....

I haven't on Rule table FK to category ID but only unique constraint (the relation is 1 to 1)

在JPA中以这种方式实施

 public Category implement Serializable {
   @Id
   @Column (name="ID")
   private Long id;

   @NotNull
   @OneToOne(cascade=CascadeType.ALL)
   @JoinColumn(name="CODE_RULE" referencedColumnName="CODE", nullable=false)
   private Rule;

   @Column (name="NAME")
   private String  name;

   //Getter and Setter methods
   .......
}

public Rule implement Serializable {
   @Id
   @Column (name="ID")
   private Long id;

   @NotNull    
   @Column (name="CODE")
   private String code;

   @Column (name="TYPE")
   private String  type;

   //Getter and Setter methods
   .......
}

我需要:

  1. 检索时,类别也会获取相关规则的所有信息
  2. SELECT c.*, r.type FROM Category c LEFT OUTER JOIN Rule r WHERE c.CODE_RULE = r.CODE
    
    1. 当编辑类别将CODE_RULE与CODE保持对齐时,所以如果我更改CODE_RULE,我会自动更改规则上的CODE
    2. UPDATE Category SET COD_RULE='5A', NAME='Test' WHERE ID=1 
      UPDATE Rule SET CODE='5A' WHERE CODE='AB'
      

      我在规范上看到:

        

      一对一协会有三种情况:要么是   关联实体共享相同的主键值,即外键   由其中一个实体持有(注意这个FK列中的   数据库应该被约束为模拟一对一的唯一   multiplicity),或关联表用于存储链接   在两个实体之间(必须在每个实体上定义唯一约束)   fk确保一对一的多重性。)

      但是这个实现满足要点1.但不是第2点。 假设我已经创建了Category(在ID = 1上)和相关规则,当我编辑类别(具有CODE_RULE = CODE =“AB”)并将代码更改为“5A”时:

      @PersistentContext
      private EntityManager em;
      .......
       Category cat = em.find(Category.class, 1L);
       cat.setName("Test");
       cat.getRule().setCode("5A");
      
       em.merge(cat);
      

      我看到代码已在规则上更新,但未在类别中更新:

      编辑之前

      Category (ID, COD_RULE, NAME) --> (1, AB, First Category)
      Rule (ID, CODE, TYPE) --> (10, AB, C)
      

      编辑后

      Category (ID, COD_RULE, NAME)--> (1, AB, Test)
      Rule (ID, CODE, TYPE) --> (10, 5A, C)
      

      我如何在JPA中完成这项工作? JPA规范是否支持这种类型的操作? 有替代方案(即我必须在规则之前合并然后分类)?

1 个答案:

答案 0 :(得分:0)

从您的数据模型中,它看起来更像是类别和规则之间的多对一关系,在您的数据模型中仅限制每个类别可以引用[0..1] Rule,但不限制多少{ {1}} Categories可以被引用。

根据您的评论,您似乎可以更改数据模型。通常如果它是〜ToOne关系,你应该让推荐方引用为FK,如下所示:

(表)

Rule

实体应该看起来像

CATEGORY (
  CATEGORY_ID NUMBER PK,
  CATEGORY_CODE VARCHAR, // Unqiue
  RULE_ID NUMBER FK to RULE,
  ...  (Don't refer by RULE_CODE!!)
)

RULE (
  RULE_ID NUMBER PK,
  RULE_CODE VARCHAR,  // unique, can be updated
  ...
)

(班级class Category { @Id @Column(name="CATEGORY_ID) Long id; @ManyToOne // or @OneToOne if you really insist @JoinColumn(name="RULE_ID) Rule rule; ) 是直截了当的,我会跳过)

你提到的HQL应该是

Rule

对于第2点,正如您在评论中提到的那样,在更新“类别”代码时,您尝试将“规则”代码与“类别”代码对齐。这应该实现为:

// When retrieiving Category together with Rule
from Category c join fetch c.rule

根据个人经验,在使用JPA时,基于领域模型设计的生活将更容易驱动数据模型。它应该可以节省很多问题,这些问题看起来是可以容忍的数据模型"。