How to populate model with primary key when persisting through a controller - spring

I'm quite new to spring and Thymeleaf integration so bear with me:
I'm having trouble getting the data from my Thymeleaf template using a JPA model. I've tried using both sequential and identity generation strategies but It doesn't even let me load the page
I've tried creating a completely new variable as seen before but that's clearly not the problem. I know the problem might come from the Thymeleaf references from the html but I'm quite confused; is there a way to auto generate an ID? It doesn't even let me add a value in the form as an ID
class Admin(#Id #GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long, var firstName: String, var lastName: String, var login: String, var password: String) {
#PostMapping("/addstuff")
fun addAdmin(#ModelAttribute(name = "admin") admin: Admin, result: BindingResult, model: Model): String {
val newAdmin: Admin = Admin(admin.id, admin.firstName, admin.lastName, admin.firstName[0].plus(admin.lastName), encoder.encode("password"))
adminRepository.save(newAdmin)
return "adminadd"
}
form action="#" data-th-action="#{/addstuff}" th:object="${admin}" method="post">
<div class="row justify-content-center" id="mainBody">
<div class="col-8">
<div id="student0">
<div class="row">
<div class="col">
Administrator Information
</div>
</div>
<div class="row">
<div class="col">
<input th:field="*{firstName}" type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input th:field="*{lastName}" type="text" class="form-control" placeholder="Last name">
</div>
<div class="col">
<input type="number" class="form-control" placeholder="Administrator ID number">
</div>
</div>
<div class="row">
<div class="col">
<label>Role
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="adminRadio"
value="option1" checked>
<label class="form-check-label" for="adminRadio">
Administrator
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="profRadio"
value="option2">
<label class="form-check-label" for="profRadio">
Professor
</label>
</div>
</label>
</div>
</div>
<hr>
</div>
<input id="submitAdmin" type="submit" value="Add Administrator">
<!-- <button id="submitAdmin">Add Administrator</button>-->
</div>
</div>
</form>
The result I expect should be the persisting of the data into my local db but the error i get is this:
'admin' on field 'id': rejected value [null]; codes [typeMismatch.admin.id,typeMismatch.id,typeMismatch.long,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [admin.id,id]; arguments []; default message [id]]; default message [Failed to convert value of type 'null' to required type 'long'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [#javax.persistence.Id #javax.persistence.GeneratedValue long] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type]]
I know it has to do with the id value but I'm stuck as to how I generate a value for it. I'm using the h2 embedded database if anyone is interested. Thanks in advance

Though your question is about data not getting transferred between template and JPA but exception clearly say the problem with JPA only. You are never required to pass ID while saving a new entity object in database. I suspect your id column in database table is not defined with auto generation strategy. Can you try modifying it and rerunning your code.

I've figured it out! I used the regular old html name tag and thymeleaf parsed and read it.
<div class="col">
<input type="text" name="lastName" class="form-control" placeholder="Last name">
</div>

Related

Request method 'GET' is not supported

have two controllers, that should give Form (html +Thymeleaf) to Update entity and post new data, after redirect to List Entities;
My Controllers
#GetMapping ("/fromUpdate")
public String updateInstructor (Model model, Long instructorId) {
Instructor instructor = instructorService.loadInstructorById(instructorId);
model.addAttribute("instructor", instructor);
return "views/updateInstructor";
}
#PostMapping ("/update")
public String update (Instructor instructor) {
instructorService.updateInstructor(instructor);
return "redirect:/instructors/index";
}
Html form + Thymeleaf
<div class="col-md-6 offset-3 mt-3">
<form class="form-control" method="post"
th:action="#{/instructors/update}" th:object="${instructor}">
<div class="mb-3 mt-3">
<label class="form-label"> Instructor Id :</label>
<input type="number" name="instructorId" class="form-control"
th:value="${instructor.getInstructorId()}">
</div>
<div class="mb-3 mt-3">
<label for="firstName" class="form-label"> First Name :</label>
<input id="firstName" type="text" name="firstName" class="form-control"
th:value="${instructor.getInstructorFirstName()}">
</div>
<div class="mb-3 mt-3">
<label for ="lastName" class="form-label"> Last Name :</label>
<input id="lastName" type="text" name="lastName" class="form-control"
th:value="${instructor.getInstructorLastName()}">
</div>
<div class="mb-3 mt-3">
<label for="instructorSummary" class="form-label"> Summary :</label>
<input id="instructorSummary" type="text" name="instructorSummary" class="form-control"
th:value="${instructor.getInstructorSummary()}">
</div>
<div class="mb-3 mt-3" th:each ="course: ${instructor.getCourses()}">
<input name="courses" class="form-control"
th:value="${instructor.courses[courseStat.index].getCourseId()}">
</div>
<div class ="mb-3 mt-3">
<input name ="user" class="form-control" th:field="${instructor.user}">
</div>
<button type ="submit" class ="btn btn-primary"> Update </button>
</form>
</div>
When i load update form i give next exception
80 --- [nio-8071-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' is not supported]
Must say, when i set in first controller #GetMapping (value =/update) analogical Url with Post my form load with all data.
If you know where my problem, please say me, tnx!!!

Error in passing the foreign key in the form for editing

I have two tables, one named Client and the other named Projects linked together via a foreign key (this is client_id, which is present in Projects).
Each project has an edit button; when I click to edit a project I have a form with all fields secured to it.
To edit a project I have to pass the client id (client_id) associated with that project.
To do this, I did the following:
ROUTE
Route::get('/project/edit/{project}', [ProjectController::class, 'edit'])->name('project.edit');
CONTROLLER
public function edit(Project $project)
{
$client_id = Project::select('client_id')->where('id',$project->id)->get();
//dd($client_id);
return view('project.edit', compact('project','client_id'));
}
VIEW
<div class="row mt-3">
<div class="col-12 col-md-6 namelabel">
<form action="{{route('project.store')}}" method="post" enctype="multipart/form-data">
#csrf
<div class="mb-3">
<input type="hidden" class="form-control" name="client_id" value="{{$client_id}}" >
</div>
<div class="mb-3">
<label for="name" class="form-label">Project name</label>
<input type="text" class="form-control" name="name" value="{{$project->name}}">
</div>
<div class="mb-3">
<div class="mb-3">
<label for="logo" class="form-label">Insert image</label>
<input type="file" name="logo">
</div>
<div class="mb-3">
<label for="project_start_date" class="form-label">Data init</label>
<input type="date" class="form-control" name="project_start_date" value="{{$project->project_start_date}}">
</div>
<label for="description" class="form-label">Description</label>
<textarea name="description" cols="30" rows="10" class="form-control">{{$project->description}}</textarea>
</div>
<button type="submit" class="btn btn-primary mb-5">Modifica progetto</button>
</form>
</div>
</div>
I get the following error:
Incorrect integer value: '[{"client_id":14}]' for column 'client_id' at row 1
How can I solve this problem?
Thanks to those who will help me
This statement
Project::select('client_id')->where('id',$project->id)->get()
does not return the client_id. It returns an Eloquent Collection of Projects with only the client_id Attribute.
You can chain the pluck function to extract only value and then you can call first to get the value from the collection.
Project::select('client_id')
->where('id',$project->id)
->get()
->pluck('client_id')
->first()
After checking your code in the full detail you don't need to do the select part at all.
You have already the Project Model so you can access all of it's fields directly.
$project->client_id
In your view you are doing this already with the name of the project:
{{$project->name}}
You can do the same with the client_id as well:
{{$project->client_id}}

Thymeleaf table

I have problem table when i want set value with for each i.index get error java.lang.NumberFormatException: For input string: "${i.index}". In Array i need numer so ${i.index} is int. I dont know what i do wrong.
<div class="form-group row" th:each="attribute, i: ${attributeList}">
<label class="col-sm-3 col-form-label" th:text="${attribute.name}"></label>
<div class="col-sm-9">
<input type="text" th:field="*{technicalAttributes[${i.index}].name}" class="form-
control" placeholder="Nazwa">
</div>
</div>
You can't nest expressions (*{...${...}...}) like you're doing without using preprocessing. Your code should look like this:
<div class="form-group row" th:each="attribute, i: ${attributeList}">
<label class="col-sm-3 col-form-label" th:text="${attribute.name}"></label>
<div class="col-sm-9">
<input type="text" th:field="*{technicalAttributes[__${i.index}__].name}" class="form-control" placeholder="Nazwa">
</div>
</div>
(If you weren't using the th:field attribute, the expression *{technicalAttributes[i.index].name} would also be appropriate. But since you are using a th:field you have to use preprocessing.)

Can't load page in Spring Boot using th:object

It contains a line error: "An error happened during template parsing (template: "class path resource [templates//register.html]")".
I can't open register html page to add new object into db. why?
<form th:action="#{/register-user}" th:object="user" method="post">
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" placeholder="Enter email" name="email">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" placeholder="Enter password" name="pswd">
</div>
<div class="form-group form-check">
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
My controller
#RequestMapping(path="/register-user", method = RequestMethod.POST)
public String registerNewUser(#Valid #ModelAttribute("user") User user){
userService.register(user);
return "redirect:/login";
}
Your "user" is a model attribute, hence, to access it (and use it as the th:object) you gotta use the ${...} syntax. The result would look like this:
<form th:action="#{/register-user}" th:object="${user}" method="post">

How to collect form data and convert them json format and send back to server in spring mvc

I have form and I want to grab the data inserted by users and then convert them json format.
So first here is my form—
<form id="patient_form" action="#" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="firstName"> First Name<em>*</em></label>
<div class="controls">
<input type="text" id="firstName" class="required" maxlength="100"
placeholder="First Name" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="middleNameInitial">
Middle Name Initial</label>
<div class="controls">
<input type="text" id="middleNameInitial"
placeholder="Middle Name Initial" class="input-small"
maxlength="1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="lastName"> Last Name <em>*</em></label>
<div class="controls">
<input type="text" id="lastName" placeholder="Last Name"
class="required" maxlength="100" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="dateOfBirth"> Date Of
Birth</label>
<div class="controls">
<input type="text" id="dateOfBirth" class="required" />
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="button" class="btn btn-primary"
onclick="savePatientInfo()">Save Changes</button>
<button type="button" class="btn"
onclick="cancelPatientInfoForm()">Cancel</button>
</div>
</div>
</form>
And then I want to send back them to server. And for server side code, I’m using spring mvc and client side I’m using JQuery.
Now how can I do it? I need two things basically,
Ajax call (JavaScript function to which will basically do 3 things, one- grab the form data and convert them into json and then ajax call)
Sever side method to consume ajax call (Controller method as I’m
suing spring mvc.)
Any help is much appreciated.
First of all you need to perform ajax call from the JSP as below:
$.post("${pageContext.servletContext.contextPath}/ajaxTestData",
{
firstName:$("#firstName").val(),
middleNameInitial:$("#middleNameInitial").val(),
<other form data>
},
function(j)
{
<j is the string you will return from the controller function.>
});
Now in the controller you need to map the ajax request as below:
#RequestMapping(value="/ajaxTestData", method=RequestMethod.POST)
#ResponseBody
public String calculateTestData(#RequestParam("firstName") String firstName, #RequestParam("middleNameInitial") String middleNameInitial, HttpServletRequest request, HttpServletResponse response){
<perform the task here and return the String result.>
return "xyz";
}
I have not used the JSON input and result in this way but I think if you return the Pojo then it might converts the same in the json format automatically. Just check that.
Hope this helps you. Cheers.

Resources