Spring Data JPA - 防止一对一关系的双重表单提交

Posted

技术标签:

【中文标题】Spring Data JPA - 防止一对一关系的双重表单提交【英文标题】:Spring DataJPA - preventing double form submission for One to One relationships 【发布时间】:2022-01-22 07:18:36 【问题描述】:

我正在开发一个简单的 Spring 项目,该项目允许餐厅使用 Thymeleaf html 表单将菜肴添加到数据库中。然后,用户可以根据一系列条件搜索它们。

我还让餐厅可以在数据库中添加/更新他们的营业时间——在 OpeningHoursServiceImp 中使用以下方法

保存 - 允许最初添加小时数

@PostMapping("/saveOpeningHour")
public String saveOpeningHour(@ModelAttribute("openinghour")OpeningHour openinghour) 
        openingHourService.saveOpeningHourWithUserId(openinghour);  
        return "redirect:/dish";
        

更新 - 检索开放时间以允许使用上述保存方法进行编辑和重新保存

        @GetMapping("/showOpeningForUpdate/openingHourID")
        public String showOpeningForUpdate(@PathVariable(value = "openingHourID") long openingHourID, Model model) 
            OpeningHour openingHour = openingHourService.getOpeningHourByOpeningHourID(openingHourID);
            model.addAttribute("openinghour", openingHour);
            return "opening_hours_update"
        

这些方法在允许餐厅添加菜品时效果很好,因为一家餐厅可以添加很多菜品(一对多关系)。

但是营业时间和餐厅之间的关系是一对一的,所以如果餐厅老板添加 2 组营业时间-应用程序崩溃。

有没有办法在提交一组营业时间后禁用添加按钮?还是在save方法中正确处理错误?

我尝试使用

在“添加营业时间表单”中禁用“保存”
onsubmit="myButton.disabled = true; return true;` 

但它不起作用(我假设是因为它是一个 Web 应用程序,当页面刷新时它会变为未禁用?)

我是 Spring 新手,发现它很困难。任何帮助将不胜感激!

请查看我的 html 以查看/编辑/添加营业时间-

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


<head>

<title>Dish Management System</title>
<link rel="stylesheet"
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">

</head>
<body>
<br>
<br>
<br>
    
    <br>
    <div class="col-sm-10 offset-sm-1 text-center">
    <h1>Opening Hours</h1>
    </div>
    <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
      <a class="navbar-brand" href="#">WhatToEat</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarCollapse">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active">
            <a class="nav-link" href="/home">Home <span class="sr-only">(current)</span></a>
          </li>
        </ul>
        
        <form class = "form-inline my-2 my-lg-0" action="#" th:action="@/logout" method="POST">
        <button  class= "btn btn-outline-danger my-2 my-sm btn-sm" type= "submit"> logout </button> 
         </form>     
      </div>
     
    </nav>
    
    
    <table border="1" class="table table-striped table-responsive-md">
        <thead>
            <tr>
                <th>Opening Monday</th>
                <th>Opening Tuesday</th>
                <th>Opening Wednesday</th>
            </tr>


        </thead>
        <tbody>
            <tr th:each="openinghour : $listopeninghours">
                <td th:text="$openinghour.openingHourMon"></td>
                <td th:text="$openinghour.openingHourTue"></td>
                <td th:text="$openinghour.openingHourWed"></td>
                
                <td><a th:href="@/showOpeningForUpdate/id(id=$openinghour.openingHourID)"
                    class="btn btn-primary">Update</a>
            </tr>
                         
        </tbody>
        
    </table>
    <div class="col-sm-10 offset-sm-1 text-center">
     <a th:href="@/openinghour"
        class="btn btn-primary btn-sm mb-3"  > Add Opening Hour </a>
        </div>
</body>

请查看我的 html 表单以添加/保存营业时间-

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Opening Hours</title>
<link rel="stylesheet"
    href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
        <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
      <a class="navbar-brand" href="#">WhatToEat</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarCollapse">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active">
            <a class="nav-link" href="/home">Home <span class="sr-only">(current)</span></a>
          </li>
        </ul>
        
        <form class = "form-inline my-2 my-lg-0" action="#" th:action="@/logout" method="POST">
        <button  class= "btn btn-outline-danger my-2 my-sm btn-sm" type= "submit"> logout </button> 
         </form>     
      </div>
     
    </nav>
    <br>
    <br>

    <form action="#" th:action="@/saveOpeningHour" th:object="$openinghour"  method="POST">
        <div class="col-sm-10 offset-sm-1 text-center">
        <div class="container">
            <br>
            
            <h2>Business Hours</h2>
            
                <hr>
            
            <div class="row">
            <div class="col">
                    Closing Hours 
                    
                        <hr>
                    
                    
                    <input type="text" th:field="*openingHourMon"
                        placeholder="Monday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourTue"
                        placeholder="Tuesday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourWed"
                        placeholder="Wednesday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourThurs"
                        placeholder="Thursday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourFri"
                        placeholder="Friday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourSat"
                        placeholder="Saturday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*openingHourSun"
                        placeholder="Sunday" class="form-control mb-4 col-10">


                </div>

                <div class="col">
                Opening Hours
                    <hr>
                
                    
                     <input type="text" th:field="*closingHourMon"
                        placeholder="Monday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourTue"
                        placeholder="Tuesday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourWed"
                        placeholder="Wednesday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourThurs"
                        placeholder="Thursday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourFri"
                        placeholder="Friday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourSat"
                        placeholder="Saturday" class="form-control mb-4 col-10">

                    <input type="text" th:field="*closingHourSun"
                        placeholder="Sunday" class="form-control mb-4 col-10">


                </div>
            </div>
        </div>



        <button type="submit" name ="myButton" class="btn btn-info col-4" >Save</button>
        <br>
        
        <a th:href="@/open"> Back to Opening Hours</a>
    </div>  
    </form>
    
</body>
</html>

【问题讨论】:

【参考方案1】:

在加载管理营业时间的页面时,您可以检查是否设置了变量openinghour。如果存在营业时间,则禁用按钮添加营业时间

假设下面是你的按钮,代码如下。

<button th:disabled="$openinghour != null">Add Opening Hour</button>

th:disabled 负责禁用按钮。

【讨论】:

感谢您的帮助,但我认为仍有一些我不明白的地方。在哪里/如何检查空值?当我实现按钮上方的按钮时,无论开放时间是否为空,按钮都显示为禁用。再次感谢!

以上是关于Spring Data JPA - 防止一对一关系的双重表单提交的主要内容,如果未能解决你的问题,请参考以下文章

与一对多 Spring Data JPA 求和

外键在一对多关系中始终为空 - Spring Boot Data with JPA

spring data jpa 一对多查询

Spring Data JPA中的mappedBy

spring-data-jpa一对多多对一多对多关联

Spring Data Jpa系列教程--------实体解析和关联关系