Даже если поля формы оставлены пустыми, отправляются пустые строки и создается новая сущность в Spring - PullRequest
1 голос
/ 24 сентября 2019

У меня есть две сущности: Student и StudentDetails. A Student может иметь только один или нет StudentDetails.Когда я отправляю форму для сохранения Student, StudentDetails также сохраняется.Это нормально, если я отправлю данные для StudentDetails объекта.Но это происходит, даже если я не отправляю никаких данных для StudentDetails объекта.Изображения после сохранения трех Student с:

student таблица :

enter image description here

student_details таблица :

enter image description here

Я хочу, чтобы строка 1,3 не сохранялась в таблице student_details.И в student таблица student_details_id будет равна null для этих двух.

Как я могу реализовать отношение @OneToOne, где родительский / владелец может иметь необязательный параметр (Один, если существует, Ноль, если не существует) дочерняя сущность?

Вот мои коды:

Student.java

@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "student_name")
    private String studentName;

    @Column(name = "student_roll")
    private String studentRoll;

    @Column(name = "student_class")
    private String studentClass;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "student_details_id")
    private StudentDetails studentDetails;

    // Constructors, Getters and Setters
}

StudentDetails.java

@Entity
@Table(name = "student_details")
public class StudentDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "student_contact")
    private String studentContact;

    @Column(name = "student_email")
    private String studentEmail;

    @Column(name = "student_address")
    private String studentAddress;

    @OneToOne(mappedBy = "studentDetails", cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH, CascadeType.REFRESH })
    @JsonIgnore
    private Student student;

    // Constructors, Getters and Setters
}

StudentController.java

@Controller
@RequestMapping("/students")
public class StudentController {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/add")
    public String add(Model theModel) {
        Student theStudent = new Student();
        theModel.addAttribute("theStudent", theStudent);
        return "student/student_add_form";
    }

    @PostMapping("/create")
    public String create(@ModelAttribute("theStudent") Student theStudent) {
        theStudent.setId((long) 0);
        studentRepository.save(theStudent);
        return "redirect:/students/index";
    }
}

student_add_form.html

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css">
<title>Student List</title>
</head>

<body>
    <div class="container">
        <div class="row">
            <div class="col-9">
                <h1 th:text="'Add New Student'"></h1>
            </div>
            <div class="col-3">
                <a th:href="@{/students/index}" class="btn btn-success">View Student List</a>
            </div>
        </div>
        <div class="row">
            <form action="#" th:action="@{/students/create}" th:object="${theStudent}" th:method="POST" class="col-12">
                <div class="row">
                    <div class="form-group col-3">
                        <label for="studentName">Name:</label> <input type="text" class="form-control"
                            id="studentName" name="studentName" placeholder="Enter Student's Name" th:field="*{studentName}">
                    </div>
                    <div class="form-group col-3">
                        <label for="studentClass">Class:</label> <input type="text" class="form-control"
                            id="studentClass" name="studentClass" placeholder="Enter Student's Class" th:field="*{studentClass}">
                    </div>
                    <div class="form-group col-3">
                        <label for="studentRoll">Roll:</label> <input type="text" class="form-control"
                            id="studentRoll" name="studentRoll" placeholder="Enter Student's Roll" th:field="*{studentRoll}">
                    </div>
                    <div class="form-group col-3">
                        <label for="studentContact">Contact:</label> <input type="text" class="form-control"
                            id="studentContact" name="studentContact" placeholder="Enter Student's Contact"
                            th:field="*{studentDetails.studentContact}">
                    </div>
                </div>
                <div class="row">
                    <div class="form-group col-3">
                        <label for="studentEmail">Email:</label> <input type="text" class="form-control"
                            id="studentEmail" name="studentEmail" placeholder="Enter Student's Email"
                            th:field="*{studentDetails.studentEmail}">
                    </div>
                    <div class="form-group col-6">
                        <label for="studentAddress">Address:</label> <input type="text" class="form-control"
                            id="studentAddress" name="studentAddress" placeholder="Enter Student's Address"
                            th:field="*{studentDetails.studentAddress}">
                    </div>
                                        <div class="form-group col-3">
                        <label></label> <input type="submit" class="form-control btn btn-success" id="saveStudent"
                            name="saveStudent" value="Save Student">
                    </div>
                </div>
            </form>
        </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.js"></script>
    <script>

    </script>
</body>
</html>

1 Ответ

2 голосов
/ 25 сентября 2019

Вы заявляете, что не отправляете какие-либо данные для StudentDetails, однако в вашей форме явно есть поля для этих данных, например:

<div class="form-group col-3">
    <label for="studentEmail">Email:</label> <input type="text" class="form-control"
        id="studentEmail" name="studentEmail" placeholder="Enter Student's Email"
        th:field="*{studentDetails.studentEmail}">
</div>

Даже если поля формы оставлены пустыми, для них будут отправлены пустые строкиЗначения и Spring, таким образом, свяжут новый экземпляр StudentDetails с атрибутом модели Student и соответствующим образом установят связанные поля, т. е. пустые строки.

Чтобы запретить Spring указать обрезать пустые строки до нуля: если естьЕсли во время привязки в запросе отсутствуют ненулевые свойства, относящиеся к StudentDetails, то экземпляр StudentDetails для атрибута модели Student не будет установлен Spring.

Вы можетесделать это глобально или на основе контроллера.См., Например:

Может ли Spring mvc обрезать все строки, полученные из форм?

Я не уверен, что Spring всегда вел себя так, то есть автоматическое создание непростыходнако я тестировал вложенные свойства в Boot 2.1.8 (MVC 5.1.9), и это то, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...