I've got problem with my entities. I've trade to make many-to-one connection between this two entities. I'm doing it like that:
User user = new User();
user.setName("a");
user.setLastName("b");
Set<Adress> a = new HashSet<Adress>();
Adress a1 = new Adress();
Adress a2 = new Adress();
a1.setCity("a1");
a2.setCity("a2");
a.add(a1);
a.add(a2);
user.setAdress(a);
userProxy.save(user);
My entites:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
#NotNull
private String name;
#NotNull
private String lastName;
#OneToMany(mappedBy="user", cascade=CascadeType.ALL)
private Set<Adress> adress = new HashSet<Adress>();
public User(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}
public User() {
}
public Set<Adress> getAdress() {
return adress;
}
public void setAdress(Set<Adress> adress) {
this.adress = adress;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Long getId() {
return id;
}
}
Second Entity
#Entity
public class Adress {
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
private Long id;
private String city;
#ManyToOne
#JoinColumn(name="user_id")
private User user;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Long getId() {
return id;
}
}
Data in table User saves fine, but in table adress field user_id is "NULL" can anyone explain to me why is that? I've tried a lots of combinations with #ManyToOne but nothing worked for me.
For more details UserProxy:
#Service
public class UserProxyDao {
private UserDao userDao;
#Autowired
public UserProxyDao(UserDao userDao) {
this.userDao = userDao;
}
public void save(User user) {
userDao.save(user);
}
}
however if i put #NotNull on field user in Adress entity validation fails... I really dont know why is that
Caused by: javax.validation.ConstraintViolationException: validation failed for classes [pl.rd.j2ee.api.domain.Adress] during persist time for groups [javax.validation.groups.Default, ]
You should be able to do this in one action as long as you do this first.
a1.setUser(user);
a2.setUser(user);
You could always add User to your Address constructor and do it there.
public Address (User user) {
this.user = user;
}
Related
I am trying to validate that if the email exists in my database, the error message will come out instead of the White Error Page.
I tried using this link but it is not working for me. Below are my codes.
Codes for Model Class
public class Employee {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email", unique = true)
#Email
private String email;
#Column(name = "posit")
private String position;
#Column(name = "mobile")
private String phone_num;
public Employee() {}
public Employee(String firstName, String lastName, String email, String position, String phone_num) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phone_num = phone_num;
this.position = position;
}
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 getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone_num() {
return phone_num;
}
public void setPhone_num(String phone_num) {
this.phone_num = phone_num;
}
}
Codes for EmployeeServiceInterface
public interface EmployeeService {
Employee save(Employee employee);
}
Codes for EmployeeServiceImplementation
#Service
public class EmployeeServiceImpl implements EmployeeService{
#Autowired
private EmployeeRepository employeeRepository;
#Override
public Employee save(Employee employee) {
this.employeeRepository.save(employee);
return employee;
}
public boolean exist(String email){
return employeeRepository.existsByEmail(email);
}
Controller
#Controller
public class EmployeeRegistrationController {
#Autowired
private EmployeeService employeeService;
private EmployeeServiceImpl employeeImpl;
#PostMapping("/saveEmployee")
public String saveEmployee(#ModelAttribute("employee") Employee employee) {
// save employee to database
employeeService.save(employee);
if(employeeService.exist==true){
return "User already exist";
}
return "success";
}
}
when i updating the records via postman record not updating it will create a new record i don't know why.i attached screenshot below along with code what i tried so far.i have attched the controller,service,
entity,repository.
i am tring this since yesterday problem not solved please some one will help me to solve
enter image description here
EmployeeController
#PutMapping("/edit/{id}")
private Employee update(#RequestBody Employee employees,#PathVariable(name = "id") long id)
{
Employee emp = services.get(id);
services.saveOrUpdate(emp);
return employees;
}
Services
//updating a record
//updating a record
public void update(Employee employees, int id)
{
repo.save(employees);
}
Repository
#Repository
public interface EmployeeRepository extends CrudRepository<Employee,Long> {
}
Entity
#Entity
#Table(name="Records")
public class Employee {
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name="fname")
private String fname;
#Column(name="lname")
private String lname;
#Column(name="city")
private String city;
#Column(name="phone")
private String phone;
#Column(name="salary")
private String salary;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
}
This an example of UPDATE and it worked for me.
//HTTP PUT
#PutMapping("/owners/{id}")
public void updateOwner(#RequestBody Owner owner, #PathVariable int id) {
owner.setId(id);
ownerRepos.save(owner);
}
I used the CrudRepository too.
Also I notice that you call services.saveOrUpdate(emp) but at the same time you showed us "public void update(Employee employees, int id)" below. If'd better if you could show the definition of the method saveOrUpdate()
SaveOrUpdate uses the ID of the object to determine if the object is the same or new. When updating, you're not considering the ID of the employee. You should first fetch the Object from DB and update the same object. The updates should take place on a persistent object
I have two entities Employee and Address.
Employee.java
public class Employee {
private Long id;
private String firstName;
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;
}
}
Address.java
public class Address {
public Address(Long addressId, String address, Long id) {
this.addressId = addressId;
this.address = address;
this.id = id;
}
public Address() {
}
#Id
private Long addressId;
private Long employeeId;
private String address;
public Long getAddressId() {
return addressId;
}
public void setAddressId(Long addressId) {
this.addressId = addressId;
}
public Long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Long employeeId) {
this.employeeId= employeeId;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Useing Javers api i want all the changes made by Employee including Address.
suppose employeeId e1 with name e made some change in address a1 with address xyz and employeeId e1
Changes changes = javers.findChanges(QueryBuilder.byInstanceId(id,com.mybatis.emo.bean.Employee.class).withNewObjectChanges(true).build());
I want address changes also comes while querying employee.
i am try to create a one to many bidirectional mapping using spring boot and spring data jpa please look the below entity
Employer Entity
#Entity
public class Employer
{
private Long id;
private String employerName;
private List<Employee> employees;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getEmployerName()
{
return employerName;
}
public void setEmployerName(String employerName)
{
this.employerName = employerName;
}
#OneToMany(cascade=CascadeType.ALL, mappedBy="employer")
public List<Employee> getEmployees()
{
return employees;
}
public void setEmployees(List<Employee> employees)
{
this.employees = employees;
}
}
Employee Entity
#Entity
public class Employee
{
private Long id;
private String employeeName;
private Employer employer;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getEmployeeName()
{
return employeeName;
}
public void setEmployeeName(String employeeName)
{
this.employeeName = employeeName;
}
#ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
public Employer getEmployer()
{
return employer;
}
public void setEmployer(Employer employer)
{
this.employer = employer;
}
}
Employer Repo
public interface EmployerServices extends JpaRepository<Employer, Long> {
}
Employee Repo
public interface EmployeeServices extends JpaRepository<Employee, Long> {
}
REST Controller is
#RestController
public class Controller {
#Autowired EmployeeServices employeeServices;
#Autowired EmployerServices employerServices;
#GetMapping("/getempr")
public Object getempr(){
return employerServices.findOne(1L);
}
}
now the problem begin start see my out put
its look like a infighting loop and my server throwing error getOutputStream() has already been called for this response.
I used #JsonBackReference & #JsonManagedReference
annotation but the problem is its working like one to many
{
"id":1,
"employerName":"employer",
"employees":[
{"id":1,"employeeName":"emp1"},
{"id":2,"employeeName":"emp2"}
]
}
if I am trying to get in the concern of many to one like all employee with employer. the output is
[
{
"id":1,
"employeeName":"emp1"
},
{
"id":2,
"employeeName":"emp2"}
]
its not showing me the employer details.
please suggets me guys what i am doing wrong. thanks in advance!!
Instead of using #JsonBackReferenceand #JsonManagedReference try to use annotation #JsonIgnoreProperties:
#JsonIgnoreProperties("employer")
private List<Employee> employees;
#JsonIgnoreProperties("employees")
private Employer employer;
It prevents Jackson from rendering a specified properties of associated objects.
with the JSON its a problem with bi-directional mapping. Use the below properties.
#JsonIgnoreProperties("employer")
#JsonIgnoreProperties("employees")
please keep fetching type as eager.
hope this will work.
You can solve your issue with two modification with annotations.
Employer.class
#Entity
public class Employer {
private Long id;
private String employerName;
#OneToMany(cascade = CascadeType.ALL,
mappedBy = "employer",
orphanRemoval = true)
private List<Employee> employees;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmployerName() {
return employerName;
}
public void setEmployerName(String employerName) {
this.employerName = employerName;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
Employee.class
#Entity
public class Employee {
private Long id;
private String employeeName;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "employer_id")
private Employer employer;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public Employer getEmployer() {
return employer;
}
public void setEmployer(Employer employer) {
this.employer = employer;
}
}
For more information please visit this link.
Change your getEmployer Method like this:
#ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
public Employer getEmployer()
{
return employer;
}
use
#JsonProperty(access = Access.WRITE_ONLY)
private List<Employee> employees;
So that it will ignore employees while printing to JSON in the response (and thus prevents the looping), but will still consider the JSON data (employee list) you pass in the request body so that it is available for persistence.
the user entity
import javax.persistence.*;
#Entity
public class User {
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private Integer age;
#Embedded
private Address address;
public User(){}
public User(String name, Integer age,Address address) {
this.name = name;
this.age = age;
this.address = address;
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
and the address entity
#JsonInclude(JsonInclude.Include.NON_NULL)
#Embeddable
public class Address {
private String city;
public Address() {
}
public Address( String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
the controller code
#ResponseStatus(HttpStatus.CREATED)
#RequestMapping(value = "users", method = RequestMethod.POST)
public void users(#RequestBody List<User> users) {
this.userRepository.save(users);
}
when i post json data with psot man, the data is
[
{
"name":"yaohao",
"age":11,
"address":{
"city":"nantong"
}
},
{
"name":"yh",
"age":11,
"address":{
"city":"nantong"
}
}
]
the address always null
when the user entity has no #Embedded address entity,the code works fine,so how can i post json data to controller when i use #Embedded annotations
It has nothing to do with the use of #Embedded. When doing the marshaling Jackson uses Java Bean properties to set the values and as your User class is lacking a getAddress and setAddress Jackson simply ignores it because it doesn't exists.
To fix add the getter and setter for Address.
Or instead of using property access switch your mapper to use field access. See how to specify jackson to only use fields - preferably globally for more information on that.