Spring Boot错误:@OneToOne或@ManyToOne引用了一个未知的实体。

huangapple go评论80阅读模式
英文:

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&#39;m a physics engineer and I have to do some research on earthquakes, for that I&#39;m building a software to perform some calculations. I have experience with java and android, but I&#39;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 = &quot;earthquakeDetails&quot;, cascade = CascadeType.ALL)
private List&lt;DistancesEntity&gt; 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 = &quot;earthquakes_id&quot;, 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&#39;m doing wrong or if I&#39;m doing a bad practice. I&#39;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&quot;>
<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>

&lt;properties&gt;
	&lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
	&lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
	&lt;java.version&gt;1.8&lt;/java.version&gt;
	&lt;jjwt.version&gt;0.6.0&lt;/jjwt.version&gt;
&lt;/properties&gt;

&lt;dependencies&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;io.jsonwebtoken&lt;/groupId&gt;
		&lt;artifactId&gt;jjwt&lt;/artifactId&gt;
		&lt;version&gt;${jjwt.version}&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
		&lt;artifactId&gt;commons-lang3&lt;/artifactId&gt;
		&lt;version&gt;3.3.2&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
		&lt;version&gt;2.3.1.RELEASE&lt;/version&gt;
	&lt;/dependency&gt;


	&lt;dependency&gt;
		&lt;groupId&gt;com.google.code.gson&lt;/groupId&gt;
		&lt;artifactId&gt;gson&lt;/artifactId&gt;
		&lt;version&gt;2.8.6&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
		&lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
		&lt;version&gt;6.0.10.Final&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.modelmapper.extensions&lt;/groupId&gt;
		&lt;artifactId&gt;modelmapper-spring&lt;/artifactId&gt;
		&lt;version&gt;2.3.0&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;commons-beanutils&lt;/groupId&gt;
		&lt;artifactId&gt;commons-beanutils&lt;/artifactId&gt;
		&lt;version&gt;1.9.4&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;org.passay&lt;/groupId&gt;
		&lt;artifactId&gt;passay&lt;/artifactId&gt;
		&lt;version&gt;1.3.0&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
		&lt;version&gt;2.11.1&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-core&lt;/artifactId&gt;
		&lt;version&gt;2.11.1&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-annotations&lt;/artifactId&gt;
		&lt;version&gt;2.11.1&lt;/version&gt;
	&lt;/dependency&gt;


	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
		&lt;optional&gt;true&lt;/optional&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;mysql&lt;/groupId&gt;
		&lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
		&lt;scope&gt;runtime&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
		&lt;scope&gt;test&lt;/scope&gt;
		&lt;exclusions&gt;
			&lt;exclusion&gt;
				&lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
				&lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
			&lt;/exclusion&gt;
		&lt;/exclusions&gt;
	&lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
	&lt;plugins&gt;
		&lt;plugin&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
		&lt;/plugin&gt;
	&lt;/plugins&gt;
&lt;/build&gt;

</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 = &quot;distances&quot;)
public class DistancesEntity implements Serializable {

    // other fields

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = &quot;earthquakes_id&quot;, 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.

huangapple
  • 本文由 发表于 2020年7月22日 18:17:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63031951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定