如何避免 Hibernate 为使用 OneToMany 的更新生成两个查询?
How to avoid Hibernate generating two queries for an update with OneToMany?
我面临与 this question 相同的情况,没有有用的答案。
当我向一对多关系的多部分添加新元素时,Hibernate 会生成两个查询,一个用于插入,一个用于更新父项的外键。
为什么需要第二次查询? insert中不是设置了parent的id吗?
有什么办法可以避免这种情况吗?
Hibernate:
/* insert mydomain.LanguageKnowledge */
insert
into
languageKnowledge
(language_fk, level_fk, personId_fk)
values
(?, ?, ?)
Hibernate:
/* create one-to-many row mydomain.Person.offeredLanguages */
update
languageKnowledge
set
personId_fk=?
where
id=?
public class LanguageKnowledge {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@Enumerated(STRING)
@Column(name = "language_fk")
private LanguageIso639_3 language;
@Enumerated(STRING)
@Column(name = "level_fk")
private LanguageLevel level;
protected LanguageKnowledge() {
}
}
public class Person {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@OneToMany(fetch = EAGER, cascade = {ALL}, orphanRemoval = true)
@JoinColumn(name = "personId_fk", referencedColumnName = "id", nullable = false)
private final Set<LanguageKnowledge> offeredLanguages = new HashSet<>();
public Person(Set<LanguageKnowledge> offeredLanguages) {
addOfferedLanguages(offeredLanguages);
}
protected Person() {
}
public void addOfferedLanguages(Set<LanguageKnowledge> offeredLanguages) {
this.offeredLanguages.addAll(offeredLanguages);
}
public void removeOfferedLanguages(Set<LanguageKnowledge> offeredLanguagesToRemove) {
this.offeredLanguages.removeAll(offeredLanguagesToRemove);
}
}
关联是单向的,因此 Person
是拥有方(因为它是唯一的一方)。
使关联成为双向关联并使 LanguageKnowledge
成为关联所有者。这样您将避免冗余更新,因为外键值将被指定为 LanguageKnowledge
.
的插入语句的一部分
我面临与 this question 相同的情况,没有有用的答案。
当我向一对多关系的多部分添加新元素时,Hibernate 会生成两个查询,一个用于插入,一个用于更新父项的外键。
为什么需要第二次查询? insert中不是设置了parent的id吗? 有什么办法可以避免这种情况吗?
Hibernate:
/* insert mydomain.LanguageKnowledge */
insert
into
languageKnowledge
(language_fk, level_fk, personId_fk)
values
(?, ?, ?)
Hibernate:
/* create one-to-many row mydomain.Person.offeredLanguages */
update
languageKnowledge
set
personId_fk=?
where
id=?
public class LanguageKnowledge {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@Enumerated(STRING)
@Column(name = "language_fk")
private LanguageIso639_3 language;
@Enumerated(STRING)
@Column(name = "level_fk")
private LanguageLevel level;
protected LanguageKnowledge() {
}
}
public class Person {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@OneToMany(fetch = EAGER, cascade = {ALL}, orphanRemoval = true)
@JoinColumn(name = "personId_fk", referencedColumnName = "id", nullable = false)
private final Set<LanguageKnowledge> offeredLanguages = new HashSet<>();
public Person(Set<LanguageKnowledge> offeredLanguages) {
addOfferedLanguages(offeredLanguages);
}
protected Person() {
}
public void addOfferedLanguages(Set<LanguageKnowledge> offeredLanguages) {
this.offeredLanguages.addAll(offeredLanguages);
}
public void removeOfferedLanguages(Set<LanguageKnowledge> offeredLanguagesToRemove) {
this.offeredLanguages.removeAll(offeredLanguagesToRemove);
}
}
关联是单向的,因此 Person
是拥有方(因为它是唯一的一方)。
使关联成为双向关联并使 LanguageKnowledge
成为关联所有者。这样您将避免冗余更新,因为外键值将被指定为 LanguageKnowledge
.