i am getting a bug when i created the product and when it shows the category type it gives me a location for a file - spring

In the createProduct.html after i created the product, and when i go to products.html page which it will show all the products with their details, so i get in the category section a wrong value. as u can see in the page.
Category Entity:
#Entity
public class Categories {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long categories_id;
private String categoryName;
#OneToMany(mappedBy = "product_category",fetch = FetchType.LAZY) //the name of the variable in the other class
private Set<Products> product_category = new HashSet<>();
public Categories(String categoryName, Set<Products> product_category) {
this.categoryName = categoryName;
this.product_category = product_category;
}
public Categories() {
}
public Long getCategories_id() {
return categories_id;
}
public void setCategories_id(Long categories_id) {
this.categories_id = categories_id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Set<Products> getProduct_category() {
return product_category;
}
public void setProduct_category(Set<Products> product_category) {
this.product_category = product_category;
}
Products Entity:
#Entity
#Table(name = "Products")
public class Products {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long product_id;
private String product_name;
private BigDecimal product_price;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "categories_id") //the name of the column in the other class and that name will be a column in the class
private Categories product_category;
private String product_quantity;
private String product_Section;
private String product_ExpDate;
public Products(String product_name, BigDecimal product_price, Categories product_category, String product_quantity, String product_Section, String product_ExpDate) {
this.product_name = product_name;
this.product_price = product_price;
this.product_category = product_category;
this.product_quantity = product_quantity;
this.product_Section = product_Section;
this.product_ExpDate = product_ExpDate;
}
public Products() {
}
public long getProduct_id() {
return product_id;
}
public void setProduct_id(long product_id) {
this.product_id = product_id;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public BigDecimal getProduct_price() {
return product_price;
}
public void setProduct_price(BigDecimal product_price) {
this.product_price = product_price;
}
public Categories getProduct_category() {
return product_category;
}
public void setProduct_category(Categories product_category) {
this.product_category = product_category;
}
public String getProduct_quantity() {
return product_quantity;
}
public void setProduct_quantity(String product_quantity) {
this.product_quantity = product_quantity;
}
public String getProduct_Section() {
return product_Section;
}
public void setProduct_Section(String product_Section) {
this.product_Section = product_Section;
}
public String getProduct_ExpDate() {
return product_ExpDate;
}
public void setProduct_ExpDate(String product_ExpDate) {
this.product_ExpDate = product_ExpDate;
}
Product Controller:
#Controller
public class ProductsController {
//adding the service layer of the product
#Autowired
private ProductService productService;
#Autowired
private CategoriesRepository categoriesRepository;
public ProductsController(ProductService productService,CategoriesRepository categoriesRepository )
{
super();
this.productService = productService;
this.categoriesRepository = categoriesRepository;
}
// models
#ModelAttribute("category")
public List<Categories> initializeCategories(){
List<Categories> categories = categoriesRepository.findAll();
return categories ;
}
#ModelAttribute("product")
public Products products()
{
return new Products();
}
/////////////////////////////////// handllers
//request to list all the products
#RequestMapping("/products/all_products")
public String listProducts(Model model)
{
model.addAttribute("product",productService.getAllProducts());
return "Products/products";
}
//request to show the form to create a product // when u are accessing the http request u will access that one coz it will show the form and then the Save method will do the action
#GetMapping("/products/new/product")
public String createProductForm(Model model)
{
//Create product object
Products product = new Products();
model.addAttribute("product",product); // product is the object from products Entityclass
return "Products/create_product";
}
//request to create/save a product
#RequestMapping(value = "/products/create_product",method = RequestMethod.POST)
public String saveProduct(#ModelAttribute("product") Products product) // Products is the name of the Entity class and creating a productObjcet from it
{
productService.saveProduct(product);
return "redirect:/products/all_products";
}
#GetMapping("/products/edit/{id}")
public String editProductForm(#PathVariable long id, Model model)
{
model.addAttribute("product",productService.getProductById(id));
return "Products/edit_product";
}
//request to update product
#RequestMapping(value = "/products/update_product/{id}",method=RequestMethod.POST)
public String updateProduct(#PathVariable Long id, #ModelAttribute("product") Products product, Model model) // model Attribute is the data taken from the html file by the user
{
//get product from the db by id
Products existingProduct = productService.getProductById(id);
existingProduct.setProduct_id(id);
existingProduct.setProduct_name(product.getProduct_name());
existingProduct.setProduct_price(product.getProduct_price());
existingProduct.setProduct_category(product.getProduct_category());
existingProduct.setProduct_quantity(product.getProduct_quantity());
existingProduct.setProduct_Section(product.getProduct_Section());
existingProduct.setProduct_ExpDate(product.getProduct_ExpDate());
//updating the product
productService.updateProduct(existingProduct);
return "redirect:/products/all_products";
}
//request to Delete product
#GetMapping("/products/delete_product/{id}")
public String deleteProduct(#PathVariable long id)
{
productService.deleteProduct(id);
return "redirect:/products/all_products";
}
}
Products.html Page to show all the products
<table class = "table table-striped table-bordered">
<thead class = "table-dark">
<tr>
<th> Category </th>
<th> Product Name </th>
<th> Product Price </th>
<th> Product Quantity </th>
<th> Product Section </th>
<th> Product Expiry Date </th>
<th> Edit </th>
<th> Delete </th>
</tr>
</thead>
<tbody>
<tr th:each = "product: ${product}"> <!-- this attribute to list up products -->
<td th:text="${product.product_category}" ></td>
<td th:text="${product.product_name}"></td>
<td th:text="${product.product_price}"></td>
<td th:text="${product.product_quantity}" ></td>
<td th:text="${product.product_Section}" ></td>
<td th:text="${product.product_ExpDate}" ></td>
<td> <center> <a th:href="#{/products/edit/{id}(id=${product.product_id})}" style="color: green"> Edit </a> </center> </td>
<td> <center> <a th:href="#{/products/delete_product/{id}(id=${product.product_id}) }" style="color: red"> Delete </a> </center> </td>
</tr>
</tbody>
</table>
CreateAProduct.html Page
<form th:action="#{/products/create_product}" method="post" th:object="${product}">
<div class="form-group">
<label class="control-label" for="product_name"> Product Name </label> <input
id="product_name" class="form-control" th:field="*{product_name}"
required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_price"> Price </label> <input
id="product_price" class="form-control" th:field="*{product_price}" required
autofocus="autofocus" />
</div>
<div class="col-1.5">
<label th:for="category"> Category </label>
<select class="form-control form-control-sm" id="category" name="product_category">
<option value=""> Select Category </option>
<option th:each = "category: ${category}"
th:value="${category.categories_id}"
th:text="${category.categoryName}"
> <!--th:field="*{product_category}"-->
</option>
</select>
</div>
<br>
<div class="form-group">
<label class="control-label" for="product_quantity"> Quantity </label> <input
id="product_quantity" class="form-control" type="text"
th:field="*{product_quantity}" required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_Section"> Section </label> <input
id="product_Section" class="form-control" type="text"
th:field="*{product_Section}" required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_ExpDate"> Expire Date </label> <input
id="product_ExpDate" class="form-control" type="text"
th:field="*{product_ExpDate}" required autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
Product Service layer:
#Service
public class ProductServiceImp implements ProductService {
//productRepository class
private ProductRepository productRepository;
public ProductServiceImp(ProductRepository productRepository) {
this.productRepository = productRepository;
}
#Override
public List<Products> getAllProducts() {
return this.productRepository.findAll();
}
#Override
public Products saveProduct(Products product) {
return this.productRepository.save(product);
}
#Override
public Products updateProduct(Products product) {
return this.productRepository.save(product);
}
#Override
public void deleteProduct(long id) {
this.productRepository.deleteById(id);
}
public Products getProductById(long id)
{
return productRepository.findById(id).get();
}
}

The Categories class is which is being used to display the value under that Category Column you see in HTML.
You either override toString():
#Entity
public class Categories {
...
...
#Override
public String toString() {
return categoryName;
}
}
Or you call the categoryName directly instead of the Object (product_category) itself:
<td th:text="${product.product_category.categoryName}" ></td>

Related

I am getting an error 500, while i am trying to show all the products that exist in my database using SpringBoot

when i create a product and fill out the details in the create_product.html page when i click on add button, it should direct me to the Products.html page which I will show all the products but I am getting an error when I transferred me to the Products.html page. However, when i check my database table I found that the product had been added.
ProductController Class
#Controller
public class ProductsController {
//adding the service layer of the product
#Autowired
private ProductService productService;
#Autowired
private CategoriesRepository categoriesRepository;
public ProductsController(ProductService productService,CategoriesRepository categoriesRepository )
{
super();
this.productService = productService;
this.categoriesRepository = categoriesRepository;
}
// models
#ModelAttribute("category")
public List<Categories> initializeCategories(){
List<Categories> categories = categoriesRepository.findAll();
return categories ;
}
#ModelAttribute("product")
public Products products()
{
return new Products();
}
/////////////////////////////////// handllers
//request to list all the products
#RequestMapping("/products/all_products")
public String listProducts(Model model)
{
model.addAttribute("product",productService.getAllProducts());
return "Products/products";
}
//request to show the form to create a product // when u are accessing the http request u will access that one coz it will show the form and then the Save method will do the action
#GetMapping("/products/new/product")
public String createProductForm(Model model)
{
//Create product object
Products product = new Products();
model.addAttribute("product",product); // product is the object from products Entityclass
return "Products/create_product";
}
//request to create/save a product
#RequestMapping(value = "/products/create_product",method = RequestMethod.POST)
public String saveProduct(#ModelAttribute("product") Products product) // Products is the name of the Entity class and creating a productObjcet from it
{
productService.saveProduct(product);
return "redirect:/products/all_products";
}
#GetMapping("/products/edit/{id}")
public String editProductForm(#PathVariable long id, Model model)
{
model.addAttribute("product",productService.getProductById(id));
return "Products/edit_product";
}
//request to update product
#RequestMapping(value = "/products/update_product/{id}",method=RequestMethod.POST)
public String updateProduct(#PathVariable Long id, #ModelAttribute("product") Products product, Model model) // model Attribute is the data taken from the html file by the user
{
//get product from the db by id
Products existingProduct = productService.getProductById(id);
existingProduct.setProduct_id(id);
existingProduct.setProduct_name(product.getProduct_name());
existingProduct.setProduct_price(product.getProduct_price());
existingProduct.setProduct_category(product.getProduct_category());
existingProduct.setProduct_quantity(product.getProduct_quantity());
existingProduct.setProduct_Section(product.getProduct_Section());
existingProduct.setProduct_ExpDate(product.getProduct_ExpDate());
//updating the product
productService.updateProduct(existingProduct);
return "redirect:/products/all_products";
}
//request to Delete product
#GetMapping("/products/delete_product/{id}")
public String deleteProduct(#PathVariable long id)
{
productService.deleteProduct(id);
return "redirect:/products/all_products";
}
}
Categories Entity Class:
#Entity
#Data
public class Categories {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long categories_id;
private String categoryName;
#OneToMany(mappedBy = "product_category",fetch = FetchType.LAZY) //the name of the variable in the other class
private Set<Products> product_category = new HashSet<>();
public Categories(String categoryName, Set<Products> product_category) {
this.categoryName = categoryName;
this.product_category = product_category;
}
public Categories() {
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
}
Product Entity class :
#Entity
#Table(name = "Products")
#Data
public class Products {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long product_id;
private String product_name;
private BigDecimal product_price;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "categories_id") //the name of the column in the other class and that name will be a column in the class
private Categories product_category;
private String product_quantity;
private String product_Section;
private String product_ExpDate;
public Products()
{
super();
}
public Products(String product_name, BigDecimal product_price,String product_quantity,Categories product_category ,String product_Section,String product_ExpDate) {
this.product_name = product_name;
this.product_category = product_category;
this.product_price = product_price;
this.product_quantity = product_quantity;
this.product_Section = product_Section;
this.product_ExpDate = product_ExpDate;
}
ProductService Class:
#Service
public class ProductServiceImp implements ProductService {
//productRepository class
private ProductRepository productRepository;
public ProductServiceImp(ProductRepository productRepository) {
this.productRepository = productRepository;
}
#Override
public List<Products> getAllProducts() {
return this.productRepository.findAll();
}
#Override
public Products saveProduct(Products product) {
return this.productRepository.save(product);
}
#Override
public Products updateProduct(Products product) {
return this.productRepository.save(product);
}
#Override
public void deleteProduct(long id) {
this.productRepository.deleteById(id);
}
public Products getProductById(long id)
{
return productRepository.findById(id).get();
}
}
CreateProduct.html page:
<form th:action="#{/products/create_product}" method="post" th:object="${product}">
<div class="form-group">
<label class="control-label" for="product_name"> Product Name </label> <input
id="product_name" class="form-control" th:field="*{product_name}"
required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_price"> Price </label> <input
id="product_price" class="form-control" th:field="*{product_price}" required
autofocus="autofocus" />
</div>
<div class="col-1.5">
<label th:for="category"> Category </label>
<select class="form-control form-control-sm" id="category" name="product_category">
<option value=""> Select Category </option>
<option th:each = "category: ${category}"
th:value="${category.categories_id}"
th:text="${category.categoryName}"
> <!--th:field="*{product_category}"-->
</option>
</select>
</div>
<br>
<div class="form-group">
<label class="control-label" for="product_quantity"> Quantity </label> <input
id="product_quantity" class="form-control" type="text"
th:field="*{product_quantity}" required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_Section"> Section </label> <input
id="product_Section" class="form-control" type="text"
th:field="*{product_Section}" required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="product_ExpDate"> Expire Date </label> <input
id="product_ExpDate" class="form-control" type="text"
th:field="*{product_ExpDate}" required autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
products.html page
<table class = "table table-striped table-bordered">
<thead class = "table-dark">
<tr>
<th> Category </th>
<th> Product Name </th>
<th> Product Price </th>
<th> Product Quantity </th>
<th> Product Section </th>
<th> Product Expiry Date </th>
<th> Edit </th>
<th> Delete </th>
</tr>
</thead>
<tbody>
<tr th:each = "product: ${product}"> <!-- this attribute to list up products -->
<td th:text="${product.product_category}" ></td>
<td th:text="${product.product_name}"></td>
<td th:text="${product.product_price}"></td>
<td th:text="${product.product_quantity}" ></td>
<td th:text="${product.product_Section}" ></td>
<td th:text="${product.product_ExpDate}" ></td>
<td> <center> <a th:href="#{/products/edit/{id}(id=${product.product_id})}" style="color: green"> Edit </a> </center> </td>
<td> <center> <a th:href="#{/products/delete_product/{id}(id=${product.product_id}) }" style="color: red"> Delete </a> </center> </td>
</tr>
</tbody>
</table>
FullTrace Error:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Oct 20 03:45:45 EDT 2021
There was an unexpected error (type=Internal Server Error, status=500).
No message available
java.lang.StackOverflowError
at com.mysql.cj.NativeSession.execSQL(NativeSession.java:696)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:930)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.getResultSet(AbstractLoadPlanBasedLoader.java:390)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeQueryStatement(AbstractLoadPlanBasedLoader.java:163)
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:104)
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:87)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:710)
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:76)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:99)
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2163)
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:589)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:458)
at com.example.warehouseManagementSystem.Entities.Categories.hashCode(Categories.java:10)
at com.example.warehouseManagementSystem.Entities.Products.hashCode(Products.java:10)
at java.base/java.util.HashMap.hash(HashMap.java:340)
at java.base/java.util.HashMap.put(HashMap.java:612)
at java.base/java.util.HashSet.add(HashSet.java:221)
The problem is that you are using #Data from Lombok on your entity. Remove this and manually implement equals() and hashCode in a way that does not lead to a StackOverflowError. In most cases, you only want to check the primary key.
See https://www.wimdeblauwe.com/blog/2021/04/26/equals-and-hashcode-implementation-considerations/ for more info on how to correctly implement equals and hashcode.
See also https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/#Avoid_Data for more info on why you should be careful with Lombok and JPA/Hibernate.

How to make Search data using Spring boot

i am a beginner of spring boot framework.i want to work with search records using spring boot application. my index.html is loaded successfully when i enter the employee id on the employee id textbox and click search button relevant employee name result want to display the below textbox.but i don't know how to pass it .what i tired so so i attached below.
index.html
<form action="#" th:action="#{/search}" th:object="${employee}" method="post">
<div alight="left">
<tr>
<label class="form-label" >Employee ID</label>
<td>
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{id}" class="form-control" placeholder="Employee ID" />
</td>
</tr>
</div>
<br>
<tr>
<td colspan="2"><button type="submit" class="btn btn-info">Search</button> </td>
</tr>
<div alight="left">
<tr>
<label class="form-label" >Employee Name</label>
<td>
<input type="text" th:field="*{ename}" class="form-control" placeholder="Employee Name" />
</td>
</tr>
</div>
</form>
Controller
#Controller
public class EmployeeController {
#Autowired
private EmployeeService service;
#GetMapping("/")
public String add(Model model) {
List<Employee> listemployee = service.listAll();
// model.addAttribute("listemployee", listemployee);
model.addAttribute("employee", new Employee());
return "index";
}
#RequestMapping("/search/{id}")
public ModelAndView showSearchEmployeePage(#PathVariable(name = "id") int id) {
ModelAndView mav = new ModelAndView("new");
Employee emp = service.get(id);
mav.addObject("employee", emp);
return mav;
}
}
Entity
#Entity
public class Employee {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String ename;
private int mobile;
private int salary;
public Employee() {
}
public Employee(Long id, String ename, int mobile, int salary) {
this.id = id;
this.ename = ename;
this.mobile = mobile;
this.salary = salary;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getMobile() {
return mobile;
}
public void setMobile(int mobile) {
this.mobile = mobile;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
#Override
public String toString() {
return "Employee [id=" + id + ", ename=" + ename + ", mobile=" + mobile + ", salary=" + salary + "]";
}
Repository
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
It is easiest to create a dedicated form data object:
public class EmployeeSearchFormData {
private long employeeId;
// getter and setter
}
In the controller:
#Controller
public class EmployeeController {
#Autowired
private EmployeeService service;
#GetMapping("/")
public String add(Model model) {
model.addAttribute("employeeSearchFormData", new EmployeeSearchFormData());
return "index";
}
#PostMapping("/search")
public String doSearchEmployee(#ModelAttribute("employeeSearchFormData") EmployeeSearchFormData formData, Model model) {
Employee emp = service.get(formData.getEmployeeId());
model.addAttribute("employee", emp);
return "index";
}
}
Thymeleaf template:
<form action="#" th:action="#{/search}" th:object="${employeeSearchFormData}" method="post">
<div alight="left">
<tr>
<label class="form-label" >Employee ID</label>
<td>
<input type="text" th:field="*{employeeId}" class="form-control" placeholder="Employee ID" />
</td>
</tr>
</div>
<br>
<tr>
<td colspan="2"><button type="submit" class="btn btn-info">Search</button> </td>
</tr>
<div alight="left">
<tr>
<label class="form-label" >Employee Name</label>
<td>
<input type="text" th:field="${employee.ename}" class="form-control" placeholder="Employee Name" />
</td>
</tr>
</div>
</form>
Note the use of th:field="${employee.ename}" and not use *{...}. I also removed the hidden field as it does not seem needed to have it to me.
As an alternative, you can have the #PostMapping redirect to /employee/<id> if there is an endpoint available like that:
#PostMapping("/search")
public String doSearchEmployee(#ModelAttribute("employeeSearchFormData") EmployeeSearchFormData formData) {
return "redirect:/employee/" + formData.getEmployeeId();
}

Cant get view of the form in thymeleaf after put to it list of object

I have a big problem to solve and I don`t see the sollution of this, because IntelliJ not given me any log. Here is the point:
When I try to open the page with form where I put data od employee and address, address form is invisible.
My code:
View:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Dodaj nową firmę</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" th:href="#{/webjars/bootstrap/4.4.1-1/css/bootstrap.min.css}" />
<script th:src="#{/webjars/jquery/3.5.1/jquery.min.js}"></script>
<script th:src="#{/webjars/bootstrap/4.4.1-1/js/bootstrap.min.js}"></script>
</head>
<body>
<div style = "text-align: center;">
<h1>Dodaj nowego pracownika do bazy danych</h1>
</div>
<form class="form-horizontal" th:object="${employee}" th:action="#{/employees}" th:method="post">
<div class="container" style="margin-top:10mm;">
<div class="row">
<div class="col-sm">
<div style = "text-align: center;">
<h5>Dane osobowe</h5>
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{name}"/>
<label class="control-label">Imię</label>
<div class="text-danger"><p th:if="${#fields.hasErrors('name')}" th:errors="*{name}"/></div>
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{surname}"/>
<label class="control-label">Nazwisko</label>
<div class="text-danger"><p th:if="${#fields.hasErrors('surname')}" th:errors="*{surname}"/></div>
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{position}"/>
<label class="control-label">Stanowisko</label>
<div class="text-danger"><p th:if="${#fields.hasErrors('position')}" th:errors="*{position}"/></div>
</div>
<div class="form-group">
<input type="number" class="form-control" th:field="*{age}"/>
<label class="control-label">Wiek</label>
<div class="text-danger"><p th:if="${#fields.hasErrors('age')}" th:errors="*{age}"/></div>
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{nationality}"/>
<label class="control-label">Obywatelstwo</label>
<div class="text-danger"><p th:if="${#fields.hasErrors('nationality')}" th:errors="*{nationality}"/></div>
</div>
</div>
<div class="col-sm">
<div th:object="${listAddress}">
<div style = "text-align: center;">
<h5>Dane adresowe</h5>
</div>
<div style = "text-align: center;">
<h6>Adres stały</h6>
</div>
<div th:each="row, stat : ${listAddress.addresses}">
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].type}"/>
<label class="control-label">Typ adresu</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('type')}" th:errors="*{type}"/></div>-->
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].street}"/>
<label class="control-label">Ulica</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('street')}" th:errors="*{street}"/></div>-->
</div>
<div class="form-group">
<input type="number" class="form-control" th:field="*{addresses[__${stat.index}__].streetNr}"/>
<label class="control-label">Numer domu</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('streetNr')}" th:errors="*{streetNr}"/></div>-->
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].flatNr}"/>
<label class="control-label">Numer mieszkania</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('flatNr')}" th:errors="*{flatNr}"/></div>-->
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].postalCode}"/>
<label class="control-label">Kod pocztowy</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('postalCode')}" th:errors="*{postalCode}"/></div>-->
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].city}"/>
<label class="control-label">Miasto</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('city')}" th:errors="*{city}"/></div>-->
</div>
<div class="form-group">
<input type="text" class="form-control" th:field="*{addresses[__${stat.index}__].country}"/>
<label class="control-label">Kraj</label>
<!-- <div class="text-danger"><p th:if="${#fields.hasErrors('country')}" th:errors="*{country}"/></div>-->
</div>
</div>
</div>
<div style = "text-align: right;">
<button type="submit" class="btn btn-primary btn-lg active center-block">ZAPISZ</button>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
Controller:
#RequestMapping("/new")
public String addNewEmployee(Model model) {
AddressesList listOfAddress = new AddressesList();
ArrayList<Address> addressesArray = new ArrayList<>();
listOfAddress.setAddresses(addressesArray);
model.addAttribute("employee", new Employee()).addAttribute("listAddress", listOfAddress);
return "new_employee_form";
}
AddressList class
public class AddressesList {
private List<Address> addresses;
public AddressesList() {
}
public AddressesList(List<Address> addresses) {
this.addresses = addresses;
}
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
}
Address class
public class Address {
public Long idAddress;
public Long idEmployee;
public String type;
public String street;
public String streetNr;
public Integer flatNr;
public String postalCode;
public String city;
public String country;
public Address() {
}
private Address(Long idEmployee, String type, String street, Integer flatNr, String streetNr, String postalCode, String city, String country) {
this.idEmployee = idEmployee;
this.type = type;
this.street = street;
this.streetNr = streetNr;
this.flatNr = flatNr;
this.postalCode = postalCode;
this.city = city;
this.country = country;
}
public static class AddressBuilder{
private Long idAddress;
private Long idEmployee;
private String type;
private String street;
private String streetNumber;
private Integer flatNr;
private String postalCode;
private String city;
private String country;
public AddressBuilder setIdEmployee(Long idEmployee) {
this.idEmployee = idEmployee;
return this;
}
public AddressBuilder setType(String type) {
this.type = type;
return this;
}
public AddressBuilder setStreet(String street) {
this.street = street;
return this;
}
public AddressBuilder setFlatNr(Integer flatNr) {
this.flatNr = flatNr;
return this;
}
public AddressBuilder setStreetNumber(String streetNumber) {
this.streetNumber = streetNumber;
return this;
}
public AddressBuilder setPostalCode(String postalCode) {
this.postalCode = postalCode;
return this;
}
public AddressBuilder setCity(String city) {
this.city = city;
return this;
}
public AddressBuilder setCountry(String country) {
this.country = country;
return this;
}
public Address build(){
return new Address(idEmployee, type, street, flatNr, streetNumber, postalCode, city, country);
}
}
public void setIdAddress(Long idAddress) {
this.idAddress = idAddress;
}
public void setIdEmployee(Long idEmployee) {
this.idEmployee = idEmployee;
}
public void setType(String type) {
this.type = type;
}
public void setStreet(String street) {
this.street = street;
}
public void setFlatNr(Integer flatNr) {
this.flatNr = flatNr;
}
public void setStreetNr(String streetNr) {
this.streetNr = streetNr;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public void setCity(String city) {
this.city = city;
}
public void setCountry(String country) {
this.country = country;
}
public Long getIdAddress() {
return idAddress;
}
public Long getIdEmployee() {
return idEmployee;
}
public String getType() {
return type;
}
public String getStreet() {
return street;
}
public Integer getFlatNr() {
return flatNr;
}
public String getStreetNr() {
return streetNr;
}
public String getPostalCode() {
return postalCode;
}
public String getCity() {
return city;
}
public String getCountry() {
return country;
}
#Override
public String toString() {
return "Address{" +
"idAddress=" + idAddress +
", idEmployee=" + idEmployee +
", type='" + type + '\'' +
", street='" + street + '\'' +
", flattNr=" + flatNr +
", streetNumber='" + streetNr + '\'' +
", postalCode='" + postalCode + '\'' +
", city='" + city + '\'' +
", country='" + country + '\'' +
'}';
}
}
I get the page like this with no errors
with no address form on the right side od page.
Please help to solve this problem.
You are adding an empty list of addresses to your backing object:
ArrayList<Address> addressesArray = new ArrayList<>();
listOfAddress.setAddresses(addressesArray);
If you want the form to show up, you need to add at least one address so it has something to loop over.
ArrayList<Address> addressesArray = new ArrayList<>();
addressesArray.add(new Address());
listOfAddress.setAddresses(addressesArray);
I think I do this wrong.
When I add index to ArrayList form showed up.
#RequestMapping("/new")
public String addNewEmployee(Model model) {
AddressesList listOfAddress = new AddressesList();
ArrayList<Address> addressesArray = new ArrayList<Address>(2);
addressesArray.add(0, new Address());
addressesArray.add(1, new Address());
listOfAddress.setAddresses(addressesArray);
model.addAttribute("employee", new Employee()).addAttribute("listAddress", listOfAddress);
return "new_employee_form";
}
I want to enter a permanent and correspondence address in the form, accept the form (POST) and save it to class objects. How to do it?

Spring boot+Web mvc+JPA using CrudRepository giving issue on insert of a row using save method throwing EntityExistsException

Among CRUD operation Create is giving error of "A different object with the same identifier value was already associated with the session" Rest all (Read, Update and Delete) is working fine.
Im using oracle sql as database and there is one more entity of product with many to one mapping with categories class.
EntityClass
#Entity
public class Categories {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
public Categories() {
super();
}
public Categories(Integer id,String name) {
this.id=id;
this.name=name;
}
public Categories(String name) {
this.name=name;
}
//with setters and getters
}
JSP page
<body onload="document.getElementById('name').disabled = true;document.getElementById('hidden').disabled = true;">
<div align="center">
<h4>Add or Modify or Delete Categories</h4>
<form:form method="POST" action="/categories" modelAttribute="categories">
<table>
<tr>
<td><form:label path="name">Name</form:label></td>
<td>
<form:select path="name">
<form:option value="NONE" label="Select" />
<form:options items="${categoriesList}" />
</form:select>
</td>
</tr>
<tr>
<td>Operations</td>
<td>
<input type="radio" name="Ops" value="Add" checked="checked" onclick="document.getElementById('name').disabled = true; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Add</input><br/>
<input type="radio" name="Ops" value="Modify" onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = false;document.getElementById('hidden').disabled = true;">Modify</input><br/>
<input type="radio" name="Ops" value="Delete" onclick="document.getElementById('name').disabled = false; document.getElementById('newName').disabled = true;document.getElementById('hidden').disabled = false;">Delete</input><br/>
</td>
</tr>
<tr>
<td>Name</td>
<td><input type="text" name="newName" id="newName"/>
<input type="hidden" id="hidden" name="newName" value="dummy"/>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
</div>
</body>
Controller Class
#Controller
public class CategoriesController {
#Autowired
private CategoriesService cservice;
#RequestMapping(value = "/categories", method = RequestMethod.GET)
public ModelAndView categories() {
// view name model
ModelAndView modelAndView = new ModelAndView("categories", "categories", new Categories());
return modelAndView;
}
#RequestMapping(value = "/categories", method = RequestMethod.POST)
public String opsOnCategories(#ModelAttribute("categories") Categories cat,#RequestParam("Ops") String ops,#RequestParam("newName") String name)
{
if(ops.equals("Modify"))
{
cservice.modifyCategory(new Categories(Integer.parseInt(cat.getName()), name));
}else if(ops.equals("Add"))
{
cservice.addCategory(new Categories(name));
}else
{
cservice.deleteCategory(Integer.parseInt(cat.getName()));
}
return "categories";
}
#ModelAttribute("categoriesList")
public Map<String, String> getCategoryList() {
Map<String, String> categoriesList = new HashMap<String, String>();
List<Categories> ls=cservice.getAll();
for(int i=0;i<ls.size();i++)
{
categoriesList.put(ls.get(i).getId().toString(), ls.get(i).getName());
}
return categoriesList;
}
}
Can anyone please help on this.
Previous one due to which there was error
insert into CATEGORIES(ID,NAME) values (1,'Mobile');
insert into CATEGORIES(ID,NAME) values (2,'Laptop');
**Changes made to remove error*
insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Mobile');
insert into CATEGORIES(ID,NAME) values (hibernate_sequence.nextval,'Laptop');
My initial guess is that there something wrong with #Id #GeneratedValue with Oracle Database specifically.
There are couple of things that you can do:
1- Try to connect to any other Database type just to test the functionality - so that you can rule out what doesn't matter
2- Try to use the #org.springframework.data.annotation.Id alongside with the #Id of javax persistence
Something that look like this
#Id
#org.springframework.data.annotation.Id
private Integer id;
3- Create a class that Generates random Integer Ids and refer to it using the annotations (#GenericGenerator & #GeneratedValue)

Image uploading and displaying from database H2 error spring boot thymleaf

I am trying to build a Book shop website using Springboot,thymleaf,H2 embedded. When I try to upload the picture of new book category it gives me a null pointer error
this is my Category.class
#Entity
#Table(name="category")
public class Category implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name="ID")
private Long id;
#Size(min=1, max=90)
#Column(name="CATEGORY_NAME")
private String CategoryName;
#Lob
#Column(name="CATEGORY_PHOTO")
private byte[] CategoryPhoto;
public Category(Long id, #Size(min = 1, max = 90) String categoryName, byte[] categoryPhoto) {
super();
this.id = id;
CategoryName = categoryName;
CategoryPhoto = categoryPhoto;
}
public byte[] getCategoryPhoto() {
return CategoryPhoto;
}
public void setCategoryPhoto(byte[] categoryPhoto) {
CategoryPhoto = categoryPhoto;
}
public Category() {}
#OneToMany(mappedBy = "category", cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Book> Books = new HashSet<>();
public Set<Book> getBooks() {
return Books;
}
CategoryController:
#Controller
#RequestMapping(value="/categories")
public class CategoryController {
private final Logger logger = LoggerFactory.getLogger(BookController.class);
private MessageSource messageSource;
#Autowired
private CategoryService categoryService;
#GetMapping
public String list(Model uiModel) {
logger.info("Listing categories:");
List<Category> categories = categoryService.findALL();
uiModel.addAttribute("categories", categories);
logger.info("No. of categories: " + categories.size());
return "categories";
}
#GetMapping(value = "/{id}")
public String show(#PathVariable Long id, Model model) {
Category category = categoryService.findbyID(id);
if(category.getCategoryPhoto() == null) {
logger.debug("Downloading photo for id: {} with size{}",
category.getId(), category.getCategoryPhoto().length);
}
model.addAttribute("category", category);
return "showCategory";
}
#GetMapping(value = "/new")
public String create(Model uiModel) {
logger.info("creating Category ...");
Category category = new Category();
uiModel.addAttribute("category", category);
return "updateCategory";
}
#PostMapping
public String saveCategory(#Valid Category category, BindingResult bindingResult,
Model uiModel, HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes,
Locale locale, #RequestParam(value="file", required=false) Part file) {
logger.info("Creating Category....");
if(bindingResult.hasErrors())
{
uiModel.addAttribute("message", new Message("error", messageSource.getMessage("category_save_fail", new Object[] {}, locale)));
uiModel.addAttribute("Category", category);
return "categories/new";
}
uiModel.asMap().clear();
redirectAttributes.addFlashAttribute("message", new Message("success", messageSource.getMessage("Category_save_success", new Object[] {}, locale)));
logger.info("Category ID" + category.getId());
//process upload file
if(file != null) {
logger.info("File name:" + file.getName());
logger.info("File size:" + file.getSize());
logger.info("File content type:" + file.getContentType());
byte[] filecontent = null;
try
{
InputStream inputStream = file.getInputStream();
if(inputStream == null)
logger.info("File InputStream is null");
filecontent = IOUtils.toByteArray(inputStream);
category.setCategoryPhoto(filecontent);
}catch(IOException ex) {
logger.error("Error Saving uploaded file");
}
category.setCategoryPhoto(filecontent);
}
categoryService.save(category);
return "redirect:/categories/" + category.getId();
}
}
updatecategories.html page :: used for creating a new category and updating category with Name and Categoryphoto
<form class="form-horizontal" th:object="${category}" th:action="#{/categories}" method="post" enctype="multipart/form-data">
<input type="hidden" th:field="*{id}"/>
<div class="form-group">
<label class="col-sm-2 control-label">Category Name</label>
<div class="col-sm-10">
<input class="form-control" th:field="*{CategoryName}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Category Photo</label>
<div class="col-sm-10">
<input name="file" type="file" value="upload" class="form-control" th:field="*{CategoryPhoto}"/>
</div>
</div>
<div class="row">
<button class="btn btn-default">Save</button>
</div>
</form>
show Categories.html page for showing the category name and photo after creating or updating
<form class="form-horizontal" th:object="${category}" th:action="#{/categories}" method="post" enctype="multipart/form-data">
<input type="hidden" th:field="*{id}"/>
<div class="form-group">
<label class="col-sm-2 control-label">Category Name</label>
<div class="col-sm-10">
<input class="form-control" th:field="*{CategoryName}"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Category Photo</label>
<div class="col-sm-10">
<input name="file" type="file" value="upload" class="form-control" th:field="*{CategoryPhoto}"/>
</div>
</div>
<div class="row">
<button class="btn btn-default">Save</button>
</div>
</form>
here is a image when I create a new category
error Image:
sorry for Long Question description but I want to clarify the details. Help would be appreciated.
I got the mistake I am using MessageSource without autowiring it Done that. And Adding Messages to my properties file.

Resources