Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why hibernate not set foreign key in the owner side of OneToMany

I have 2 Entities, Hospital and Department, Department reference its hospital by hospital_id in it.

@Entity
public class Hospital {
    ...
    private Set<Department> departments;

    @OneToMany(mappedBy = "hospital", cascade = CascadeType.ALL)
    public Set<Department> getDepartments() {
        return departments;
    }
}

@Entity
public class Department {
    ...
    private Hospital hospital;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "hospital_id")
    public Hospital getHospital() {
        return hospital;
    }
}

I use Rest API to create instance of Entities:

@RequestMapping("/create")
@ResponseBody Hospital create(@RequestBody Hospital hospital){
    hospital = hospitalService.save(hospital);

    return hospital;
}

I post json payload to create a Hospital:

{"name":"t-hospital", "departments":[{"name": "department1"}]}

Since I use SpringBoot, Jackson will auto parse the json payload into Java Object, here its Hospital and Departments in it.

While after I save the hospital, I found the foreign key: 'hospital_id' in department is not set.

Why is this and if possible, how can I make the foreign key set when I save the hospital object?

like image 276
DiveInto Avatar asked Aug 01 '16 16:08

DiveInto


People also ask

How do you make a foreign key a primary key in Hibernate?

You can use JPA's @MapsId annotation to tell Hibernate that it shall use the foreign key of an associated entity as the primary key. Let's take a look at a simple example. Each Book has a Manuscript, and each Manuscript belongs to 1 Book. The foreign key of the Book is also the primary key of the Manuscript.

What is@ OneToMany in Hibernate?

One To Many Mapping in Hibernate. In simple terms, one to many mapping means that one row in a table can be mapped to multiple rows in another table. For example, think of a Cart system where we have another table for Items. A cart can have multiple items, so here we have one to many mapping.

What is difference between mappedBy and @JoinColumn?

The @JoinColumn annotation helps us specify the column we'll use for joining an entity association or element collection. On the other hand, the mappedBy attribute is used to define the referencing side (non-owning side) of the relationship.

What is@ OneToMany annotation?

Please note that the @OneToMany annotation is used to define the property in Item class that will be used to map the mappedBy variable. That is why we have a property named “cart” in the Item class: @Entity @Table(name="ITEMS") public class Item { //... @


1 Answers

You should always create an association in owner side before persisting an entity because owner side is responsible for creating relationships.

Modify your code as below (Contains Java 8 Code):

@RequestMapping("/create")
@ResponseBody Hospital create(@RequestBody Hospital hospital){

    hospital.getDepartments().forEach(department->department.setHospital(hospital));
    hospital = hospitalService.save(hospital);

    return hospital;
}

You may face a new problem when converting entity to json because Jackson serializes related entities recursively and you'll get StackOverflow Error. To resolve this issue add @JsonManagedReference along with @OneToMany annotation and @JsonBackReference along with @ManyToOne annotation.

Note:@JsonManagedReference and @JsonBackReference available in new version of Jackson

like image 102
AsSiDe Avatar answered Oct 04 '22 20:10

AsSiDe