简体   繁体   中英

Spring JPA joint table doesn't return all fields

I created two tables -student and subject. Then I created a third table student_subject, which is a joint table to connect students with subjects. It has 5 fileds: row id, student id, subject id and the created_at and updated_at fields (which comes from the AuditModel class):

  package com.rest.web.postgresapi.data.models;

import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Entity
@Table(uniqueConstraints = {
        @UniqueConstraint(columnNames = {"student_id", "subject_id"})
})
public class StudentSubject extends AuditModel {

    @Id
    @GeneratedValue(generator = "enrollment_generator")
    @SequenceGenerator(
            name = "enrollment_generator",
            sequenceName = "enrollment_sequence",
            initialValue = 4420
    )
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "student_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonIgnore
    private Student student_id;  // If I put private Long student_id, it fails

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "subject_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonIgnore
    private Subject subject_id; // If I put private Long subject_id, it fails

    // Constructors
    protected StudentSubject() {}

    public StudentSubject(Student student_id, Subject subject_id) {
        this.student_id = student_id;
        this.subject_id = subject_id;
    }

    // Getters
    public Long getId() {
        return id;
    }

    public Student getStudent_id() {
        return student_id;
    }

    public Subject getSubject_id() {
        return subject_id;
    }

    // Setters
    public void setId(Long id) {
        this.id = id;
    }

    public void setStudent_id(Student student) {
        this.student_id = student;
    }

    public void setSubject_id(Subject subject) {
        this.subject_id = subject;
    }

}

The application perfectly creates the tables in the database and I can get and post in the student and subject tables. No problem with that. The pain comes with the controller for the joint table.

This is the controller for the student_subject joint table table

package com.rest.web.postgresapi.controllers;

import com.rest.web.postgresapi.data.models.StudentSubject;
import com.rest.web.postgresapi.repository.StudentSubjectRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

import java.util.List;

@RestController
public class StudentSubjectController {

    @Autowired
    private StudentSubjectRepository studentSubjectRepository;

    @GetMapping("/enrollments")
    public List<StudentSubject> getAllStudentsSubjects(){
        return studentSubjectRepository.findAll();
    }

    @PostMapping("/enrollments/student/subject")
    public StudentSubject createStudentSubject(@Valid @RequestBody StudentSubject studentSubject) {
        return studentSubjectRepository.save(studentSubject);
    }

}

There are two problems:

1 .- when I do the get from the student_subject table, It only retrieves the id of the row and the created_at and updated_at fields. No student_id nor subject_id.

response from get

2 .- when I do the post (from postman) to insert a row, I got the following error:

Detail: Failing row contains (4671, 2018-11-20 11:04:34.176, 2018-11-20 11:04:34.176, null, null).

I provide both student_id and subject_id, as you can see at this screenshot from postman, but the error clearly states both fields are null:

postman post

It seems that my definition of the table is somehow wrong. What am I missing in my code?

Spring MVC uses Jackson to serialize/deserialize Java objects to/from JSON.

If you annotate an attribute with @JSONIgnore then Jackson will ignore it.

This is the reason why you don't see the student_id field or the subject_id field in your JSON response of the GET method. Because Jackson is ignoring them when converts from object to json.

And this is the reason why your POST fails. Because Jackson is ignoring the received attributes. Jackson is creating an empty entity and JPA is saving the entity without student_id and subject_id .

Solved by replacing

@JsonIgnore

with

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})

as indicated in this answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM