I've been researching for days and none of them worked for me. Most of what I got from the Internet was jsp, but I'm using Thymeleaf. What I'm trying to write is a generic type of CRUD which takes in any class and its variables to become the view page's field labels and inputs.
However, every time I try to submit the form which is filled out, it saves on the database but only the ID is not null, all else is of null value.
Here's my method which has the annotation of @ModelAttribute:
@ModelAttribute
public void instantiateEntity(Model model,
@RequestParam("entityName") String entityName)
throws Exception {
String className = SimpleEntity.NAMEPREF + entityName;
SimpleEntity entity =
(SimpleEntity) Class.forName(className).getDeclaredConstructor().newInstance();
Field[] fields = Class.forName(className).getDeclaredFields();
List<FieldUI> fieldUISpecs = new ArrayList<>();
for (Field f : fields) {
System.out.println(f.getName());
FieldUI fieldUI = new FieldUI(f);
UI ui = f.getAnnotation(UI.class);
if (ui != null){
fieldUI.setColHeading(ui.colHeading());
fieldUI.setFldPrompt(ui.fldPrompt());
fieldUI.setCss(ui.css());
fieldUI.setInputHidden(ui.inputHidden());
fieldUI.setColHidden(ui.colHidden());
fieldUI.setType(ui.type());
if(!ui.option().equals("")){
fieldUI.setOption(entityDBA.listEntities(ui.option()));
System.out.println(fieldUI.getOption());
}
System.out.println("\n --- CSS: "+fieldUI.getCss());
} else {
fieldUI.setColHeading(f.getName());
fieldUI.setFldPrompt(f.getName());
fieldUI.setColHidden(false);
fieldUI.setInputHidden(false);
}
fieldUISpecs.add(fieldUI);
}
List<SimpleEntity> entities = entityDBA.listEntities(entityName);
model.addAttribute("fieldUISpecs", fieldUISpecs);
model.addAttribute("entity", entity);
model.addAttribute("entities", entities);
model.addAttribute("currentEntity", entityName);
model.addAttribute("displayAddButton", true);
model.addAttribute("displayList", true);
}
Here's my controller for the saving:
@PostMapping("/add")
public String addEntity(@Valid @ModelAttribute("entity") SimpleEntity entity, BindingResult result, Model model, @RequestParam("entityName") String entityName){
List<SimpleEntity> entities = db.listEntities(entityName);
model.addAttribute("displayList", true);
System.out.println("Entity values: "+entityName);
if (result.hasErrors()) {
model.addAttribute("displayForm", true);
model.addAttribute("isNew", true);
return "th_home";
}
db.saveEntity(entity);
return "redirect:/list-edit-entities?entityName="+entityName;}
//Here's my transactional or service layer:
public long saveEntity(SimpleEntity entity) {
long id = 0;
Session ses = sf.getCurrentSession();
if (entity.getId() == 0) ses.persist(entity);
else ses.merge(entity);
return entity.getId();
}
here's my view:
<form th:if="${isNew}" method="POST" th:action="@{'/add?entityName='+${currentEntity}}" th:object="${entity}">
<th:block th:each="field: ${fieldUISpecs}">
<div class="input-group" th:unless="${field.inputHidden}">
<label th:unless="${field.name} == 'id'" th:text="${field.name}"></label>
<input type="hidden" th:if="${field.name} == 'id'" class="c-form" th:field="*{__${field.name}__}" readonly>
<input th:type="${field.type}" th:unless="${field.name} == 'id'" class="c-form" th:field="*{__${field.name}__}">
</th:block>
</div>
</th:block>
<div class="input-group input-button">
<input class="save-button" type="submit" value="Save">
</div>
</form>