Entité de l'entreprise

@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;




}

Entité des employés

@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;

}

Service d'entreprise

@Service
public class CompanyService {

    @Autowired
    private CompanyRepository companyRepo;

    public Company fetchCompany(int cmpId){
        System.out.println("11111111111111111");
        return companyRepo.findByCmpId(cmpId);
    }
}

Repo d'entreprise

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());
}

Le problème est que lorsque j'essaie d'exécuter mon code, j'obtiens l'erreur suivante:

  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]

Comment régler ceci? De plus, lorsque j'ai supprimé referenceColumnName , l'erreur est supprimée, mais elle se joint à la clé primaire de la classe d'entreprise, ce que je ne veux pas.?

15
Ankit Bansal 21 avril 2017 à 14:46

3 réponses

Meilleure réponse

Cela a l'air un peu génial, mais je pense que cela fonctionne comme vous l'avez demandé.

Entreprise

@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);
    }
}

Employé

@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;
    }
}

Référentiel des employés

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);
    }
}

Tests unitaires

@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();
    }
}

La configuration du test est un peu répétitive, mais j'ai dû la configurer de cette façon pour que ces cas de test fonctionnent. Vous pouvez probablement trouver un meilleur moyen.

Sortie SQL Hibernate du test de l'entreprise

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=?

Sortie SQL Hibernate du test des employés

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=?
2
ryan2049 2 août 2017 à 05:06

Exception:

 IllegalArgumentException: Can not set int field com.example.domain.Company.cmpId to java.lang.Integer

Veuillez utiliser Integer instead sur int dans l'entreprise comme dans l'entité Employé si le champ id.

 @Id
    @GeneratedValue
    private Integer id;

Veuillez également fournir des méthodes getter et setter pour les champs de votre entité.

1
Bhushan Uniyal 21 avril 2017 à 14:05
**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;
1
Akkave 24 avril 2017 à 12:44