我有两个表,一个名为“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
.......
}
我需要:
SELECT c.*, r.type FROM Category c LEFT OUTER JOIN Rule r WHERE c.CODE_RULE = r.CODE
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规范是否支持这种类型的操作? 有替代方案(即我必须在规则之前合并然后分类)?
答案 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时,基于领域模型设计的生活将更容易驱动数据模型。它应该可以节省很多问题,这些问题看起来是可以容忍的数据模型"。