如何使用spring+eleaf+jpa强制数据作为表单提交的一部分

zyfwsgd6  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(254)

tldr公司;我希望整个对象在表单提交中是持久的,而不仅仅是添加到thymeleaf模板的对象部分。
基本上,我在一个端点执行数据库查询,并用jpa实体结果中的几个字段填充表单,显示数据库中当前的数据。但是,当我提交表单时,只有通过thymeleaf在页面上显示的字段才会发送到表单数据中。我想要整个对象,而不仅仅是显示的部分,因为我需要id字段来标识提交表单时要更新的记录(当用户点击“保存”按钮时)。Spring一般是怎么做的?
下面是一些代码:

<form id="form" th:action="@{/labor/save}" th:object="${laborSession}" method="post">
    <!-- various input fields and select lists -->
</form>

加载页面时发送到模型中的实体:

"laborSession": {
    "OverTime": 0,
    "TripTypeFactor": 0.5,
    "EmergencyCall": false,
    "LaborDate": "2020-11-12",
    "TripMileageRate": 1.2,
    "TripMileageTotal": 36,
    "LaborTotal": 962.5,
    "LaborRate": 110,
    "JobNumber": 99998,
    "TripLaborRate": 110,
    "LastModified": "2020-11-25 14:56:06.0",
    "LaborID": 1,
    "CustomerNumber": 100279,
    "PersonalVehicle": false,
    "RTMiles": 60,
    "LaborHrs": 8.75,
    "DriveTime_EMT": 0,
    "DriveTime_RT": 0,
    "InvoiceNumber": 0,
    "LaborClass": "SCALES",
    "PayPeriod": 1507,
    "TechName": "TYLER DOEPEL",
    "TripMileage": 30,
    "DriveTime_SHT": 0,
    "RegularTime": 8,
    "LaborPerformed": "THIS IS JUST A TEST LABOR ENTRY\r\nLINE #2\r\nLINE #3",
    "TripLaborHrs": 0.75,
    "EmergencyTime": 0,
    "BaseOfOperation": "NASHVILLE",
    "TripLaborTotal": 82.5,
    "LaborType": "MAINTENANCE",
    "LaborCompleted": false,
    "Sun_HolidayTime": 0,
    "Total": 998.5,
    "TripType": "TRUCK HALF TRIP",
    "DiscountedTime": 0,
    "JobRowGUID": "64AAB2C8-3BFA-449A-B722-0BCD10283EE6",
    "DriveTime_OT": 0,
    "PersonalMiles": 30
}

这是表单提交返回的实体对象,显然缺少值。我只收到表单中显式引用的值。

"laborEntity": {
    "OverTime": 0,
    "LaborClass": "SCALES",
    "TechName": "TYLER DOEPEL",
    "LaborDate": "2020-11-12",
    "DriveTime_SHT": 0,
    "RegularTime": 8,
    "LaborPerformed": "THIS IS JUST A TEST LABOR ENTRY\r\nLINE #2\r\nLINE #3",
    "EmergencyTime": 0,
    "BaseOfOperation": "NASHVILLE",
    "LaborType": "MAINTENANCE",
    "Sun_HolidayTime": 0,
    "TripType": "TRUCK HALF TRIP",
    "DiscountedTime": 0,
    "DriveTime_EMT": 0,
    "DriveTime_RT": 0,
    "DriveTime_OT": 0,
    "PersonalMiles": 30
}

当我提交时 laborSession 对象只包含我显示的字段,如前所述。我如何提交所有的部分 th:object 不在页面/模板的代码中到处乱扔带有数据属性的额外隐藏字段?当提交被处理的时候,有没有一个好的,整洁的方法来取回完整的对象?
顺便说一句,除非我在模板的标记中添加id作为属性,否则我会从entityrepository(jpa)中得到一个很好的异常,它指示在尝试 save() 记录:

org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.m.j.db.entity.LaborEntity
roejwanj

roejwanj1#

我只收到表单中显式引用的值。
(...)
我如何提交所有的部分 th:object 不在页面/模板的代码中到处乱扔带有数据属性的额外隐藏字段?
你不能。我不明白它怎么能工作,否则,因为thymeleaf是一个模板引擎,而不是一个神奇的数据绑定器。
幸运的是,您可以在后端处理这种情况。在对另一个问题的回答中描述了一种优雅的方法。具体如下:
提供表单视图的enpoint接受 LaborID 作为请求参数或路径变量。让我们选择request param方法作为示例:

@GetMapping(value = "/labor", params = "laborID")
public String getLabor() {
   return "labor_form_template";
}

你提供你的 laborSession 使用专用方法创建模型,了解 laborID :

@ModelAttribute("laborSession")
public YourLaborSessionClass loadLaborSession(@RequestParam("laborID") int laborID){ 
    return yourLaborRepository.findByLaborID(laborID); // or whatever source it has...
}

处理表单提交接受的终结点 laborID 与第1点相同:

@PostMapping(value = "/labor", params = "laborID")
public String saveLabor(@ModelAttribute(name = "laborSession") YourLaborSessionClass laborSession) {
   // At this point laborSession object received from @ModelAttribute method is enriched with input data.
   // All fields available in form are updated whereas other fields are as before.
}

在创建端点之后 laborID 意识到,反映出你内在形态的变化 th:action 属性。

<form id="form" th:action="@{/labor(laborID=${laborSession.laborID})}" th:object="${laborSession}" method="post">

相关问题