i have two tables category and products. where category id is foreign key in products table.when i am trying to insert data in products table using hql my category table is also updated and suppose category is mobile and its id is 1 than after update it will be 1 and null. here are the codes.
Products.java
package com.main.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="Products")
public class Products {
#Id#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column
private String productname;
#Column
private String productstore;
#Column
private String productdesc;
#Column
private double price;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="categoryid")
private Category category;
private String imagePath;
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductname() {
return productname;
}
public void setProductname(String productname) {
this.productname = productname;
}
public String getProductstore() {
return productstore;
}
public void setProductstore(String productstore) {
this.productstore = productstore;
}
public String getProductdesc() {
return productdesc;
}
public void setProductdesc(String productdesc) {
this.productdesc = productdesc;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
}
Category.java
package com.main.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Category")
public class Category {
#Id#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="category_id")
private int id;
#Column
private String categoryName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
}
admin.jsp
<form id="asd" action="/shopping_cart/addProduct" method="post">
<center>
<h3>Please Enter Product Details</h3>
Category<select name="category.id">
<option name="mobiles" value="1">Mobiles</option>
<option name="" value="2">Books</option>
<option name="" value="3">EarPhones</option>
</select><br /> <br />
Product Name <input type="text" value="" name="productname" width="100%" /><span
id="errorname" required></span> <br /> <br /> Product Store
<input type="text" value="" name="productstore" required /> <span
id="error_address" required></span><br /> <br />
Product Desc<input
type="text" value="" name="productdesc" required> <span
id="error_city"></span><br /> <br /> Image Path
<input
type="text" value="" name="imagePath" /><span id="error_state"></span>
<br /> <br /> Price
<input
type="number" value="" name="price" /><span id="error_zipcode"></span>
<br /> <br />
<input
type="submit" value="Add Product" name="addProduct" />
</center>
</form>
Controller
#RequestMapping(value = "/addProduct", method = RequestMethod.POST)
public ModelAndView processForm11(#ModelAttribute("products1") Products products) {
System.out.println("adding product to db");
adminService.addProduct(products);
System.out.println("Product inserted successfully");
ModelAndView model=new ModelAndView("nextpage");
return model;
}
DAOImpl class
package com.main.dao;
import javax.annotation.Resource;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;
import com.main.model.Products;
#Repository
public class AdminDAOImpl implements AdminDAO {#Resource(name="sessionFactory")
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void addProduct(Products product) {
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(product);
tx.commit();
session.close();
}
}
Thanks in advance.
Related
I am writing a SpringBoot application for an e-commerce website project where I'm creating a form to change the current password of the user account. I am getting the following two errors when the form gets submitted.
ERROR-1
An error happened during template parsing (template: "class path resource [templates/myprofile.html]")
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
ERROR-2
Property or field 'id' cannot be found on object of type 'java.lang.Boolean' - maybe not public or not valid?
HomeController
#RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
public String updateUserInfo(
#ModelAttribute("user") user user,
#ModelAttribute("newPassword") String newPassword,
Model model
) throws Exception{
user currentUser = userService.findById(user.getId());
if(currentUser == null) {
throw new Exception ("User not found.");
}
if(userService.findByEmail(user.getEmail())!=null) {
if(userService.findByEmail(user.getEmail()).getId() != currentUser.getId()) {
model.addAttribute("emailExists", true);
return "myprofile";
}
}
if(userService.findByUsername(user.getUsername())!=null) {
if(userService.findByUsername(user.getUsername()).getId() != currentUser.getId()) {
model.addAttribute("usernameExists", true);
return "myprofile";
}
}
if(newPassword != null && !newPassword.isEmpty() && !newPassword .equals("")) {
BCryptPasswordEncoder passwordEncoder = SecurityUtility.passwordEncoder();
String dbPassword = currentUser.getPassword();
if(passwordEncoder.matches(user.getPassword(), dbPassword)) {
currentUser.setPassword(passwordEncoder.encode(newPassword));
}else {
model.addAttribute("invalidPassword", true);
return "myprofile";
}
}
currentUser.setFirstName(user.getFirstName());
currentUser.setLastName(user.getLastName());
currentUser.setUsername(user.getUsername());
currentUser.setEmail(user.getEmail());
userService.save(currentUser);
model.addAttribute("updateSuccess", true);
model.addAttribute("user", true);
model.addAttribute("classActiveEdit", true);
UserDetails userDetails = userSecurityService.loadUserByUsername(currentUser.getUsername());
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return "myprofile";
}
myprofile.html
<form th:action="#{/updateUserInfo}" method="post" >
<input type="hidden" name="id" th:value="${user.id}" />
<div class="bg-info" th:if="${updateUserInfo}">User info updated</div>
<div class="form-group">
<div class="row">
<div class="col-xs-6">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" name="firstName" th:value="${user.firstName}" />
</div>
<div class="col-xs-6">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" name="lastName" th:value="${user.lastName}" />
</div>
</div>
</div>
<div class="form-group">
<label for="userName">Username</label>
<input type="text" class="form-control" id="userName" name="username" th:value="${user.username}" />
</div>
<div class="form-group">
<label for="currentPassword">Current Password</label>
<input type="password" class="form-control" id="currentPassword" name="password" th:value="${currentPassword}" />
</div>
<p style="color: #828282">Enter your current password to change the email address or password</p>
<div class="form-group">
<label for="email">Email Address</label>
<input type="text" class="form-control" id="email" name="email" th:value="${user.email}" />
</div>
<p style="color: #828282">A valid email address. All
emails from the system will be sent to this address.The
email address is not make public and will only be used if
you wish to receive a new password or wish to receive
certain notification</p>
<div class="form-group">
<label for="txtNewPassword">Password</label> <span id="checkPasswordMatch" style="color:red;"></span>
<input type="password" class="form-control" id="txtNewPassword" name="txtNewPassword" />
</div>
<div class="form-group">
<label for="txtConfirmPassword">Confirm Password</label>
<input type="password" class="form-control" id="txtConfirmPassword" />
</div>
<p style="color: #828282">To change the current user password, enter new password in both fileds </p>
<button id="updateUserInfobutton" type="submit" class="btn btn-primary">Save All</button>
</form>
User Class
package com.eshop.domian;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.eshop.security.UserRole;
import com.eshop.security.auth;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
public class user implements UserDetails{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id", nullable = false, updatable = false)
private Long id;
private String firstName;
private String lastName;
private String username;
private String password;
#Column(name="email", nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled=true;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
private ShoppingCart shoppingCart;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserShipping> userShippingList;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserPayment> userPaymentList;
#OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JsonIgnore
private Set<UserRole> userRoles= new HashSet<>();
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public List<UserShipping> getUserShippingList() {
return userShippingList;
}
public void setUserShippingList(List<UserShipping> userShippingList) {
this.userShippingList = userShippingList;
}
public List<UserPayment> getUserPaymentList() {
return userPaymentList;
}
public void setUserPaymentList(List<UserPayment> userPaymentList) {
this.userPaymentList = userPaymentList;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
userRoles.forEach(ur -> authorities.add(new auth(ur.getRole().getName())));
return authorities;
}
#Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled()
{
return enabled;
}
}
User Service
package com.eshop.service;
import java.util.Set;
import com.eshop.domian.UserBilling;
import com.eshop.domian.UserPayment;
import com.eshop.domian.UserShipping;
import com.eshop.domian.user;
import com.eshop.security.PasswordResetToken;
import com.eshop.security.UserRole;
public interface UserService {
PasswordResetToken getPasswordResetToken(final String token);
void createPasswordResetTokenForUser(final user user, final String token);
user findByUsername(String username);
user findByEmail(String email);
user findById(Long Id);
user createUser(user user, Set<UserRole> userRoles) throws Exception;
user save(user user);
void updateUserBilling(UserBilling userBilling, UserPayment userPayment, user user);
void setUserDefaultPayment(Long userPaymentId, user user);
void updateUserShipping(UserShipping userShipping, user user);
void setUserDefaultShipping(Long userShippingId, user user);
}
User Service Implementation
package com.eshop.service.impl;
#Service
public class UserServiceImpl implements UserService{
private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
#Autowired
private PasswordResetTokenRepository passwordResetTokenRepository;
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
private UserPaymentRepository userPaymentRepository;
#Autowired
private UserShippingRepository userShippingRepository;
#Override
public PasswordResetToken getPasswordResetToken(final String token) {
return passwordResetTokenRepository.findByToken(token);
}
#Override
public void createPasswordResetTokenForUser(final user user, final String token) {
final PasswordResetToken myToken = new PasswordResetToken(token, user);
passwordResetTokenRepository.save(myToken);
}
#Override
public user findByUsername(String username) {
// TODO Auto-generated method stub
return userRepository.findByusername(username);
}
#Override
public user findById(Long id) {
return userRepository.findById(id).get();
}
#Override
public user findByEmail(String email) {
// TODO Auto-generated method stub
return userRepository.findByEmail(email);
}
}
Here you try to access the id field of the user model attribute:
<input type="hidden" name="id" th:value="${user.id}" />
Here you set the user model attribute to true, therefore it's of type boolean:
model.addAttribute("user", true);
As a variable of type boolean does not have a field called id, trying to access it gives the error you see. I assume what's going on is that you didn't want to set that model attribute to true (perhaps you wanted to set it to currentUser?), or that the id field that you want to access belongs to another model attribute.
I am trying to add 2 values "name" and "city" to my 2 tables using #OneToOne. I think I write incomplete code at #Controller and wrong at Thymeleaf code. Help me . Thanks very much
Student.java
package com.example.demo.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "student_id")
private long studentId;
#Column(name = "name")
private String name;
#OneToOne
#JoinColumn(name = "home_address_id")
private Address address;
public long getStudentId() {
return studentId;
}
public void setStudentId(long studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java
package com.example.demo.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "address")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "address_id")
private long addressId;
#Column(name = "city")
private String city;
public long getAddressId() {
return addressId;
}
public void setAddressId(long addressId) {
this.addressId = addressId;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
StudentRepository.java
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.models.Student;
public interface StudentRepository extends JpaRepository<Student, Long> {
Student findByName (String name);
}
StudentService.java
package com.example.demo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.models.Student;
import com.example.demo.repository.StudentRepository;
#Service
public class StudentService {
#Autowired
private StudentRepository studentRepository;
public List<Student> findAll (){
return studentRepository.findAll();
}
public Student findByName (String name) {
return studentRepository.findByName(name);
}
public Student save (Student student) {
return studentRepository.save(student);
}
}
StudentController.Java
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import com.example.demo.models.Student;
import com.example.demo.service.StudentService;
#Controller
public class StudentController {
#Autowired
private StudentService studentService;
#GetMapping("/all")
public ModelAndView getAll (ModelAndView modelAndView, Student student) {
modelAndView.addObject("student", studentService.findAll());
modelAndView.setViewName("all");
return modelAndView;
}
#GetMapping("/add")
public ModelAndView add (ModelAndView modelAndView, Student student) {
modelAndView.addObject("add", student);
modelAndView.setViewName("add");
return modelAndView;
}
#PostMapping("/add")
public ModelAndView postAdd (ModelAndView modelAndView, Student student) {
Student existStudent= studentService.findByName(student.getName());
if (existStudent!=null) {
modelAndView.setViewName("add");
}
else {
studentService.save(student);
modelAndView.setViewName("success");
}
return modelAndView;
}
}
add.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Add</title>
</head>
<body>
<center>
<form action="#" th:action="#{/add}" th:object="${add}" method="post">
<table>
<tr>
<td><label for="name">Name</label></td>
<td><input th:field="*{name}" type="text" name="name"></input></td>
</tr>
<tr>
<td><label for="city">City</label></td>
<td><input th:field="*{address.city}" type="text" name="address.city"></input>
</td>
</tr>
<tr>
<td><input type="submit" value="Submit"></input></td>
</tr>
</table>
</form>
</center>
</body>
</html>
student.sql
create table student (
student_id BIGINT NOT NULL AUTO_INCREMENT,
home_address_id BIGINT NOT NULL,
name VARCHAR(30) NOT NULL,
PRIMARY KEY (student_id),
CONSTRAINT student_address FOREIGN KEY (home_address_id) REFERENCES ADDRESS ( address_id)
);
Address.sql
create table ADDRESS (
address_id BIGINT NOT NULL AUTO_INCREMENT,
city VARCHAR(30) NOT NULL,
PRIMARY KEY (address_id)
);
I think I am wrong and may write incomplete. If possible, rewrite code snippets I need to fix or add. Thanks very much
I'm new to Spring and trying to build a sample application. In this I have a Company(OwnerCompany) which can have multiple locations(OwnerCompanyOffices). I am trying to save the company and it multiple locations at the same time using same JSP page.I'm not able to get proper data from my JSP page to the spring controller. My Hibernate logs are like this
OwnerCompanyOffices [id=0, name=null, location=null, ownerCompany=null]
Hibernate: insert into owner_company_offices (location, name, owner_company_id) values (?, ?, ?)
Here is my code
My OwnerCompany Entity OwnerCompany.java
package com.sachinmukherjee.spring_hibernate.entity;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "owner_company")
public class OwnerCompany {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name="name")
private String name;
#Column(name = "short_name")
private String short_name;
#OneToMany(mappedBy = "owner_company",cascade = CascadeType.REMOVE,fetch = FetchType.LAZY)
private Set<Users> users;
#OneToMany(mappedBy = "ownerCompany", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
private List<OwnerCompanyOffices> ownerCompanyOffices;
public OwnerCompany() {
super();
// TODO Auto-generated constructor stub
}
public OwnerCompany(String name, String short_name) {
this.name = name;
this.short_name = short_name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getShort_name() {
return short_name;
}
public void setShort_name(String short_name) {
this.short_name = short_name;
}
public Set<Users> getUsers() {
return users;
}
public void setUsers(Set<Users> users) {
this.users = users;
}
public List<OwnerCompanyOffices> getOwnerCompanyOffices() {
return ownerCompanyOffices;
}
public void setOwnerCompanyOffices(List<OwnerCompanyOffices> ownerCompanyOffices) {
this.ownerCompanyOffices = ownerCompanyOffices;
}
#Override
public String toString() {
return "OwnerCompany [id=" + id + ", name=" + name + ", short_name=" + short_name + ", users=" + users
+ ", ownerCompanyOffices=" + ownerCompanyOffices + "]";
}
public void addOwnerCompanyOffices(OwnerCompanyOffices ownerCompanyOffice) {
if(ownerCompanyOffices == null) {
ownerCompanyOffices = new ArrayList<OwnerCompanyOffices>();
}
ownerCompanyOffices.add(ownerCompanyOffice);
ownerCompanyOffice.setOwnerCompany(this);
}
}
My OwnerCompanyOffices Entity OwnerCompanyOffices.java
package com.sachinmukherjee.spring_hibernate.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="owner_company_offices")
public class OwnerCompanyOffices {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "name")
private String name;
#Column(name="location")
private String location;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "owner_company_id")
private OwnerCompany ownerCompany;
public OwnerCompanyOffices() {
super();
// TODO Auto-generated constructor stub
}
public OwnerCompanyOffices(String name, String location) {
this.name = name;
this.location = location;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public OwnerCompany getOwnerCompany() {
return ownerCompany;
}
public void setOwnerCompany(OwnerCompany ownerCompany) {
this.ownerCompany = ownerCompany;
}
#Override
public String toString() {
return "OwnerCompanyOffices [id=" + id + ", name=" + name + ", location=" + location + ", ownerCompany="
+ ownerCompany + "]";
}
}
My OwnerCompanyOfficesDAO class OwnerCompanyOfficesDAOImp
package com.sachinmukherjee.spring_hibernate.dao;
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.sachinmukherjee.spring_hibernate.entity.OwnerCompanyOffices;
#Repository
public class OwnerCompanyOfficesDAOImp implements OwnerCompanyOfficesDAO {
#Autowired
SessionFactory sessionFactory;
public List<OwnerCompanyOffices> getAllOffices() {
// TODO Auto-generated method stub
return null;
}
#Transactional
public void saveOffice(OwnerCompanyOffices ownerCompanyOffice) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(ownerCompanyOffice);
}
}
My OwnerCompanyController Class OwnerCompanyController
package com.sachinmukherjee.spring_hibernate.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.ui.Model;
import com.sachinmukherjee.spring_hibernate.dao.OwnerCompanyDAO;
import com.sachinmukherjee.spring_hibernate.dao.OwnerCompanyOfficesDAO;
import com.sachinmukherjee.spring_hibernate.entity.OwnerCompany;
import com.sachinmukherjee.spring_hibernate.entity.OwnerCompanyOffices;
#Controller
#RequestMapping("/owner_company/")
public class OwnerCompanyController {
#Autowired
private OwnerCompanyDAO ownerCompanyDAO;
#Autowired
private OwnerCompanyOfficesDAO ownerCompanyOfficesDAO;
#GetMapping("/add/")
public String add(Model model) {
OwnerCompanyOffices ownerCompanyOffices = new OwnerCompanyOffices();
model.addAttribute("ownerCompanyOffices", ownerCompanyOffices);
return "owner_company/add";
}
#PostMapping("/submit")
public String submit(#ModelAttribute("ownerCompanyOffices") OwnerCompanyOffices ownerCompanyOffices) {
System.out.println(ownerCompanyOffices);
ownerCompanyOfficesDAO.saveOffice(ownerCompanyOffices);
return "redirect:/owner_company/";
}
}
My add.jsp page where I'm entering the ownercompany and ownercompanyoffices data
<div class="row">
<div class="col-md-12">
<form action="${pageContext.request.contextPath}/owner_company/submit/" method="POST" modelAttribute="ownerCompanyOffices" class="form-control">
<label>Name</label>
<input name="ownerCompanyOffices.ownerCompany.name" required="required"/>
</br></br>
<label>Short Name</label>
<input name="ownerCompanyOffices.ownerCompany.short_name" type="text" />
</br></br>
<table class="table table-responsive">
<thead>
<tr>
<th>Name</th>
<th>Location</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr class="toClone">
<td><input type="text" name="ownerCompanyOffices.name" required="required"/></td>
<td><input type="text" name="ownerCompanyOffices.location" required="required"/></td>
<td class="remove"></td>
</tr>
<tr id="addRow">
<td></td>
<td></td>
<td>Add More
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-success">Save</button>
</form>
</div>
</div>
</body>
</html>
<script type="text/javascript">
$(document).on("click",".addMore", function(){
var clonedRow = $(".toClone:first").clone();
$(clonedRow).find("input").each(function(){
$(this).val("");
});
$(clonedRow).addClass("toRemove");
$(clonedRow).find(".remove").addClass("removeRow");
$(clonedRow).find(".remove").html("<a href='#'>Remove</a>");
$(clonedRow).insertBefore($("#addRow"));
});
$(document).on("click",".removeRow", function(){
$(this).closest("tr").remove();
});
</script>
Here By clicking on add more link user can add multiple offices against a single company.
My English is not very well, so sorry for mistakes.
I'am using a Spring, Spring MVC, Hibernate, Spring Data.
I have two entities Customer and CustomerDetails I would like to connect/bind them.
I'am using #OneToOne annotation, but I have no idea how to set a customer for CusomerDetails and vice versa. I found that I should create Customer and CustomerDetails in controller, and there connect them, but it is not working and I think that it is a bad approach. Anyone knows How should it looks?
Thanks for help.
Customer class:
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="customer")
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="customer_id")
private int id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
#Column(name="address")
private String address;
#OneToOne(cascade=CascadeType.ALL)
private CustomerDetails customerDetails;
public Customer() {
}
public Customer(CustomerDetails customerDetails)
{
this.customerDetails=customerDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public CustomerDetails getCustomerDetails() {
return customerDetails;
}
public void setCustomerDetails(CustomerDetails customerDetails) {
this.customerDetails = customerDetails;
}
#Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", address=" + address
+ ", customerDetails=" + customerDetails + "]";
}
}
CustomerDetails:
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="customer_details")
public class CustomerDetails {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name="surname")
private String lastName;
#Column(name="number")
private int number;
#OneToOne(cascade= {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH})
private Customer customer;
public CustomerDetails() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
#Override
public String toString() {
return "CustomerDetails [id=" + id + ", lastName=" + lastName + ", number=" + number + ", customer=" + customer
+ "]";
}
}
Services:
import java.util.List;
import com.firstapp.entity.Customer;
public interface CustomerService {
public List<Customer>getCustomers();
public Customer getCustomer(int id);
public void saveCustomer(Customer customer);
public void deleteCustomer(int id);
public List<Customer>search(String keyword);
}
public interface CustomerDetailsService {
public List<CustomerDetails> getCustomers();
public CustomerDetails getCustomer(int id);
public void saveCustomer(CustomerDetails customer);
public void deleteCustomer(int id);
}
#Service
public class CustomerServiceImpl implements CustomerService {
#Autowired
private CustomerRepository repo;
public List<Customer> getCustomers() {
return repo.findAll();
}
public Customer getCustomer(int id) {
Optional<Customer>result= repo.findById(id);
return result.get();
}
public void saveCustomer(Customer customer) {
repo.save(customer);
}
public void deleteCustomer(int id) {
repo.deleteById(id);
}
public List<Customer>search(String keyword)
{
return repo.search(keyword);
}
}
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.firstapp.entity.CustomerDetails;
import com.firstapp.repository.CustomerDetailsRepository;
#Service
public class CustomerDetailsServiceImpl implements CustomerDetailsService{
#Autowired
private CustomerDetailsRepository repo;
public List<CustomerDetails> getCustomers() {
return repo.findAll();
}
public CustomerDetails getCustomer(int id) {
return repo.findById(id).get();
}
public void saveCustomer(CustomerDetails customer) {
repo.save(customer);
}
public void deleteCustomer(int id) {
repo.deleteById(id);
}
}
Repositories:
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.firstapp.entity.Customer;
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
#Query(value="SELECT c from Customer c where c.name LIKE '%'|| :keyword || '%'"
+ "OR c.email LIKE '%'|| :keyword || '%'"
+ "OR c.address LIKE '%'|| :keyword || '%'")
public List<Customer>search(#Param("keyword")String keyword);
}
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.firstapp.entity.CustomerDetails;
#Repository
public interface CustomerDetailsRepository extends JpaRepository<CustomerDetails, Integer> {
}
My controller:
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.firstapp.entity.Customer;
import com.firstapp.entity.CustomerDetails;
import com.firstapp.service.CustomerDetailsService;
import com.firstapp.service.CustomerDetailsServiceImpl;
import com.firstapp.service.CustomerService;
import com.firstapp.service.CustomerServiceImpl;
#Controller
#RequestMapping("/customer")public class CustomerController {
#Autowired
private CustomerService service;
#Autowired
private CustomerDetailsService serviceCD;
#GetMapping("/home")public String home(Model model)
{
List<Customer>customers=service.getCustomers();
model.addAttribute("message","Hello from Spring MVC"); model.addAttribute("customers",customers);
return "home-page";
}
#GetMapping("/showForm")
public String showForm(Map<String,Object>model)
{
Customer customer=new Customer();
CustomerDetails cd=new CustomerDetails();
customer.setCustomerDetails(cd);
model.put("customer",new Customer());
model.put("customerDetails", cd);
return "new-customer";
}
#PostMapping("/add")
public String addCustomer(#ModelAttribute("customer") Customer customer)
{
service.saveCustomer(customer);
return "redirect:/customer/addDetails";
}
#RequestMapping("/addDetails")
public String addCustomerDetails(#ModelAttribute("customerDetails") CustomerDetails customerDt)
{
serviceCD.saveCustomer(customerDt);
return "redirect:/customer/home";
}
#GetMapping("/edit")
public String editCustomer(#RequestParam int id, Model model)
{
Customer customer=service.getCustomer(id);
model.addAttribute("customer",customer);
return "edit-customer";
}
#GetMapping("/delete")
public String deleteCustomer(#RequestParam int id)
{
service.deleteCustomer(id);
return "redirect:/customer/home";
}
#GetMapping("/search")
public String search(#RequestParam String keyword,Model model)
{
List<Customer>customers=service.search(keyword);
model.addAttribute("customers",customers);
return "search-page";
}
}
my jsp:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Customer registration</title>
</head>
<body>
<div align="center">
<h2>New Customer</h2>
<form:form action="add" method="post" modelAttribute="customer">
<table>
<tr>
<td>Name:</td>
<td><form:input path="name"/></td>
</tr>
<tr>
<td>E-mail:</td>
<td><form:input path="email"/></td>
</tr>
<tr>
<td>Address:</td>
<td><form:input path="address"/></td>
</tr>
<tr>
<td></td><td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</div>
</body>
</html>
Set the CustomerDetails for Customer:
customer.setCustomerDetail(customerDetail);
customerDetail.setCustomer(customer);
It's enough. Spring JPA automatically sets references and id's between table entities.
In additional try to change model layer:
1) First what you should to change - add the mappedBy parameter with table name into '#OneToOne'
2) Use #JoinColumn for one of entity:
for Customer:
#OneToOne(mappedBy = "customer")
#JoinColumn(name = "customer_details_id", referencedColumnName = "id")
for CustomerDetails:
#OneToOne(mappedBy = "customer_detail")
in additional: try to save CustomerDetail entity into table after creating, but before saving a Customer.
PS
Does no matter technically where are you create entities - it is just patterns and SOLID principals.
All parameters in #OneToOne and #JoinColumn should be named as fields in entity and as tables. Once I had a very difficult and long resolving with this issue. So be precise.
What am I doing wrong here?
i get this error...
Failed to convert property value of type java.lang.String to required type com.akybenko.entity.Department for property department; nested exception is java.lang.IllegalStateException: Cannot convert value of type java.lang.String to required type com.akybenko.entity.Department for property department: no matching editors or conversion strategy found
please help me solve this..
EmployeeController.java
package com.akybenko.controller;
import java.beans.PropertyEditorSupport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.akybenko.entity.Department;
import com.akybenko.entity.Employee;
import com.akybenko.service.DepartmentService;
import com.akybenko.service.EmployeeService;
#Controller
#RequestMapping("/employee")
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#Autowired
private DepartmentService departmentService;
class EmployeeEditor extends PropertyEditorSupport {
#Override
public void setAsText(String text) throws IllegalArgumentException {
int id = Integer.parseInt(text);
Employee employee = employeeService.get(id);
setValue(employee);
}
}
#InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
binder.registerCustomEditor(Employee.class, new EmployeeEditor());
}
#GetMapping("/list")
public String listEmployees(Model model) {
List<Employee> employees = employeeService.getAll();
model.addAttribute("employees", employees);
return "list-employees";
}
#GetMapping("/add")
public String getAddEmployee(Model model) {
model.addAttribute("addEmployee", new Employee());
model.addAttribute("listDept", departmentService.getAll());
return "addEmployee";
}
#PostMapping("/add")
public String add(
#ModelAttribute("addEmployee") Employee employee,
BindingResult result,
Model model) {
if (result.hasErrors()) {
return "addEmployee";
}
employeeService.add(employee);
return "redirect:/employee/list";
}
}
addEmployee.jsp
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%# page import="com.akybenko.entity.Department" %>
<!DOCTYPE html>
<html>
<head>
<title>Add Employee</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/addEmployee.css" />
</head>
<body>
<div id = "wrapper">
<div id = "header">
<h2>ADD EMPLOYEE</h2>
</div>
</div>
<div id = "container">
<form:form action="add" modelAttribute="addEmployee" method="post">
<div class="row">
<label for="employeeId">ID</label>
<div>
<form:input path="employeeId"/>
</div>
</div>
<div class="row">
<div>
<label for="employeeLastName">Last Name</label>
<div>
<form:input path="employeeLastName"/>
</div>
</div>
</div>
<div class="row">
<div>
<label for="employeeFirstName">First Name</label>
<div>
<form:input path="employeeFirstName"/>
</div>
</div>
</div>
<div class="row">
<div>
<label for="department">Department</label>
<div>
<form:select path="department">
<form:option value="NONE">---SELECT---</form:option>
<form:options items="${listDept}" itemLabel="departmentName" itemValue="departmentId" />
</form:select>
</div>
<div>
<form:errors path="department" />
</div>
</div>
</div>
<div><input type="submit" value="Save" id="buttonSave"/> </div>
<div><input type="reset" value="Reset" id="buttonReset"/></div>
</form:form>
</div>
</body>
</html>
Employee.java
package com.akybenko.entity;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="employee")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMP_SEQUENCE")
#SequenceGenerator(name="EMP_SEQUENCE", sequenceName="employee_seq", allocationSize=1)
#Column(name="employee_id")
private int employeeId;
#Column(name="employee_lname")
private String employeeLastName;
#Column(name="employee_fname")
private String employeeFirstName;
#ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JoinColumn(name="department_id", referencedColumnName="department_id", nullable = false, insertable = false, updatable = false)
private Department department;
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeLastName() {
return employeeLastName;
}
public void setEmployeeLastName(String employeeLastName) {
this.employeeLastName = employeeLastName;
}
public String getEmployeeFirstName() {
return employeeFirstName;
}
public void setEmployeeFirstName(String employeeFirstName) {
this.employeeFirstName = employeeFirstName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
#Override
public String toString() {
return "Employee [employeeId=" + employeeId + ", employeeLastName=" + employeeLastName + ", employeeFirstName="
+ employeeFirstName + ", department=" + department + "]";
}
}
Department.java
package com.akybenko.entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="department")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DEPT_SEQUENCE")
#SequenceGenerator(name="DEPT_SEQUENCE", sequenceName="department_seq", allocationSize=1)
#Column(name="department_id")
private int departmentId;
#Column(name="department_name")
private String departmentName;
#OneToMany(mappedBy="department", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<Employee> employees;
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
#Override
public String toString() {
return "Department [departmentId=" + departmentId + ", departmentName=" + departmentName + ", employees="
+ employees + "]";
}
}
What am I doing wrong here?
Department is the reference table. Better to remove employees from it.
Please, add classes DepartmentDto, EmployeeDto and use them on the web tier.
In the EmployeeService#add() method:
Get departmentId from EmployeeDto.
Check that department with departmentId exists in the database, if there is not such department generate exception that can be converted to 404 HTTP error.
Convert EmployeeDto to the Employee and set Department to the Employee (you can use load() method for that, or create a fake department with the departmentId only.