使用referenceColumnName

时间:2017-04-21 11:46:31

标签: hibernate spring-data-jpa

公司实体

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




}

员工实体

@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
public class CompanyService {

    @Autowired
    private CompanyRepository companyRepo;

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

公司回购

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

问题是当我尝试执行我的代码时,我收到以下错误:

  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]

如何解决这个问题?此外,当我删除 referenceColumnName 时,错误将被删除,但是它们正在加入公司类的主键,我不想这样做。

3 个答案:

答案 0 :(得分:2)

这看起来有点时髦,但我相信它的工作方式与您的要求相同。

公司

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

<强>员工

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

单元测试

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

测试的设置有点重复,但我不得不设置它以使这些测试用例正常工作。你可能想出一个更好的方法。

来自公司测试的Hibernate SQL输出

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

来自Employee test的Hibernate SQL输出

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

答案 1 :(得分:1)

例外:

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

如果是id字段,请使用公司instead的整数int和我们的员工实体。

 @Id
    @GeneratedValue
    private Integer id;

另外,请为您实体中的字段提供getter和setter方法。

答案 2 :(得分:1)

for (int i = 0; i < routedataArray.length(); i++) {
                        JSONObject jsonObject, studentobject;
                        JSONArray studentArray;
                        try {
                            jsonObject = routedataArray.getJSONObject(i);


                            ch_list = new ArrayList<studentData>();
                            stopNum = generalFunc.getStringFromJobject(jsonObject, "stopNum");
                            stopName = generalFunc.getStringFromJobject(jsonObject, "stopName");
                            stopLoc = generalFunc.getStringFromJobject(jsonObject, "loc");

                            studentArray = jsonObject.getJSONArray("students");

                            for (int j = 0; j < studentArray.length(); j++) {

                                studentobject = studentArray.getJSONObject(j);
                                studentName = generalFunc.getStringFromJobject(studentobject, "studentName");
                                studentId = generalFunc.getStringFromJobject(studentobject, "studentId");
                                studentData ch = new studentData(studentName,studentId);
                                ch_list.add(ch);

                            }
                            routedata gru = new routedata(stopNum,stopName,stopLoc,ch_list);
                            list.add(gru);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }