认识到已经对此有很多疑问,我看不到我的具体情况的问题。我在我的应用程序中有另一个实例(运行良好),据我所知我正在镜像配置。实际上,当我使用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或 @ManyToMany定位未映射的类: 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;
}
}
机器操作员
@Entity
@Table(name="humanresources.employee_machineoperators")
@IdClass(MachineOperatorID.class)
public class MachineOperator implements Serializable {
private static final long serialVersionUID = 1L;
private Employee employee;
private Machine machine;
private SkillLevel skillLevel;
public MachineOperator() {}
public MachineOperator(Employee employee, Machine machine) {
this.employee = employee;
this.machine = machine;
}
public MachineOperator(Employee employee, Machine machine, SkillLevel skillLevel) {
this.employee = employee;
this.machine = machine;
this.skillLevel = skillLevel;
}
@Id
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="fk_employeeid")
@JsonView(View.SimpleEmployeeView.class)
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
@Id
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="fk_machineid")
public Machine getMachine() {
return machine;
}
public void setMachine(Machine machine) {
this.machine = machine;
}
@ManyToOne
@JoinColumn(name="fk_skilllevelid")
public SkillLevel getSkillLevel() {
return skillLevel;
}
public void setSkillLevel(SkillLevel skillLevel) {
this.skillLevel = skillLevel;
}
@Override
public int hashCode() {
return Objects.hash(machine, employee);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) {
return false;
}
MachineOperator other = (MachineOperator) obj;
return Objects.equals(machine, other.getMachine()) && Objects.equals(employee, other.getEmployee());
}
}
MachineOperatorID
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。谢谢!
答案 0 :(得分:2)
通常,如果未注释javax.persistence
的{{1}}或未扫描实体,就会发生这种情况。如果您已尝试使用注释中的给定选项,请按以下步骤进行调试:
@Entity
org.hibernate日志记录。寻找以下或类似的日志:
DEBUG
到此,您将知道注册实体。检查是否从路径中扫描了您的实体。
o.hibernate.jpa.internal.util.LogHelper : PersistenceUnitInfo
.
.
.
Managed classes names [
.
.
]
MachineOperatorID ,使其仅具有特定的列字段而没有对象。从休眠规范中,我引用:将多个属性映射为@Id属性并声明一个外部 class为标识符类型。这个课,需要 可序列化,通过@IdClass注释在实体上声明。 标识符类型必须包含与标识符相同的属性 实体的属性:每个属性名称必须相同,其属性 如果实体属性属于基本类型,则类型也必须相同 类型,其类型必须是关联的主键的类型 实体,如果实体属性是关联(@ OneToOne或 @ManyToOne)。
IdClass
,并且在不同字段上分别使用@Id
关联。绝对可以简化您的关系。答案 1 :(得分:0)
从machineoperator类中删除雇员和机器对象,并将其替换为其中的MachineOperatorID实例。并在MachineOperatorID类中创建计算机ID和操作员ID,并使用@ID注释实例,这将解决您的问题,这就是在休眠状态下做事的正确方法。
答案 2 :(得分:0)
首先,您需要通过将ID更改为原始类型来编辑MachineOperatorID类:
public class MachineOperatorID implements Serializable {
private static final long serialVersionUID = 1L;
private int employee;
private int machine;
...
}
,看看是否可以解决问题。或者,也许您应该考虑从文档中使用这种方法:
如果您希望加载完整的应用程序配置,但是 使用嵌入式数据库,应考虑将@SpringBootTest组合使用 使用@AutoConfigureTestDatabase而不是此注释。