Spring MVC NumberFormatException - spring

I have to entities which are in #OneToMany realtion.
I have an error when I'm trying to get unitPrice from my entity. Could anybody help me to resolve this problem?
My entities:
#Entity
#Table(name="Product")
public class Product {
#Id
#GeneratedValue
private int idProduct;
private String status;
private String name;
#OneToMany(mappedBy = "product")
private List <Repository> repository;
#Entity
#Table(name="Repository")
public class Repository {
#Id
private int idRepository;
private int quantity;
private double unitPrice;
#ManyToOne
private Product product;
view:
<c:forEach items="${products.repository}" var="product">
<p>${product.unitPrice}</p>
</c:forEach>
ERROR:
java.lang.NumberFormatException: For input string: "repository"

You have to use the code below to display the unitPrice in repository.
In the code below, products represents a List of Product objects where each Product object has a List of Repository objects.
<c:forEach items="${products}" var="product">
<c:forEach items="${product.repository}" var="repo">
<p>${repo.unitPrice}</p>
</c:forEach>
</c:forEach>

Related

Spring MVC Error: Failed to convert property value of type java.lang.String to required type

I can't let this exception go:
Failed to convert property value of type java.lang.String to required type com.company.springdemo.entity.Product for property productId; nested exception is java.lang.IllegalStateException: Cannot convert value of type java.lang.String to required type com.company.springdemo.entity.Product for property productId: no matching editors or conversion strategy found
Order Model
#Entity
#Table(name = "orders") // naming the table only order, will throw exception
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "order_id")
private Integer orderId;
#OneToOne(cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH})
#JoinColumn(name = "product_id")
private Product productId;
#ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH})
#JoinColumn(name = "client_id")
private Client client;
....
Product Model
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "product_id")
private Integer id;
#Column(name = "product_name")
private String productName;
#Column(name = "product_serial")
private String productSerial;
...
Client Model
#Entity
#Table(name = "clients")
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#NotEmpty
#Column(name = "first_name")
private String firstName;
#NotEmpty
#Column(name = "last_name")
private String lastName;
#NotEmpty
#Email
#Column(name = "email")
private String email;
#NotEmpty
#Column(name = "location")
private String location;
#OneToMany(mappedBy = "client",cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Order> orders;
Controller, where I save the order with related client and product
#PostMapping("add")
public ModelAndView addOrder( #Validated #ModelAttribute("ords") Order order, BindingResult bindingResult ){
if (bindingResult.hasErrors()) {
System.out.println("Having errors: " + bindingResult.getAllErrors());
Iterable<Product> products = productService.listProducts();
Iterable<Client> clients = clientService.listClients();
System.out.println("Error "+ bindingResult.getAllErrors());
ModelAndView mv = new ModelAndView("orders/add-order");
mv.addObject("products",products);
mv.addObject("clients",clients);
return mv;
}
try {
orderService.saveOrder(order);
} catch (Exception e) {
e.printStackTrace();
}
ModelAndView mv = new ModelAndView("redirect:list");
return mv;
}
Finally, my JSP form View page
<form:form action="add" method="post" modelAttribute="ords">
<label for="productId" >Product Id</label>
<form:select path="productId" >
<c:forEach var="product" items="${products}">
<form:option value="${product.id}">${product.productName}</form:option>
</c:forEach>
</form:select>
<form:errors path="productId"/>
<br>
<label for="client" >Client Id</label>
<form:select path="client" >
<c:forEach var="client" items="${clients}">
<form:option value="${client.id}">${client.id} - ${client.lastName}</form:option>
</c:forEach>
</form:select>
<form:errors path="client"/>
<br>
<input type="submit" value="Place Order">
</form:form>
What am I doing wrong?
You most likely need to build a converter class such as this one :
#Component("facilityConverter")
public class FacilityConverter implements Converter<String, Facility>
{
#Autowired
FacilityService facilityService;
#Override
public Facility convert(String id)
{
return facilityService.findById(Integer.parseInt(id));
}
}
Then, you need to register it by implementing the addFormatters method inside of a configuration class implementing WebMvcConfigurer like so :
#Override
public void addFormatters (FormatterRegistry registry)
{
registry.addConverter((FacilityConverter)ctx.getBean("facilityConverter"));
}
Your entities will then correctly be mapped from a dropdown selection. Also, this might not be part of your issue but you can just build your dropdowns like this :
<form:select name="linkedInterface" path="linkedInterface" id="linkedInterface">
<form:options items="${interfaces}" itemLabel="name" itemValue="id"/>
</form:select>
The productId field is actually a Product object, not an ID (String/int). You need your JSP to use path="productId.id" rather than path="productId".
(Although I'd also suggest you also rename the field product rather than productId.)
<form:select path="product.id">
I think you'll hit the same issue on your <form:select path="client"> too.

Haw can i show the details of each with using many to many relationship using spring and thymeleaf

I want to display the details of each user here is my class entity
#Entity
#Table(name="user")
public class User implements Serializable{
#Id #GeneratedValue
private Long id;
private String nom ;
#ManyToMany(cascade = {CascadeType.ALL})
#JoinTable(name="user_user_detail",joinColumns={
#JoinColumn(name="id")},
inverseJoinColumns={#JoinColumn(name="UserId")})
private Collection<UserDetail>userDetail ;
classe user detail
#Entity
#Table(name="userDetail")
public class UserDetail implements Serializable{
#Id #GeneratedValue
private Long UserId;
private String adresse ;
My controller
#RequestMapping(name="/vue", method = RequestMethod.GET)
public String vue(Model model){
User u=new User();
List<User>p=new ArrayList<User>();
p.add(u);
p=ur.findAll();
model.addAttribute("us",p);
return "user" ;
}
My view thymeleaf
<table border="1">
<tr>
<td>Nom</td>
<td>adresse</td>
</tr>
<tr th:each="t:${us}">
<td th:text="${t.Id}"></td>
<td th:text="${t.nom}"></td>
<td th:text="${t.getUserDetail()}"></td>
</tr>
</table>
i would to show the userdetail with
${t.getUserDetail()}">
but the result of details like this [org.sid.entity.UserDetail#1469f77e, org.sid.entity.UserDetail#78a81727]
please answer me quickly
thank's in advance

Spring MVC, load objects attributes in a jsp

I got an issue when trying to load an object attribute in a jsp file.
The model contains a list of objects of type "Evaluation", for each element in the list, all the attributes are correctly loaded except the ones that it has to fetch from another table.
The .jsp file :
<div class="container">
<h1>Liste des Evaluations pour ${etudiant.username}</h1>
<table class="tbl">
<thead>
<th>Module</th>
<th>Note</th>
<th>Remarque</th>
</thead>
<tbody>
<c:forEach items="model.evaluations" var="ev">
<tr>
<td>${ev.examen.module.code}</td> --> Error occurs here
<td>${ev.note}</td>
<td>${ev.remarque}</td>
</tr>.
</c:forEach>
</tbody>
</table>
The Controller :
#RequestMapping(value="/{username}", method=RequestMethod.GET)
public String etudiantEvaluations(
#PathVariable String username, Model model) {
List<Evaluation> evaluations = evalDAO.findAllByEtudiant(username);
Etudiant etudiant = etDAO.findByUsername(username);
model.addAttribute("evaluations", evaluations);
model.addAttribute("etudiant", etudiant);
return "etudiants/listEvaluations";
}
The Evaluation entity :
#Data
#NoArgsConstructor
#EqualsAndHashCode
#Immutable #Entity(name="TEVALUATION")
public class Evaluation {
private enum evaldeliberation {
REUSSITE,
AJOURNEMENT,
REFUS,
ABANDON
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
protected Long id;
#NotNull
#Min(0) #Max(100)
#Column(updatable = true)
private Double note;
#Column(name="deliberation")
private evaldeliberation delib;
#Column(name="remarque")
private String remarque;
#Column(name="module_code")
private String moduleCode;
private Long examenId;
private String etudiantUsername;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name = "FKExamen",
insertable = false,
updatable = false)
protected Examen examen;
#ManyToOne
#JoinColumn(name = "FKEtudiant",
insertable = false,
updatable = false)
protected Etudiant etudiant;
#OneToMany(mappedBy="evaluation")
protected List<EvalComp> evalComps = new ArrayList<>();
public Evaluation(Double note, Examen examen, Etudiant etudiant) {
super();
this.examen = examen;
this.etudiant = etudiant;
examen.getEvaluations().add(this);
etudiant.getEvaluations().add(this);
}
}
Examen:
#Data
#EqualsAndHashCode
#NoArgsConstructor
#Entity(name="TEXAMEN")
public class Examen {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#OneToMany(mappedBy = "examen")
private Set<Evaluation> evaluations = new HashSet<>();
#NotNull
#OneToOne(cascade=CascadeType.PERSIST)
#JoinColumn(name="FKmodule")
protected Module module;
public Examen(Module module) {
this.module = module;
}
}
The Query:
#Query("SELECT ev FROM TEVALUATION ev JOIN FETCH ev.examen ex JOIN FETCH ex.module m WHERE ev.etudiant=?1")
List<Evaluation> findAllByEtudiantId(String username);
The getters and setters are generated by Lombok(also tried without it).
Any idea how can I load the attributes ?
Thanks in advance.

What is the EL test expression for foreign key attribute?

I have 3 entities :
#Entity
#Table(name = "resultat")
public class Resultat {
#Id
#SequenceGenerator(name="s_resultat", sequenceName="pta.s_resultat", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_resultat")
#Column(name = "result_code")
private Integer code;
#Column(name="result_intitule")
private String lib;
#ManyToOne
#JoinColumn(name = "acti_code")
private Activite activite;
...
}
#Entity
#Table(name = "activite")
public class Activite {
#Id()
#Column(name="acti_code")
private String code;
#Column(name="acti_design")
private String lib;
#ManyToOne
#JoinColumn(name = "action_code")
private Action action;
public Activite() {
super();
}
...
}
#Entity
#Table(name = "action")
public class Action {
#Id
#SequenceGenerator(name="s_action", sequenceName="pta.s_action", allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_action")
#Column(name = "action_code")
private Integer code;
#Column(name="action_design")
private String lib;
...
}
Now I want to display a master-detail JSP page for the two entities Activite and Resultat. I created DAOs returning list of Action, list of Activite, and list of Resultat. And called them in the controller in order to be passed to the JSP.
In my JSP I loop the list of Activite first , then I loop the list of Resultat :
<c:forEach items="${activites}" var="activite" varStatus="statusActivite">
<c:forEach items="${resultats}" var="resultat">
// here I want to test if resultat is the right foreign key for the actual activite
</c:forEach>
</c:forEach>
So how to write the test for the resultat variable to be the foreign key associated to the activite ?

Spring select multiple tag and binding

I am trying to use the select tag of spring to select multiple options to fill a List.
My select tags is well displayed and when I select options the List is correctly updated.
The only problem I have is when I render the for with an already filled List, my select tag does not highlight the selected options. I have try to debug and Ican see that the List is not empty, it is really the tag that seems to not mark the selected options as selected.
My code :
#Entity
public class ProductsGroup
{
#Version #Column(name = "version")
private Integer version;
#Id #GeneratedValue(strategy = GenerationType.AUTO) #Column(name = "id")
private Integer id;
#ManyToMany(fetch = FetchType.EAGER)
private List<Product> products;
public List<Product> getProducts()
{
return products;
}
public void setProducts(List<Product> products)
{
this.products = products;
}
}
#Entity
public class Product
{
#Version #Column(name = "version")
private Integer version;
#Id #GeneratedValue(strategy = GenerationType.AUTO) #Column(name = "id")
private Long id;
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
<form:form action="${action}" class="fancyform" commandName="productsGroup" id="productForm">
....
<form:select path="products" items="${products}" itemLabel="name" itemValue="id" multiple="true"/>
....
</form:form>
It's probably due to the fact that the list of selected products doesn't contain the same instances as the complete list of displayed products.
The tag compares products with equals(), and you have not overridden equals() (and hashCode()) in your Product class.
So even if the selected products contain the Product with the name "foo", and the complete list of Product also contains a Product with the name "foo", those products are not equal, and Spring thus doesn't know they're the same product, and that this product should thus be selected.

Resources