英文:
Spring Boot Error: @OneToOne or @ManyToOne references an unknown entity
问题
I'm a physics engineer and I have to do some research on earthquakes, for that I'm building a software to perform some calculations. I have experience with java and android, but I'm having some difficulties with Spring Boot framework. I need to send to MySql database some important earthquakes, to analyze them. I have two entities, one is for the earthquakes and one is for a list of distances near the epicenter. Currently my problem consists in @OneToMany and @ManyToOne relationship where the error starts. I have for each entities also a DTO like below:
EarthquakeEntity:
@Entity(name = "earthquakes")
public class EarthquakeEntity implements Serializable {
@Id
@GeneratedValue
private long id;
@Column(nullable = false)
private String earthquakeId;
@Column(nullable = false)
private float magnitude;
@Column(nullable = false, length = 120)
private String region;
@Column(nullable = false, length = 50)
private String dateTime;
@Column(nullable = false, length = 50)
private String location;
@Column(nullable = false, length = 50)
private Integer depth;
@OneToMany(mappedBy = "earthquakeDetails", cascade = CascadeType.ALL)
private List<DistancesEntity> distances;
// getters and setters
}
Earthquake DTO:
public class EarthquakeDto implements Serializable {
private long id;
private String earthquakeId;
private float magnitude;
private String region;
private String dateTime;
private String location;
private Integer depth;
private List<DistanceDto> distances;
// getters and setters
}
and for the distance:
DistanceEntity:
@Entity(name = "distances")
public class DistancesEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, length = 30)
private String distanceId;
@Column(nullable = false, length = 120)
private String distance;
@Column(nullable = false, length = 50)
private Integer population;
@Column(nullable = false, length = 50)
private String localTime;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "earthquakes_id", nullable = false)
private EarthquakeDto earthquakeDetails;
// getters and setters
}
DistanceDTO:
public class DistanceDto implements Serializable {
private long id;
private String distanceId;
private String distance;
private Integer population;
private String localTime;
private EarthquakeDto earthquakeDetails;
// getters and setters
}
And in my service I have the logic for adding the earthquakes to the database,
EarthquakeServiceImpl.java
@Override
public EarthquakeDto addEarthquake(EarthquakeDto earthquake) {
for (int i = 0; i < earthquake.getDistances().size(); i++) {
DistanceDto distance = earthquake.getDistances().get(i);
distance.setEarthquakeDto(earthquake);
distance.setDistanceId(utils.generateQuakeDistanceID(30));
earthquake.getDistances().set(i, distance);
}
ModelMapper modelMapper = new ModelMapper();
EarthquakeEntity earthquakeEntity = modelMapper.map(earthquake, EarthquakeEntity.class);
String earthquakeId = utils.generateEarthquakeID(30);
earthquakeEntity.setEarthquakeId(earthquakeId);
EarthquakeEntity addedEarthquakes = earthquakeRepository.save(earthquakeEntity);
EarthquakeDto returnQuake = modelMapper.map(addedEarthquakes, EarthquakeDto.class);
return returnQuake;
}
and my controller
@PostMapping(consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE },
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public EarthquakeRest addEarthquake(@RequestBody EarthquakeRequestModel earthquakeDetails) throws Exception {
EarthquakeRest earthquakeRest = new EarthquakeRest();
ModelMapper modelMapper = new ModelMapper();
EarthquakeDto quakeDto = modelMapper.map(earthquakeDetails, EarthquakeDto.class);
EarthquakeDto addedEarthquake = earthquakeService.addEarthquake(quakeDto);
earthquakeRest = modelMapper.map(addedEarthquake, EarthquakeRest.class);
return earthquakeRest;
}
I did some research before decided to post my question on stack overflow, but none of them worked for me. The error seems to do with the hibernate, I carefully checked if I had import the annotations from javax.persistence and maven dependencies. Everything seems to be okay, but error persists:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.physicslab.Physics.Lab.io.entity.DistancesEntity.earthquakeDetails references an unknown entity: com.physicslab.Physics.Lab.shared.dto.EarthquakeDto
and another one
Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.physicslab.Physics.Lab.io.entity.DistancesEntity.earthquakeDetails references an unknown entity: com.physicslab.Physics.Lab.shared.dto.EarthquakeDto
I need some advice or suggestions of what I'm doing wrong or if I'm doing a bad practice. I'm also posting my maven dependencies if I did something wring here:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.physicslab</groupId>
<artifactId>Physics-Lab</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Physics-Lab</name>
<description>Project and laboratory management for physics projects</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jjwt.version>0.6.0</jjwt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io
<details>
<summary>英文:</summary>
I'm a physics engineer and I have to do some research on earthquakes, for that I'm building a software to perform some calculations. I have experience with java and android, but I'm having some difficulties with Spring Boot framework. I need to send to MySql database some important earthquakes, to analyze them. I have two entities, one is for the earthquakes and one is for a list of distances near the epicenter. Currently my problem consists in @OneToMany and @ManyToOne relationship where the error starts. I have for each entities also a DTO like below:
EarthquakeEntity:
@Entity(name = "earthquakes")
public class EarthquakeEntity implements Serializable {
@Id
@GeneratedValue
private long id;
@Column(nullable = false)
private String earthquakeId;
@Column(nullable = false)
private float magnitude;
@Column(nullable = false, length = 120)
private String region;
@Column(nullable = false, length = 50)
private String dateTime;
@Column(nullable = false, length = 50)
private String location;
@Column(nullable = false, length = 50)
private Integer depth;
@OneToMany(mappedBy = "earthquakeDetails", cascade = CascadeType.ALL)
private List<DistancesEntity> distances;
// getters and setters
}
Earthquake DTO:
public class EarthquakeDto implements Serializable {
private long id;
private String earthquakeId;
private float magnitude;
private String region;
private String dateTime;
private String location;
private Integer depth;
private List<DistanceDto> distances;
// getters and setters
}
and for the distance:
DistanceEntity:
@Entity(name = "distances")
public class DistancesEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false, length = 30)
private String distanceId;
@Column(nullable = false, length = 120)
private String distance;
@Column(nullable = false, length = 50)
private Integer population;
@Column(nullable = false, length = 50)
private String localTime;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "earthquakes_id", nullable = false)
private EarthquakeDto earthquakeDetails;
// getters and setters
}
DistanceDTO:
public class DistanceDto implements Serializable {
private long id;
private String distanceId;
private String distance;
private Integer population;
private String localTime;
private EarthquakeDto earthquakeDetails;
// getters and setters
}
And in my service I have the logic for adding the earthquakes to the database,
EarthquakeServiceImpl.java
Override
public EarthquakeDto addEarthquake(EarthquakeDto earthquake) {
for (int i = 0; i < earthquake.getDistances().size(); i++) {
DistanceDto distance = earthquake.getDistances().get(i);
distance.setEarthquakeDto(earthquake);
distance.setDistanceId(utils.generateQuakeDistanceID(30));
earthquake.getDistances().set(i, distance);
}
ModelMapper modelMapper = new ModelMapper();
EarthquakeEntity earthquakeEntity = modelMapper.map(earthquake, EarthquakeEntity.class);
String earthquakeId = utils.generateEarthquakeID(30);
earthquakeEntity.setEarthquakeId(earthquakeId);
EarthquakeEntity addedEarthquakes = earthquakeRepository.save(earthquakeEntity);
EarthquakeDto returnQuake = modelMapper.map(addedEarthquakes, EarthquakeDto.class);
return returnQuake;
}
and my controller
@PostMapping(consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE },
produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE })
public EarthquakeRest addEarthquake(@RequestBody EarthquakeRequestModel earthquakeDetails) throws Exception {
EarthquakeRest earthquakeRest = new EarthquakeRest();
ModelMapper modelMapper = new ModelMapper();
EarthquakeDto quakeDto = modelMapper.map(earthquakeDetails, EarthquakeDto.class);
EarthquakeDto addedEarthquake = earthquakeService.addEarthquake(quakeDto);
earthquakeRest = modelMapper.map(addedEarthquake, EarthquakeRest.class);
return earthquakeRest;
}
I did some research before decided to post my question on stack overflow, but none of them worked for me. The error seems to do with the hibernate, I carefully checked if I had import the annotations from javax.persistence and maven dependencies. Everything seems to be okay, but error persists:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.physicslab.Physics.Lab.io.entity.DistancesEntity.earthquakeDetails references an unknown entity: com.physicslab.Physics.Lab.shared.dto.EarthquakeDto
and another one
Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.physicslab.Physics.Lab.io.entity.DistancesEntity.earthquakeDetails references an unknown entity: com.physicslab.Physics.Lab.shared.dto.EarthquakeDto
I need some advice or suggestions of what I'm doing wrong or if I'm doing a bad practice. I'm also posting my maven dependencies if I did something wring here:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.physicslab</groupId>
<artifactId>Physics-Lab</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Physics-Lab</name>
<description>Project and laboratory management for physics projects</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jjwt.version>0.6.0</jjwt.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
</dependency>
<dependency>
<groupId>org.modelmapper.extensions</groupId>
<artifactId>modelmapper-spring</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.passay</groupId>
<artifactId>passay</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Maybe someone can suggest me some books to read about Spring Boot Framework because the tutorials treat differently and cannot understand well the concepts.
Thanks in advance
</details>
# 答案1
**得分**: 2
如错误提示所示,您正在在另一个JPA实体中对非持久性类型进行注释(引用)。
`EarthquakeEntity` 应该是映射的类型,而不是 `EarthquakeDto`:
```java
@Entity(name = "distances")
public class DistancesEntity implements Serializable {
// 其他字段
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "earthquakes_id", nullable = false)
private EarthquakeEntity earthquakeDetails;
// 获取器和设置器
}
然后,您应该配置您的 ModelMapper
以便在将 EarthquakeDto
映射到 EarthquakeEntity
实例时,DistanceDto
也自动映射到 DistanceEntity
。
请注意,您的问题与Spring框架本身无关,而是纯粹的JPA - Hibernate错误。
英文:
As the error suggests, you are annotating (referencing) a non-persistent type within anohter JPA Entity.
The EarthquakeEntity
should be the mapped type instead of EarthquakeDto
:
<!-- lanugage: lang-java -->
@Entity(name = "distances")
public class DistancesEntity implements Serializable {
// other fields
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "earthquakes_id", nullable = false)
private EarthquakeEntity earthquakeDetails;
// getters and setters
}
You should then configure your ModelMapper
so that the DistanceDto
gets automatically mapped to DistanceEntity
as well when mapping the EarthquakeDto
to a EarthquakeEntity
instance.
Note that you issue has nothing to do with the Spring framework itself and is a pure JPA - Hibernate error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论