【问题标题】:How to avoid Hibernate generating two queries for an update with OneToMany?如何避免 Hibernate 为 OneToMany 的更新生成两个查询?
【发布时间】:2016-05-15 10:02:43
【问题描述】:

我面临与this question 相同的情况,没有有用的答案。

当我向一对多关系的许多部分添加一个新元素时,Hibernate 会生成两个查询,一个用于插入,另一个用于将外键更新到父级。

为什么需要第二个查询?插入中没有设置父母的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);
        }
    }

【问题讨论】:

  • 您想避免哪个查询?两者看起来都很有用....
  • @JordiCastilla 第二个,更新。编辑了我的问题。

标签: java hibernate one-to-many hibernate-onetomany


【解决方案1】:

关联是单向的,所以Person 是拥有方(因为它是唯一的一方)。

使关联成为双向的,并使LanguageKnowledge 成为关联所有者。这样可以避免冗余更新,因为外键值将被指定为 LanguageKnowledge 的插入语句的一部分。

【讨论】:

  • 感谢您的回答,但您能否说一下,它到底为什么要进行更新?因为当我看到日志时,在子 Insert 查询中它已经添加了外键。所以它只是更新现有的 fk 以获得相同的值(冗余操作)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多