hibernate - 使用referenceColumnName时OnetoOne双向关联错误

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

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

问题是当我尝试执行我的代码时,出现以下错误:
  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]

如何解决这个问题?也当我删除了 引用列名 ,然后错误被删除,但他们加入了公司类的主键,这是我不想要的。?

最佳答案

这看起来有点时髦,但我相信它可以按照您的要求工作。

公司

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

公司库
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);
}

公司服务
@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);
}

员工服务
@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=?

员工测试的 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=?

关于hibernate - 使用referenceColumnName时OnetoOne双向关联错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43541916/

相关文章:

spring-data-jpa - QueryDSL NoSuchMethodError : jpa. JPQLQuery.from() 错误

java - Spring Boot RESTful API 的各层设计及其实体映射

eclipse - 运行 tomcat 服务器获取输出作为目录列表/

java - Hibernate 和 MySQL 超出锁定等待超时(使用 Play Framework )

spring - Spring Boot with JOOQ 和 Spring Data JPA 之间的技术差异

java - 使用 Spring Data JPA 进行搜索

java - 配置 Spring 事务或 EJB CMT

java - Hibernate 示例查询

java - 使用 spring jpa 编写 group by 表达式

java - Spring Data JPA 和 startsWith 存储库