【问题标题】:@OneToMany relationship does not save the primary key of the parent in the children tables@OneToMany 关系不会将父项的主键保存在子表中
【发布时间】:2019-03-24 01:37:18
【问题描述】:

假设有三个 JPA 实体。一个Person 和两个一对多的关系。当我试图保存 Person AD_P_IDAC_P_ID 时,外键始终为空。 这些字段的预期值是人员 ID。我做错了什么?

  1. Person.java:这包含与 AccountAddress 实体类的一对多关系:

    @Entity
    @Table(name = "A2C_PERSON")
    class Person implements Serializable {
    
        private long id;
    
        private List<Account> acs;
    
        private List<Address> ads;
    
        @OneToMany(cascade=CascadeType.ALL, mappedBy = "person")
        public List<Account> getAccount() {
            return this.acs;
        }
    
        @OneToMany(cascade=CascadeType.ALL, mappedBy = "person")
        public List<Address> getAddress() {
            return this.ads;
        }
    }
    
  2. 帐户.java

    @Entity
    @Table(name = "A2C_ACCOUNT")
    public class Account implements Serializable {
    
        private long id;
    
        private Person person;
    
        @ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
        @JoinColumn(name = "AC_P_ID")
        public Person getPerson() {
            return this.person;
        }
    }
    
  3. 地址.java

    @Entity
    @Table(name = "A2C_ADDRESS")
    public class Address implements Serializable {
    
        private long id;
    
        private Person person;
    
        @ManyToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
        @JoinColumn(name = "AD_P_ID")
        public Person getPerson() {
            return this.person;
        }
    }
    

救人的密码:

Person p = new Person();

Account ac1 = new Account();
Account ac2 = new Account();
List<Account> acList = new ArrayList<>();
acList.add(ac1);
acList.add(ac2)

Address ad1 = new Adddress();
Address ad2 = new Adddress();
List<Address> adList = new ArrayList<>();
acList.add(ad1);
acList.add(ad2)

p.setAcs(acList);
p.setAds(adList);

personRepo.save(p);

【问题讨论】:

    标签: java spring hibernate jpa spring-data-jpa


    【解决方案1】:

    对于每个AddressAccount 实体,您需要设置Person 实体。 这是强制性的,以便 hibernate 将 ids 保存在孩子中:

    Person p = new Person();
    
    Account ac1 = new Account();
    ac1.setPerson(p);  
    List<Account> acList = new ArrayList<>();
    acList.add(ac1);
    
    Address ad1 = new Adddress();
    ad1.setPerson(p);
    List<Address> adList = new ArrayList<>();
    acList.add(ad1);
    

    【讨论】:

    • 这行得通,但是@Maxim Popravko 的答案在通常情况下会更好,因为您希望所有事情都自动发生:)
    【解决方案2】:

    @JoinColumn 表示关系的所有者。

    “MappedBy”表示反面。

    所以:

    @OneToMany(mappedBy = "parent")
    private Collection<Child> childCollection;
    

    不会将父引用设置为其子引用。这是你的情况。您可以像 Maciej 建议的那样手动设置它,但它会添加一些样板代码。

    要自动设置父级对其子级的引用,您必须按以下方式定义关系的所有者。

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn
    private Collection<Child> childCollection;
    

    【讨论】:

    • 这会抛出异常:调用 init 方法失败;嵌套异常是 org.hibernate.AnnotationException: 标记为 mappedBy 的关联不得定义数据库映射,如 [@]JoinTable 或 [@]JoinColumn: com.registration.dao.Person.account 无论如何,非常感谢您的回复 :)
    猜你喜欢
    • 2019-07-08
    • 2020-06-17
    • 2010-10-23
    • 2016-09-03
    • 2011-04-09
    • 2019-09-23
    • 2019-03-31
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多