java - Spring Data JPA 无法找到具有 id 的对象
问题描述
我在我的项目中使用 JPA + Hibernate + Spring Data JPA 来处理数据库(MySQL)。最近我有一个错误说:
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.kanda.mindwire.domain.results.CognitiveResult with id 1700; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.kanda.mindwire.domain.results.CognitiveResult with id 1700
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:379) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528) ~[spring-orm-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) ~[spring-data-jpa-2.2.3.RELEASE.jar:2.2.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at com.sun.proxy.$Proxy157.findByCompany(Unknown Source) ~[na:na]
at com.kanda.mindwire.service.employee.EmployeeService.findWithFilter(EmployeeService.java:210) ~[classes/:1.0-SNAPSHOT]
该代码试图获取与CognitiveResult具有OneToOne关系的Employee实体列表。我在想可能是有Employee行,cognitive_id=1700但是当我查询我的数据库时,我发现没有这样的行。
问题是hibernate从哪里获取这个id以及如何修复它?
这是我的代码: Employee.java
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {Employee_.EMAIL}))
@Entity
@Data
public class Employee extends BaseEmployee {
@Column
private String email;
....
@ManyToOne
@JoinColumn(name = "company_id")
private Company company;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "cognitive_id", referencedColumnName = "id")
private CognitiveResult cognitiveResult;
...
}
认知结果.java
@Entity
@Table(name = "cognitive_results")
@Data
public class CognitiveResult extends BaseAssesment {
...
@OneToOne(mappedBy = "cognitiveResult")
private Employee employee;
@PreRemove
public void removeCognitiveForEmployee() {
if (employee != null) {
employee.setCognitiveResult(null);
}
}
...
}
EmployeeRepository.java
public interface EmployeeRepository extends BaseRepository<Employee> {
...
List<Employee> findByCompany(Company company);
...
}
公司.java
@Entity
@Data
public class Company extends BaseSettingsEntity {
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
private Set<Employee> employees = new HashSet<>();
/**
* Logic for syncing employees
* @param employee
*/
public void removeEmployee(Employee employee) {
if (!employees.contains(employee)) {
return;
}
employees.remove(employee);
employee.setCompany(null);
}
public void addEmployee(Employee employee) {
if (employees.contains(employee)) {
return;
}
employees.add(employee);
employee.setCompany(this);
}
...
}
我所有的域模型都继承自BaseEntity.java
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
@Data
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(updatable = false, nullable = false)
protected Long id;
...
}
调用 findByCompany 时发生异常:
@Slf4j
public class EmployeeService extends BaseEntityService<Employee> {
private final EmployeeRepository repo;
public Map<String, Map<EmployeeJob, List<Employee>>> findWithFilter(EmployeeFilterWrapper filter, String username) {
List<Employee> employeeList;
User user = userService.findByUsername(username);
Company company = user.getCompany();
if (company == null)
throw new InvalidCompanyException("Company not assigned for a user!");
if (filter != null && filter.getDivisionsFilter() != null && CollectionUtils.isNotEmpty(filter.getDivisionsFilter().getDivisions())) {
employeeList = repo.findEmployeeByDivisionNamesAndCompany(filter.getDivisionsFilter().getDivisions(), company.getName());
} else {
employeeList = repo.findByCompany(company);
}
...
}
解决方案
发现一个问题。那里有一个链接cognitive_id
在另一个表中丢失并且它丢失了,因为我最近直接在 db 中清除了这些实体,但忘记了它们引用了另一个表。这是一张Supervisors
继承自Employee
@Entity
@Table(name = "supervisors")
@Data
public class Supervisor extends Employee {
...
}
推荐阅读
- php - 未找到 InvalidArgumentException 视图 [layouts.app]。Larave-8 LliveWire-2
- android - 类型不匹配:推断类型是 () -> Unit but Runnable!预计
- reactjs - Typescript 和 Context API,错误:渲染的钩子比上一次渲染时更多
- uipath - 通过 Orchestrator API 删除库
- android - Rad Studio 10.2.3 安装 apk 时出错:INSTALL_PARSE_FAILED_NO_CERTIFICATES
- django - 在 Vagrant 中无法访问本地主机返回站点
- numpy - 2个numpy数组之间的元素欧几里得距离
- python - 如何使用 Boto3 库在 AWS Glue 中创建工作流?
- python - 为什么pandas中的.columns方法没有括号()?
- excel - 网页抓取 Zerohedge