【问题标题】:Hibernate save object (one to many relationship) foreign key is nullHibernate保存对象(一对多关系)外键为空
【发布时间】:2016-12-28 19:11:13
【问题描述】:

我在 person 类和 car 类之间有一对多的关系。一个人可以拥有多辆汽车,反之亦然。我正在使用 RESTful API 来发布数据。我的注释和 Get 服务工作正常,但每当我尝试插入新数据时,我的 post 服务都会抛出“java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL" error。子表 foreign key 被插入为 null。

这是我的代码的一部分。

Person.java

 private List<Car> cars = new ArrayList<Car>();

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")    
@JsonManagedReference
public List<Car> getCars() {
  return cars;
 }

汽车.java

private Person person;  

    @ManyToOne
    @JoinColumn(name = "PERSON_ID", nullable = false, updatable = true, insertable = true)
    @JsonBackReference
    public Person getPerson() {
        return person;
    }

我的服务等级:

@POST
        @Path("/PersonRegistration")
        @Consumes(MediaType.APPLICATION_JSON)
        public Response postPersonCars(Person person) throws Exception{

            Session session = null;     
            ObjectMapper mapper = new ObjectMapper();   
            //Person per = new Person();
            //Car cars = new Car();
            try{
                session = HibernateUtil.getSessionFactory().openSession();
                session.beginTransaction(); 
                //per.setCars(person.getCars());
                session.save(person);
                session.getTransaction().commit();

            }catch(Exception e){
                e.printStackTrace();
                throw e;
            }finally{
                if(null != session){
                    session.close();
                }
            }

            return Response.status(201).entity(mapper.writeValueAsString(person)).build();
        }

【问题讨论】:

    标签: java hibernate rest jakarta-ee http-post


    【解决方案1】:

    这个注释:

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")
    

    有两个后果:

    1. mappedBy 暗示 Car 是关系的拥有方。这意味着每当您想在Car 和Person 之间建立关系时,您需要通过将Car.person 属性设置为适当的值来实现。 Hibernate 将忽略对Person.cars 的更改。
    2. cascade=CascadeType.ALL 意味着每当你保存一个Person 时,Hibernate 也会对包含在Person.cars 中的所有实体调用保存操作

    结果:您正在对一组未正确设置 Car.person 属性的 Car 实体调用 Session.save()。

    解决方案:要么更改关系的拥有方(请注意,如果您不希望创建额外的数据库表,则在 Person.cars 上还需要 @JoinColumn)或循环通过 Person.cars 并设置Car.person 属性在他们每个人中正确。

    cascade=CascadeType.ALL 建议第一个解决方案更适合您的用例。

    【讨论】:

    • 感谢 crizzis 的回答。我在具有汽车 ArrayList 的人员实体上调用 session.save。那么我应该迭代 json 并将汽车设置为 Person 吗?
    • 你应该遍历person.getCars()并在每个car上调用car.setPerson(person)
    • 所以对于删除我也需要这样做吗?遍历 person.getCars 并删除汽车然后删除人?这是好方法还是我错过了什么?
    • 没有。在这种情况下删除该人就足够了,因为CascadeType.ALL 将级联删除
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    相关资源
    最近更新 更多