Spring Boot Hibernate-针对未映射类使用@OneToMany

Spring Boot Hibernate-针对未映射类使用@OneToMany,hibernate,spring-boot,spring-data-jpa,Hibernate,Spring Boot,Spring Data Jpa,认识到这方面已经有很多问题了,我看不出我的具体案例有什么问题。在我的应用程序中有另一个这样的实例(运行良好),据我所知,我正在镜像配置。事实上,当我使用mvn:spring boot:run运行应用程序时,一切正常,所有数据都按预期找到。但是,当我尝试为应用程序运行测试时,任何使用 @RunWith(SpringRunner.class) @DataJpaTest public class TestClass { @Autowired private TestEntityMana

认识到这方面已经有很多问题了,我看不出我的具体案例有什么问题。在我的应用程序中有另一个这样的实例(运行良好),据我所知,我正在镜像配置。事实上,当我使用
mvn:spring boot:run
运行应用程序时,一切正常,所有数据都按预期找到。但是,当我尝试为应用程序运行测试时,任何使用

@RunWith(SpringRunner.class)
@DataJpaTest
public class TestClass {
    @Autowired
    private TestEntityManager em;
    ...
}
产生以下错误:

java.lang.IllegalStateException:未能加载ApplicationContext 原因:org.springframework.beans.factory.BeanCreationException: 创建类中定义的名为“entityManagerFactory”的bean时出错 路径资源 [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: 调用init方法失败;嵌套异常是 org.hibernate.AnnotationException:使用@OneToMany或@ManyToMany 以未映射的类为目标: com.utilities.domain.manufacturing.Machine.operators[com.humanresources.domain.MachineOperator] 原因:org.hibernate.AnnotationException:使用@OneToMany或 @许多针对未映射类的对象: com.utilities.domain.manufacturing.Machine.operators[com.humanresources.domain.MachineOperator]

诚然,我对配置没有太多的了解,但我不明白为什么一组类可以工作,而这一组却不能。以下是课程(仅包含相关部分):

员工

@Entity
@Table(name="humanresources.employees")
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;

    private int employeeID;
    ...
    private List<MachineOperator> machines = new ArrayList<>();

    public Employee() {}

    @Id
    @Column(name="pk_employeeid")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView(View.SimpleEmployeeView.class)
    public int getEmployeeID() {
        return employeeID;
    }

    public void setEmployeeID(int employeeID) {
        this.employeeID = employeeID;
    }

    ...    
    @OneToMany(mappedBy="employee",cascade=CascadeType.ALL,orphanRemoval=true)
    @JsonView(View.EmployeeView.class)
    public List<MachineOperator> getMachines() {
        return machines;
    }

    public void setMachines(List<MachineOperator> machines) {
        this.machines = machines;
    }

    public void addMachine(Machine machine) {
        MachineOperator machineOperator = new MachineOperator(this, machine);
        this.machines.add(machineOperator);
        machine.getOperators().add(machineOperator);
    }

    public void removeCompany(Machine machine) {
        for (Iterator<MachineOperator> iterator = machines.iterator(); iterator.hasNext(); ) {
            MachineOperator machineOperator = iterator.next();

            if (machineOperator.getEmployee().equals(this) &&
                    machineOperator.getMachine().equals(machine)) {
                iterator.remove();
                machineOperator.getMachine().getOperators().remove(machineOperator);
                machineOperator.setEmployee(null);
                machineOperator.setMachine(null);
            }
        }
    }
}
@Entity
@Table(name="utilities.mnfg_machines")
public class Machine implements Serializable {
    private static final long serialVersionUID = 1L;

    private int machineID;
    ...
    private List<MachineOperator> operators = new ArrayList<>();

    public Machine() {}

    @Id
    @Column(name="pk_machineid")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView({View.MachineView.class,View.DefaultMachineView.class})
    public int getMachineID() {
        return machineID;
    }

    public void setMachineID(int machineID) {
        this.machineID = machineID;
    }

    ...

    @OneToMany(mappedBy="machine",orphanRemoval=true)
    @JsonView({View.MachineView.class,View.DefaultMachineView.class})
    public List<MachineOperator> getOperators() {
        return operators;
    }

    public void setOperators(List<MachineOperator> operators) {
        this.operators = operators;
    }
}
机器操作ID

public class MachineOperatorID implements Serializable {
    private static final long serialVersionUID = 1L;

    private Employee employee;
    private Machine machine;

    public MachineOperatorID() {}

    public MachineOperatorID(Employee employee, Machine machine) {
        this.employee = employee;
        this.machine = machine;
    }

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public Machine getMachine() {
        return machine;
    }

    public void setMachine(Machine machine) {
        this.machine = machine;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 83 * hash + Objects.hashCode(this.machine);
        hash = 83 * hash + Objects.hashCode(this.employee);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final MachineOperatorID other = (MachineOperatorID) obj;
        if (!Objects.equals(this.machine, other.machine)) {
            return false;
        }
        if (!Objects.equals(this.employee, other.employee)) {
            return false;
        }
        return true;
    }
}

任何人都知道什么是错误的,或者有没有更好的方法得到同样的结果?(我希望能够查看员工并查看他们可以操作的机器,或者查看机器并查看所有可以操作机器的员工。)我使用的是Spring Boot 2.0.3。谢谢

从machineoperator类中删除employee和machine对象,并将其替换为MachineOperatorID实例。并在MachineOperatorID类中使用创建机器id和操作员id,并使用@id注释实例,这将解决您的问题,这是在hibernate中执行操作的正确方法。

从machineoperator类中删除employee和machine对象,并将其替换为MachineOperatorID实例。在MachineOperatorID类中创建机器id和操作员id,并用@id注释实例,这将解决您的问题,这是在hibernate中执行操作的正确方法。

通常在
javax.persistence
@Entity
未注释或未扫描实体时发生这种情况。如果您在注释中尝试了给定的选项,请按如下方式调试:

  • 在application.yaml/properties或log4j2.xml或任何日志配置中启用org.hibernate的日志记录
查找以下或类似日志:
o.hibernate.jpa.internal.util.LogHelper:PersistenceUnitInfo
.
.
.
托管类名称[
.
.
]

通过这一点,您将了解注册实体。检查是否从路径扫描实体

  • 其次,如果加载了实体,请将
    IdClass
    MachineOperatorID更改为只包含特定的列字段,而不包含对象。从hibernate规范中,我引用:
将多个属性映射为@Id属性并声明外部 类作为标识符类型。这个类,需要 Serializable,通过@IdClass注释在实体上声明。 标识符类型必须包含与标识符相同的属性 实体的属性:每个属性名称必须相同,其 如果实体属性是基本属性,则类型也必须相同 类型,其类型必须是关联的 实体,如果实体属性是关联(a@OneToOne或 a@manytone)

  • 如果这是可变代码,请简化您的关联。对单个列使用
    @Id
    ,并在不同字段上分别使用
    @ManyToOne
    关联。当然,你们的关系可以简化很多

通常,如果您的
javax.persistence
@实体
未被注释,或者实体未被扫描,就会发生这种情况。如果您在注释中尝试了给定的选项,请按如下方式调试:

  • 在application.yaml/properties或log4j2.xml或任何日志配置中启用org.hibernate的日志记录
查找以下或类似日志:
o.hibernate.jpa.internal.util.LogHelper:PersistenceUnitInfo
.
.
.
托管类名称[
.
.
]

通过这一点,您将了解注册实体。检查是否从路径扫描实体

  • 其次,如果加载了实体,请将
    IdClass
    MachineOperatorID更改为只包含特定的列字段,而不包含对象。从hibernate规范中,我引用:
将多个属性映射为@Id属性并声明外部 类作为标识符类型。这个类,需要 Serializable,通过@IdClass注释在实体上声明。 标识符类型必须包含与标识符相同的属性 实体的属性:每个属性名称必须相同,其 如果实体属性是基本属性,则类型也必须相同 类型,其类型必须是关联的 实体,如果实体属性是关联(a@OneToOne或 a@manytone)

  • 如果这是可变代码,请简化您的关联。对单个列使用
    @Id
    ,并在不同字段上分别使用
    @ManyToOne
    关联。当然,你们的关系可以简化很多
  • public class MachineOperatorID implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private Employee employee;
        private Machine machine;
    
        public MachineOperatorID() {}
    
        public MachineOperatorID(Employee employee, Machine machine) {
            this.employee = employee;
            this.machine = machine;
        }
    
        public Employee getEmployee() {
            return employee;
        }
    
        public void setEmployee(Employee employee) {
            this.employee = employee;
        }
    
        public Machine getMachine() {
            return machine;
        }
    
        public void setMachine(Machine machine) {
            this.machine = machine;
        }
    
        @Override
        public int hashCode() {
            int hash = 7;
            hash = 83 * hash + Objects.hashCode(this.machine);
            hash = 83 * hash + Objects.hashCode(this.employee);
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final MachineOperatorID other = (MachineOperatorID) obj;
            if (!Objects.equals(this.machine, other.machine)) {
                return false;
            }
            if (!Objects.equals(this.employee, other.employee)) {
                return false;
            }
            return true;
        }
    }
    
    public class MachineOperatorID implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private int employee;
    private int machine; 
    
    ...
    }