I am developing Employee Management application using Spring-Hibernate. I have two entities Employee and Department. And Employee entity has a field Department which is mapped to Department entity as #ManyToOne.
#ManyToOne(cascade = {CascadeType.PERSIST})
#JoinColumn(name = "dept")
private Department dept;
And accordingly #OneToMany mapping in Department entity
#OneToMany(mappedBy = "dept")
private List<Employee> employees = new ArrayList<>();
My JSP Spring form is mapped to Employee entity. And it has a form:select element to select department with values as department ids.
<form:form modelAttribute="createEmployee"
action="${pageContext.request.contextPath}/createdemployee"
method="post">
..............
..............
<form:input path="employee.firstName" type="text" width="20px;" />
<form:select>
<form:option value="1001">IT</form:option>
<form:option value="1002">Finance</form:option>
<form:option value="1003">Marketing</form:option>
<form:option value="1004">Sales</form:option>
<form:option value="1005">H.R</form:option>
</form:select>
How can I set Deparment object in Employee entity as per selection made on the form?
Controller
#RequestMapping("/createdemployee")
public String goCreatedEmployee(Model model, Employee employee){
employeeDataServices.addEmployee(employee);
return "created_employee";
}
You can use it like :
<form:select path="employee.department.code">
<form:option value="1001">IT</form:option>
<form:option value="1002">Finance</form:option>
<form:option value="1003">Marketing</form:option>
<form:option value="1004">Sales</form:option>
<form:option value="1005">H.R</form:option>
</form:select>
And from the Controller, get the employee model and get department's name?
Also add the request method in your code - POST/PUT.
#RequestMapping(value = /createdemployee, method = RequestMethod.POST)
public String goCreatedEmployee(Model model, Employee employee){
employeeDataServices.addEmployee(employee);
return "created_employee";
}
Let me know if it works?
Related
Trying to save child entity containing 2 existing parents in the DB ( user and type , the user works fine) , i don't know why it tells me the type is transient while i got it ( populated the dropdown list) from the DB i get :
WARN UnresolvedEntityInsertActions - HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
Unsaved transient entity: ([jpa.project.model.DemTypeDemande#0])
Dependent entities: ([[jpa.project.model.DemDemande#8950]])
Non-nullable association(s): ([jpa.project.model.DemDemande.demTypeDemande])
Controller :
#RequestMapping(value = "/demandes/manage",method = RequestMethod.GET)
public ModelAndView manageUsers(HttpServletRequest request) throws IOException {
ModelAndView model = new ModelAndView();
//----1.ADD USER
model.addObject("demUser", new DemUser());
//----2.ADD TYPES
List<DemTypeDemande> listTypes = service.getTypeDemandes();
model.addObject("listTypes", listTypes);
//----3.ADD DEMANDE
DemDemande demande = new DemDemande();
model.addObject("DemDemande", demande);
model.setViewName("managedemandes");
return model; }
#RequestMapping(value = "/demandes/actionadddemande", method = RequestMethod.POST)
public String actionadduser(HttpServletRequest request ,#ModelAttribute("demTypeDemande") DemTypeDemande typeDemande,#ModelAttribute ("DemDemande") DemDemande demande , BindingResult result) {
demande.setDemUser(service.getUserByUsername(service.getConnectedUsername(request)));
demande.setDemTypeDemande(typeDemande);
service.addDemande(demande);
return "redirect:/demandes/manage";
}
JSP :
<form:form action="actionadddemande" method="POST" commandName="DemDemande">
<table>
<form:hidden path="idDemande" />
<form:hidden path="demUser" />
<tr>
<td>Types :</td>
<td>
<form:select path="demTypeDemande">
<form:options items="${listTypes}" itemValue="idTypeDemande" itemLabel="libTypeDemande"></form:options>
</form:select></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
Type entity relation :
//bi-directional many-to-one association to DemDemande
#OneToMany(mappedBy="demTypeDemande")
private List<DemDemande> demDemandes;
Demande entity relation :
//bi-directional many-to-one association to DemTypeDemande
#ManyToOne(optional = false)
#JoinColumn(name="ID_TYPE_DEMANDE")
private DemTypeDemande demTypeDemande;
I want to insert list of items into a database table submitted from multiple select form.
My submit form is:
<form method="post" action="${pageContext.request.contextPath }/">
<div>
<label>User:</label>
<select name="customer">
<option value="">Select Customer</option>
<c:forEach var="c" items="${ cList }">
<option value="${ c.id }">${ c.name }</option>
</c:forEach>
</select>
</div><br>
<div>
<label>Hobby:</label>
<select name="product" multiple size="8">
<!-- <option value="">Select Items</option> -->
<c:forEach var="p" items="${ pList }">
<option value = "${ p.id }">${ p.productName }</option>
</c:forEach>
</select>
</div>
<br><br>
<input type="submit" value="Send">
</form>
And so far i have done this:
My Transaction POJO:
#Entity
#Table(name = "transcation")
public class Transcation {
#Id
#GeneratedValue
#Column
private Long id;
#JoinColumn
#OneToOne
private Customer customer;
#JoinColumn
#OneToMany
private List<Product> product;
...
My Product POJO:
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue
#Column
private Long id;
#Column
private String productName;
...
But when i run this project i get this type of database table for transcation and product:
Product table in database
Transaction table in database
I need to insert the customers' transaction with the list of items and customer id in the transaction table.
I assume the database tables are generated from the Entity you defined. Hence its okay to have such tables generated. But the thing is you are interpreting a wrong relationship between Tranasaction and Product.
Think - Is it really an OneToMany relation ? I guess No. Cause not only an Transaction contains list of Product but also a Product could be in multiple Tracnsaction. So this should be an unidirectional ManyToMany relation.
If I understand your business this okay then just annotate you Transaction Entity like below (having #JoinTable for the ManyToMany relation.
#Entity
#Table(name = "transcation")
public class Transcation {
#Id
#GeneratedValue
private Long id;
#OneToOne
#JoinColumn(name="customer_id")
private Customer customer;
#ManyToMany
#JoinTable(name = "transaction_product",
joinColumns = #JoinColumn(name = "transaction_id"),
inverseJoinColumns = #JoinColumn(name = "product_id"))
private List<Product> productList;
...
Having #JoinTable actually creates separate mapping table tranasction_product in the database having foreign key reference with transaction and product table primary key.
Saving this Relation from UI
Assuming you have the selected Customer and the selected List of Product from the submission. Now just create a Transaction. Simply assign the values and save your Tranasction object through an opened session
Transaction transaction = new Transaction();
transaction.setCustomer(customer);
transaction.setProductList(productList);
Your Entities seems to be correct.
First please add products into database. Consider you have added products already. id of these are 1,2,3.
Before persisting transaction load products by ids and add into product list.
Then create object of transaction :
Transaction = new Transaction();
transaction.setProducts(products); //list of products loaded already into list
Then set other parameters and finally just save this transaction.
You want to map an collection type (List) in Transaction table. You should try to annotate the list with #ElementCollection annotation like below:
...
#JoinColumn
#OneToMany
#ElementCollection
private List<Product> product;
Of course we take for granted that Product table actually exists.
I want to create a bank account register related to a specific Person in a OneToMany relationship.
I have the clas Pessoa (Person):
#Entity
public class Pessoa {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int idPessoa;
private String nome;
#OneToMany(mappedBy = "pessoa", targetEntity = ContaCorretora.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<ContaCorretora> contaCorretora;
...and the class ContaCorretora (Bank account):
#Entity
public class ContaCorretora {
#Id #GeneratedValue(strategy=GenerationType.IDENTITY)
private int idConta;
private TipoConta tipoConta;
private TipoRisco tipoRisco;
private String login;
private String senha;
private BigDecimal valorAtual;
#ManyToOne
#JoinColumn(name="idPessoa")
private Pessoa pessoa;
I'm using this method in Controller for start the process of registration:
#RequestMapping(value = "pessoacorretora/{id}")
public ModelAndView pessoaCorretora(#PathVariable("id") int id, ContaCorretora contaCorretora ) {
Map<String, Object> model = new HashMap<String, Object>();
Pessoa pessoa = pessoaDao.find(id);
model.put("pessoa", pessoa);
model.put("tipoConta", TipoConta.values());
model.put("tipoRisco", TipoRisco.values());
return new ModelAndView("corretora/contacorretora", "model", model);
}
Sumarizining, I have a specific page for recording bank accounts. So, I created this form:
<form:form action="${s:mvcUrl('CC#gravar').build() }" method="post" commandName="contaCorretora" enctype="multipart/form-data" >
<div class="form-group" >
<label>Conta</label>
<select name="tipoConta">
<c:forEach items="${model.tipoConta}" var="tipoConta">
<option value=${tipoConta}>${tipoConta}</option>
</c:forEach>
</select>
</div>
<div class="form-group" >
<label>Risco</label>
<select name="tipoRisco">
<c:forEach items="${model.tipoRisco}" var="tipoRisco">
<option value=${tipoRisco}>${tipoRisco}</option>
</c:forEach>
</select>
</div>
<div class="form-group">
<label>Login</label>
<form:input path="login" cssClass="form-control" />
</div>
<div class="form-group">
<label>Senha</label>
<form:input path="senha" cssClass="form-control" />
</div>
<div class="form-group">
<label>Valor Atual</label>
<form:input path="valorAtual" cssClass="form-control" />
</div>
<form:hidden path="pessoa" cssClass="form-control" value="${pessoa}"/>
<button type="submit" class="btn btn-primary">Cadastrar</button>
</form:form>
When I use the form in this way, I receive the error "description The request sent by the client was syntactically incorrect." I figured out that the problem is in this line, because when I delete, the form post ok:
<form:hidden path="pessoa" cssClass="form-control" value="${pessoa}"/>
Nevertheless, if I delete this line, the program doesn't save the idPessoa as a foreign key, this field is null. I would like to know how to pass an entire object in my JSP form. The post method is:
#RequestMapping(method=RequestMethod.POST)
public ModelAndView gravar(ContaCorretora contaCorretora) {
contaCorretoraDao.gravar(contaCorretora);
return new ModelAndView("pessoa/listageral");
}
all the DAO's methods are okay.
You only need to send the primary key of pessoa to the form.
Change the form attribute
<form:hidden path="pessoa.idPessoa" cssClass="form-control" value="${model.pessoa.idPessoa}"/>
Before persisting the ContaCorretora, make sure you get the Pessoa object from db.
#RequestMapping(method=RequestMethod.POST)
public ModelAndView gravar(ContaCorretora contaCorretora) {
contaCorretora.setPessoa(pessoaDao.find(contaCorretora.getPessoa().getIdPessoa()));
//I escaped null check and not found exceptions, you should apply some logic to take care of that
contaCorretoraDao.gravar(contaCorretora);
return new ModelAndView("pessoa/listageral");
}
Using Entities as form model is not a good approach. Persistance layer should not be on the MVC layer.
In order to pass Java object from your Controller
#RequestMapping(method=RequestMethod.POST)
public ModelAndView gravar(ContaCorretora contaCorretora) {
ModelAndView mav = new ModelAndView("pessoa/listageral");
// retrieve object from DAO
Object myObj = Dao.find(id);
// Put object into model map
mav.addObject("myObj", myObj);
// return model and view
return mav;
}
In JSP you can refer to object using ExpressionLanguage syntax
${myObj}
I have a form with two dropdowns, One for selecting a group and the other one for selecting a material so the commandName is DTO class which contains two List fields of "Group" and "Material" classes, i have another class "Absence" mapped ManyToOne to class Student and class Material too, i want to list the students of the selected group to mark their absence in the selected material,also class Absence has a String field which has "present" or "absent" as value and a Date field,how to do that?
Any help on this would be appreciated, Thank you
here is DTO class
public class ListeleveDTO {
private java.util.List<Groupe> groupe;
private java.util.List<Matiere> matiere;
public ListeleveDTO() {
}
public ListeleveDTO(java.util.List<Groupe> groupe, java.util.List<Matiere> matiere) {
this.groupe= groupe;
this.matiere = matiere;
}
Class Absence
#Entity
#Table(name = "Absence")
public class Absence implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
#Column(name="Date", nullable=false)
private Date date;
#Column(name="Etat", unique=true,nullable=false)
private EtatAbs etat;//enum class which contains "Present" or "Absent"
#ManyToOne
#JoinColumn(name="Eleve_id", referencedColumnName="id")
private Eleve eleve;
#ManyToOne
#JoinColumn(name="Matiere_id", referencedColumnName="id")
private Matiere matiere;
//getters and setters
jsp form
<form:form method="post" commandName="listeleveDTO" role="form" >
<label>Sélectionnez un groupe</label>
<select name="Groupe" class="form-control">
<option value="NONE" label="--- Select ---" />
<c:forEach items="${listeleveDTO.groupe}" var="m">
<option value="${m.libelle}">${m.libelle} </option>
</c:forEach>
</select>
<div class="form-group" style="margin-top:50px">
<label> Sélectionnez une matiere</label>
<select name="Matiere" class="form-control">
<option value="NONE" label="--- Select ---" />
<c:forEach items="${listeleveDTO.matiere}" var="mg">
<option value="${mg.libelle}">${mg.libelle} </option>
</c:forEach>
</select>
</div>
<button type="submit" class="btn btn-info" style="margin-top:30px" >Valider</button>
</form:form>
Controller
#Controller
#RequestMapping ("abs")
#SessionAttributes({"groupe","matiere"})
public class AbsController {
#Autowired GroupeService groupeservice;
#Autowired AbsenceService absenceService;
#Autowired MatiereService matiereservice;
#RequestMapping(method = RequestMethod.GET)
public ModelAndView showForm() {
ModelAndView mv = new ModelAndView("abs");
ListeleveDTO listeleveDTO = new ListeleveDTO(groupeservice.findAllGroupes(), matiereservice.findAlmatieres());
mv.addObject("listeleveDTO",listeleveDTO );
return mv;
}
#RequestMapping( method = RequestMethod.POST)
public String submitForm( #ModelAttribute("listeleveDTO") ListeleveDTO listeleveDTO,BindingResult result,
ModelMap map
) {
return "listeleve" ;
}
#RequestMapping(value="/listeleve")
public String geteleves (Model model){
model.addAttribute("absence", new Absence());
model.addAttribute("listAbsence", absenceService.findAllAbsence());
model.addAttribute("etats",EtatAbs.values());
return "listeleve";
}
ListofStudent jsp
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th width="200px">Eleve</th>
<th width="150px">Absence</th>
<th width="150px">Edit</th>
</tr>
</thead>
<tbody>
<sql:query dataSource="${ds}" var="result">
SELECT X.FIRST_NAME,X.LAST_NAME,A.Etat,X.id from Absence A, MATIERE M,
(SELECT E.id,E.FIRST_NAME,E.LAST_NAME from GROUPE G, ELEVE E where G.LIBELLE= "<%=liste %>" and E.groupe_id = G.id) as X
where X.id = A.ELEVE_ID and A.MATIERE_ID = M.id and M.LIBELLE = "<%=liste1%>" ;
</sql:query>
//i joined table groupe and eleve(student) to select first and last name of students then i joined table absence to table matiere (material) and table X the result of joining student and group to select field "etat",this field contains "absent" or "present" student
<c:forEach var="row" items="${result.rows}">
<tr class="gradeU">
<td><c:out value="${row.FIRST_NAME}"/> <c:out value="${row.LAST_NAME}"/></td>
<td>
<c:out value="${row.Etat}"/>
</td>
<td></td>
</tr>
</c:forEach>
</tbody>
</table>
Facing issue in spring form binding.Say i have two models Category and Product.
#Entity
#Table(name="PRODUCT")
public class Product
{
#Id
#GeneratedValue
private long productID;
#ManyToOne
#JoinColumn(name="categoryID")
private Category category;
//Getters and setters
}
#Entity
#Table(name = "CATEGORY")
public class Category {
#Id
#GeneratedValue
private long categoryID;
private String categoryName;
}
In controller to render add product page
#RequestMapping(value = "/productpage", method=RequestMethod.GET)
private ModelAndView getAddProductPage(){
ModelAndView modelAndView = new ModelAndView("add-product","product",new Product());
Map<Category,String> categoriesMap = new HashMap<Category, String>();
List<Category> categories = categoryService.getAllCategories();
if(categories != null && !categories.isEmpty())
{
for(Category category : categories)
{
categoriesMap.put(category, category.getCategoryName());
}
}
modelAndView.addObject("categoryList",categories);
return modelAndView;
}
I am able to populate the drop down values of categories in JSP page using below code :
<form:select path="category" >
<form:options items="${categoryList}"/>
</form:select>
While submitting the form i'm facing error 400 The request sent by the client was syntactically incorrect.Failed to convert property value of type 'java.lang.String' to required type 'com.example.model.Category' for property 'category'.
If i view page source for each option category is assigned correctly. But not understanding why spring throwing that err.. Need help. Thanks in advance!
This worked for me!
<form:select path="category.categoryID" >
<form:options items="${categoryList}" itemValue="categoryID" />
</form:select>
You should make the following change in your Controller's action:
for(Category category : categories)
{
categoriesMap.put(category.geCategorytId(), category.getCategoryName());
}
and in your view change:
<form:select path="category.categoryID" >
The select drop-down will have the category name as the display text and category ID as the value.
<form:select path="category">
<c:forEach items="${categoryList}" var="category">
<form:option value="${category}">${category.categoryName}</form:option>
</c:forEach>
</form:select>
or
<form:select class="form-control" path="site">
<form:option value="-1">Select...</form:option>
<form:options items="${categoryList}" itemValue="categoryID" itemLabel="categoryName"/>
</form:select>