我一直在玩JPA,遇到了这种情况,想知道如何解决这个问题。
我有2张表,即公司和员工。 因此,这里的员工只能为 1 家公司工作,因此@OneToOne单向映射是在员工类中完成的。公司表中的公司详细信息已经存在。
因此,当我尝试将记录插入 Employee 表时,我甚至会创建一个对公司的引用,将其添加到 Employee 类并使用我的 EmployeeRepository 的 save 方法保存它。由于company_id已存在于公司表中,因此它应该只引用它,而不是创建新公司。但这并没有发生。 我得到一个例外,说company object is still in the transient state.
我可以通过添加CascadeType.All
来解决这个问题,但我不需要插入公司,而只需要将公司链接到员工即可。
以下是代码片段。
员工类
@Entity
@Table(name = "employee")
@Setter
@Getter
public class Employee
{
@Id
@GeneratedValue
private Long id;
@Column(name = "employee_id")
private Integer employeeId;
@Column(name = "employee_name")
private String employee_name;
@OneToOne
@JoinColumn(name = "company_id")
private Company company;
}
公司类
@Entity
@Table(name = "company")
@Setter
@Getter
public class Company
{
@Id
@GeneratedValue
@Column(name = "company_id")
private Long id;
@Column(name = "company_name")
private String companyName;
}
公司表
company_id company_name
1 Dell
2 Apple
3 Microsoft
这是我创建员工对象的方式
Employee emp = new Employee();
emp.setEmployeeId(10);
emp.setEmployeeName("Michael");
Company company = new Company();
company.setId(1);
emp.setCompany(company);
employeeRepository.save(emp);
请有人告诉我如何将公司类链接到员工类,而不是再保存一家公司。
对我来说最好的解决方案是用代理延迟加载您的公司。要使用 Spring Data JPA 执行此操作,您需要使您的公司存储库扩展JpaRepository
.这使您可以访问方法getReferenceById:
Employee emp = new Employee();
emp.setEmployeeId(10);
emp.setEmployeeName("Michael");
emp.setCompany(companyRepository.getReferenceById(1))
employeeRepository.save(emp);
如果给定 id 没有公司,则会抛出EntityNotFoundException
。
使用代理,在大多数情况下,您可以避免对数据库的请求,因为Hibernate使用其缓存来检查公司是否存在。但是,如果我没记错的话,Hibernate将在每次调用代理的getter时向数据库发出请求,除了getId()
。因此,在您的情况下,这是一个很好的解决方案,但不要一直使用它。
假设Company
可能有多个Employee
关系是ManyToOne
,而不是OneToOne
。
如果要引用现有实体,请加载它而不是创建新实体:
Employee emp = new Employee();
// ...
emp.setCompany(companyRepository.findById(1));
employeeRepository.save(emp);