Company Entity
@Entity @Table(name="company") public class Company implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private int id; @Column(name="company_id") private int cmpId; @Column(name="company_name") private String companyName; @OneToOne(fetch=FetchType.LAZY, mappedBy="company") private Employee employee; }
Employee Entity
@Entity @Table(name="employee") public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private int id; @Column(name="emp_id") private int empId; @Column(name="emp_name") private String empName; @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name="cmp_id", referencedColumnName="company_id") private Company company; }
Company Service
@Service public class CompanyService { @Autowired private CompanyRepository companyRepo; public Company fetchCompany(int cmpId){ System.out.println("11111111111111111"); return companyRepo.findByCmpId(cmpId); } }
Company Repo
public interface CompanyRepository extends JpaRepository<Company, Integer>{ @Query(value="select a from Company a join fetch a.employee where a.cmpId = ?1") public Company findByCmpId(int cmpId); }
API
@RequestMapping("/cmp/{cmpId}") public void findCmp(@PathVariable int cmpId){ Company cmp = cmpService.fetchCompany(cmpId); System.out.println(cmp.getEmployee().getEmpName()); }
Issue is when I am trying to execute my code, I am getting following error:
Hibernate: select company0_.id as id1_1_0_, employee1_.id as id1_2_1_, company0_.company_id as company_2_1_0_, company0_.company_name as company_3_1_0_, employee1_.cmp_id as cmp_id4_2_1_, employee1_.emp_id as emp_id2_2_1_, employee1_.emp_name as emp_name3_2_1_ from company company0_ inner join employee employee1_ on company0_.id=employee1_.cmp_id where company0_.company_id=? 2017-04-21 17:22:11.386 ERROR 10766 --- [nio-8105-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Error accessing field [private int com.example.domain.Company.cmpId] by reflection for persistent property [com.example.domain.Company#cmpId] : 1; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private int com.example.domain.Company.cmpId] by reflection for persistent property [com.example.domain.Company#cmpId] : 1] with root cause java.lang.IllegalArgumentException: Can not set int field com.example.domain.Company.cmpId to java.lang.Integer at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_91] at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_91] at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58) ~[na:1.8.0_91] at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:56) ~[na:1.8.0_91] at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:36) ~[na:1.8.0_91] at java.lang.reflect.Field.get(Field.java:393) ~[na:1.8.0_91]
How to fix this? Also when I have removed referenceColumnName, then the error is removed but them it is joining with primary key of company class, which I dont want.?
3 Answers
Answers 1
Exception :
IllegalArgumentException: Can not set int field com.example.domain.Company.cmpId to java.lang.Integer
Please use Integerinstead
of int
in Company as we as in Employee entity if id field.
@Id @GeneratedValue private Integer id;
Also please provide getter and setter methods for fields in your entity.
Answers 2
**Can not set int field com.example.domain.Company.cmpId to java.lang.Integer** Hibernate except foreign key of employee table cmp_id, should be primary key of company. But in your code cmpId is not primary key. @Column(name="company_id") private int cmpId; Please make that primary and check once. Edited:- 1. @OneToOne(fetch=FetchType.LAZY, mappedBy="company") private Employee employee; change to:- @OneToOne(fetch=FetchType.LAZY, mappedBy="company",optional=false) private Employee employee; 2. @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name="cmp_id", referencedColumnName="company_id") private Company company; change to:- @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name="cmp_id") private Company company;
Answers 3
This looks a bit funky, but I believe it works the way you requested.
Company
@Entity @Table(name = "company") public class Company implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; @Column(name = "comp_id") private Integer compId; @Column(name = "company_name") private String companyName; @OneToOne @JoinColumn(name="emp_id", referencedColumnName="emp_id") private Employee employee; @PostPersist public void postPersist() { if (id != null && compId == null) { setCompId(new Integer(id)); } } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public Integer getCompId() { return compId; } public void setCompId(Integer compId) { this.compId = compId; } }
CompanyRepository
public interface CompanyRepository extends JpaRepository<Company, Integer> { @Query(value = "select a from Company a join fetch a.employee as emp where a.compId = ?1") public Company findByCmpId(int cmpId); }
CompanyService
@Service public class CompanyService { @Autowired private CompanyRepository companyRepo; public Company fetchCompany(int cmpId) { return companyRepo.findByCmpId(cmpId); } }
Employee
@Entity @Table(name = "employee") public class Employee implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Integer id; @Column(name = "emp_id") private Integer empId; @Column(name = "emp_name") private String empName; @OneToOne @JoinColumn(name="comp_id", referencedColumnName="comp_id") private Company company; @PostPersist public void postPersist() { if (id != null && empId == null) { setEmpId(new Integer(id)); } } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getEmpId() { return empId; } public void setEmpId(Integer empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } }
EmployeeRepository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> { @Query(value = "select a from Employee a join fetch a.company as comp where a.empId = ?1") public Employee findByEmpId(int cmpId); }
EmployeeService
@Service public class EmployeeService { @Autowired private EmployeeRepository employeeRepo; public Employee fetchEmployee(int empId) { return employeeRepo.findByEmpId(empId); } }
Unit Tests
@RunWith(SpringRunner.class) @SpringBootTest public class RnlApplicationTests { @Autowired CompanyService companyService; @Autowired EmployeeService employeeService; @Autowired CompanyRepository companyRepository; @Autowired EmployeeRepository employeeRepository; @Before public void setup() { Employee employee = new Employee(); employee.setEmpName("Test Employee"); Company company = new Company(); company.setCompanyName("Test Company"); company = companyRepository.save(company); employee.setCompany(company); employee = employeeRepository.save(employee); company.setEmployee(employee); company = companyRepository.save(company); Employee employee2 = new Employee(); employee2.setEmpName("Test Employee2"); Company company2 = new Company(); company2.setCompanyName("Test Company2"); company2 = companyRepository.save(company2); employee2.setCompany(company2); employee2 = employeeRepository.save(employee2); company2.setEmployee(employee2); company2 = companyRepository.save(company2); } @Test public void testRepository() { Company company = companyService.fetchCompany(1); assertThat(company).isNotNull(); Company company2 = companyService.fetchCompany(2); assertThat(company2).isNotNull(); Employee employee = employeeService.fetchEmployee(1); assertThat(employee).isNotNull(); Employee employee2 = employeeService.fetchEmployee(2); assertThat(employee2).isNotNull(); } }
The setup for the test is a bit repetitive, but I had to set it up that way to get these test cases working. You can probably figure out a better way.
Hibernate SQL output from Company test
select company0_.id as id1_0_2_, company0_.comp_id as comp_id2_0_2_, company0_.company_name as company_3_0_2_, company0_.emp_id as emp_id4_0_2_, employee1_.id as id1_1_0_, employee1_.comp_id as comp_id4_1_0_, employee1_.emp_id as emp_id2_1_0_, employee1_.emp_name as emp_name3_1_0_, company2_.id as id1_0_1_, company2_.comp_id as comp_id2_0_1_, company2_.company_name as company_3_0_1_, company2_.emp_id as emp_id4_0_1_ from company company0_ left outer join employee employee1_ on company0_.emp_id=employee1_.emp_id left outer join company company2_ on employee1_.comp_id=company2_.comp_id where company0_.comp_id=?
Hibernate SQL output from Employee test
select employee0_.id as id1_1_0_, company1_.id as id1_0_1_, employee0_.comp_id as comp_id4_1_0_, employee0_.emp_id as emp_id2_1_0_, employee0_.emp_name as emp_name3_1_0_, company1_.comp_id as comp_id2_0_1_, company1_.company_name as company_3_0_1_, company1_.emp_id as emp_id4_0_1_ from employee employee0_ inner join company company1_ on employee0_.comp_id=company1_.comp_id where employee0_.emp_id=?
0 comments:
Post a Comment