【问题标题】:Spring Data JPA unable to find object with idSpring Data JPA 无法找到具有 id 的对象
【发布时间】:2020-08-19 00:17:26
【问题描述】:

我在我的项目中使用 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 实体列表。我在想可能是 cognitive_id=1700Employee 行,但是当我查询我的数据库时,我发现没有这样的行。

问题是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;
...
}

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

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

【问题讨论】:

  • I was thinking that it might be that there are Employee row with cognitive_id=1700 but when I query my db I see that there are no such row. 你为什么会这样想?无论如何,这些 ID 都可以匹配,因为它们位于不同的表中。错误说没有 ID 为 1700CognitiveResult:“无法找到 ID 为 1700 的 com.kanda.mindwire.domain.results.CognitiveResult”
  • @ChristopherSchneider 我认为是因为我正在获取Employee 类型的列表,并且以某种方式收到错误“未找到 ID 为 1700 的 CognitiveResult”。所以我猜测应该在Employee 表中对这个cognitive_id 有“未清理的引用”(是的,我看到CognitiveResult 表中没有这样的行)。由于既没有引用它,也没有 CognitiveResult 有这样的 id,我不明白这个 1700 是从哪里来的......

标签: java mysql spring hibernate spring-data-jpa


【解决方案1】:

发现一个问题。那里有一个链接到另一个表中缺少 cognitive_id 并且它丢失了,因为我最近直接在 db 中清除了这些实体,但忘记了它们引用了另一个表。 这是一个Supervisors 表,继承自Employee

@Entity
@Table(name = "supervisors")
@Data
public class Supervisor extends Employee {
...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    相关资源
    最近更新 更多