I am using two tables:
with a many (Repairs) to one (Terminal) relationship. I am trying to populate a Thymeleaf form to create a new repair. One of the fields is a dropdown to select the Terminal but I am getting a java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type error. This is my code:
Entity:
public class Repair {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long repairId;
@ManyToOne(targetEntity = Terminal.class)
@JoinColumn(nullable = false)
private Terminal terminal;
@Column(name = "date_received", nullable = false)
private Date dateReceived;
@Column(name = "date_ready")
private Date dateReady;
@Column(name = "fault")
private String fault;
@Column(name = "solution")
private String solution;
//constructors, getters & setters
public class Terminal {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private long terminalId;
@Column(nullable = false)
private String ptid;
@ManyToOne(targetEntity = TerminalModel.class)
@JoinColumn(nullable = false)
private TerminalModel terminalModel;
//constructors, getters & setters
Controller:
@GetMapping("/repair/repairs/new")
public String createRepairForm(Model model){
List<Terminal> terminals = terminalService.getAllTerminals();
Repair repair = new Repair();
model.addAttribute("terminals", terminals);
model.addAttribute("repair", repair);
return "repair/create-repair";
}
View:
<form th:action="@{/repairs}" th:object="${repair}" method="POST">
<div class="form-group">
<label>Date Received</label>
<input type="text" name="dateReceived" th:field = "*{dateReceived}" class="form-control" placeholder="Enter Date Received"/>
</div>
<div class="form-group">
<label>Date Ready</label>
<input type="text" name="dateReady" th:field = "*{dateReady}" class="form-control" placeholder="Enter Date Ready"/>
</div>
<div class="form-group">
<label>Fault</label>
<input type="text" name="fault" th:field = "*{fault}" class="form-control" placeholder="Enter Fault"/>
</div>
<div class="form-group">
<label>Solution</label>
<input type="text" name="solution" th:field = "*{solution}" class="form-control" placeholder="Enter Solution"/>
</div>
<div class="form-group">
<label for="terminal">Terminal:</label>
<select id="terminal" name="terminal.terminalId" th:field="*{terminal.terminalId}">
<option value="">-- Select Terminal --</option>
<option th:each="terminal : ${terminals}" th:value="${terminal.terminalId}" th:text="${terminal.ptid}">
</option>
</select>
</div>
<div class="footer-body">
<button type="submit" class="btn btn-primary"> Submit </button>
</div>
</form>
This is part of the trace:
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@jakarta.persistence.Id @jakarta.persistence.GeneratedValue @jakarta.persistence.Column long] for value 'null'
at org.springframework.core.convert.support.GenericConversionService.assertNotPrimitiveTargetType(GenericConversionService.java:335) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.convert.support.GenericConversionService.handleResult(GenericConversionService.java:328) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:193) ~[spring-core-6.0.7.jar:6.0.7]
at org.springframework.core.convert.support.ConvertingPropertyEditorAdapter.setAsText(ConvertingPropertyEditorAdapter.java:60) ~[spring-core-6.0.7.jar:6.0.7]
at org.thymeleaf.spring6.util.SpringSelectedValueComparator.exhaustiveCompare(SpringSelectedValueComparator.java:173) ~[thymeleaf-spring6-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.thymeleaf.spring6.util.SpringSelectedValueComparator.isSelected(SpringSelectedValueComparator.java:90) ~[thymeleaf-spring6-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.thymeleaf.spring6.processor.SpringOptionFieldTagProcessor.doProcess(SpringOptionFieldTagProcessor.java:68) ~[thymeleaf-spring6-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.thymeleaf.spring6.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:187) ~[thymeleaf-spring6-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74) ~[thymeleaf-3.1.1.RELEASE.jar:3.1.1.RELEASE]
... 52 common frames omitted
Caused by: java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
... 61 common frames omitted
2023-08-25T08:48:04.115+02:00 ERROR 28912 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring6.processor.SpringOptionFieldTagProcessor' (template: "repair/create-repair" - line 60, col 17)] with root cause
java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type
How do I fix this?
The error indicates that a primitive type (such as int
, long
, ...) cannot have null
assigned to it. The Java language does not allow this.
If you want to allow null
values, you need to use a wrapper (e.g. Integer
, Long
, ...).
I see you have private long terminalId;
. Try changing this to private Long terminalId;
PS: A better alternative is to use a dedicated form data object so you only need to change it to Long
in the form data object and keep your entity like you want. See https://www.wimdeblauwe.com/blog/2021/05/23/form-handling-with-thymeleaf/ for more info.