我问这个问题是因为我的OneToMany没有将对象添加到我的集合中。我想知道是我犯了一个错误还是我在配置中遗漏了什么。下面是我的代码:
application.properties :
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${SMTP_SPREE_USERNAME}
spring.mail.password=${SMTP_SPREE_PASSWORD}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
server.servlet.context-path=/api
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/Workshop
spring.datasource.username=${SPREE_DB_USERNAME}
spring.datasource.password=${SPREE_DB_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
jwt.secret=${SPREE_JWT_SECRET}
ActivityCategory.java :
package com.spreeapi.spree.models;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.Set;
@Entity
@Getter
@Setter
@Table(name="activity_category")
public class ActivityCategory {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title")
private String title;
@OneToMany(targetEntity = Activity.class,
cascade = CascadeType.ALL,
fetch = FetchType.EAGER)
private Set<Activity> activities;
}
Activity.java :
package com.spreeapi.spree.models;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Table(name = "activity")
@Getter
@Setter
public class Activity {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@Column(name = "min_persons")
private String minimalPersons;
@Column(name = "max_persons")
private String maximumPersons;
@Column(name = "is_remote")
private boolean isRemote;
@Column(name = "working_hours")
private boolean workingHours;
@Column(name = "minimal_duration")
private String minimalDuration;
@ManyToOne(targetEntity = ActivityCategory.class)
@JoinColumn(name = "activity_category_id")
private ActivityCategory activityCategory;
}
ActivityCategoryRepository.java :
package com.spreeapi.spree.repository;
import com.spreeapi.spree.models.ActivityCategory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ActivityCategoryRepository extends JpaRepository<ActivityCategory, Integer> {
}
ActivityRepository.java :
package com.spreeapi.spree.repository;
import com.spreeapi.spree.models.Activity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ActivityRepository extends JpaRepository<Activity, Long> {
public Page<Activity> findByActivityCategoryId(int id, Pageable pageable);
}
Test.java :
package com.spreeapi.spree.controllers;
import com.spreeapi.spree.models.Activity;
import com.spreeapi.spree.models.ActivityCategory;
import com.spreeapi.spree.repository.ActivityCategoryRepository;
import com.spreeapi.spree.repository.ActivityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class Test {
@Autowired
private ActivityRepository activityRepository;
@Autowired
private ActivityCategoryRepository activityCategoryRepository;
@GetMapping("/rest/demand/categories")
public List<ActivityCategory> test3(){
return activityCategoryRepository.findAll();
}
@GetMapping("/rest/demand/activities")
public List<Activity> test(){
return activityRepository.findAll();
}
}
pom.xml文件:
<?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.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spree-api</groupId>
<artifactId>spree</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spree</name>
<description>spree</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
当我对/类别执行GET时,结果是:
[
{
"id": 1,
"title": "Escape game",
"activities": []
},
{
"id": 2,
"title": "Jeux de société",
"activities": []
},
{
"id": 3,
"title": "Sports",
"activities": []
},
{
"id": 4,
"title": "Voyage",
"activities": []
},
{
"id": 5,
"title": "Laser-game",
"activities": []
},
{
"id": 6,
"title": "Activité culturelle",
"activities": []
},
{
"id": 7,
"title": "After Work",
"activities": []
},
{
"id": 8,
"title": "Jeux de cartes",
"activities": []
},
{
"id": 9,
"title": "Jeux Vidéo",
"activities": []
},
{
"id": 10,
"title": "Jeux de Rôle sur Table",
"activities": []
},
{
"id": 11,
"title": "Karaoké",
"activities": []
}
]
如您所见,ActivityCategory的activities属性返回空,但如果我通过获取DB的所有活动列表来执行此操作,则通过访问/activities可获得以下结果:
[
{
"id": 1,
"title": "Escape Game",
"description": "L'Escape Game est un jeu dont le but est à tenter de s’échapper d’une pièce en un temps limité. En groupe de 2 à 6 participants, les joueurs doivent chercher des indices disséminés dans une ou plusieurs pièces, puis les combiner pour avancer dans la salle.",
"minimalPersons": "2",
"maximumPersons": "50",
"workingHours": true,
"minimalDuration": "Quelques heures",
"activityCategory": {
"id": 1,
"title": "Escape game",
"activities": []
},
"remote": false
},
{
"id": 2,
"title": "7 wonders",
"description": "7 Wonders est un jeu de cartes ayant pour thème le développement de civilisations autour de chacune des sept Merveilles du monde en utilisant un système de draft.",
"minimalPersons": "2",
"maximumPersons": "7",
"workingHours": true,
"minimalDuration": "Quelques heures",
"activityCategory": {
"id": 2,
"title": "Jeux de société",
"activities": []
},
"remote": true
},
{
"id": 3,
"title": "Catan",
"description": "Catan est un classique du jeux de société, un jeu de plateau stratégique mais convivial avec un principe d'échange de ressource.",
"minimalPersons": "2",
"maximumPersons": "7",
"workingHours": true,
"minimalDuration": "Quelques heures",
"activityCategory": {
"id": 2,
"title": "Jeux de société",
"activities": []
},
"remote": true
},
{
"id": 4,
"title": "Risk",
"description": "Risk est un jeux de société inspiré du jeux de guerre, en plus simplifier, où votre but est de conquérique le monde.",
"minimalPersons": "2",
"maximumPersons": "6",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 2,
"title": "Jeux de société",
"activities": []
},
"remote": true
},
{
"id": 5,
"title": "Les demeures de l'épouvante",
"description": "Les Demeures de l’Épouvante est un jeu de plateau coopératif d’horreur et d’enquête. Les joueurs y incarnent des investigateurs qui s’aventurent dans les salles sombres des demeures hantées d’Arkham",
"minimalPersons": "2",
"maximumPersons": "5",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 2,
"title": "Jeux de société",
"activities": []
},
"remote": true
},
{
"id": 6,
"title": "Foot",
"description": "Le football est un sport collectif qui se joue avec un ballon sphérique, où il faut faire pénétrer un ballon rond dans les buts adverses sans utiliser les mains",
"minimalPersons": "5",
"maximumPersons": "100",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 3,
"title": "Sports",
"activities": []
},
"remote": false
},
{
"id": 7,
"title": "Tennis de table",
"description": "Le tennis de table, appelé aussi ping-pong, est un sport de raquette opposant deux ou quatre joueurs autour d'une table",
"minimalPersons": "2",
"maximumPersons": "100",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 3,
"title": "Sports",
"activities": []
},
"remote": false
},
{
"id": 8,
"title": "Bowling",
"description": "Le bowling est un jeu qui consiste à renverser des quilles à l'aide d'une boule.",
"minimalPersons": "2",
"maximumPersons": "10",
"workingHours": true,
"minimalDuration": "Quelques heures",
"activityCategory": {
"id": 3,
"title": "Sports",
"activities": []
},
"remote": false
},
{
"id": 9,
"title": "Voyage",
"description": "Un voyage en équipe est un bon moyen de souder ses équipes.",
"minimalPersons": "5",
"maximumPersons": "100",
"workingHours": true,
"minimalDuration": "1 journée",
"activityCategory": {
"id": 4,
"title": "Voyage",
"activities": []
},
"remote": false
},
{
"id": 10,
"title": "Laser-game",
"description": "Un jeu laser aussi connu sous le terme anglophone Laser tag est une activité physique où les participants, revêtus habituellement d'une veste à capteurs, se tirent dessus avec des « pistolets laser »",
"minimalPersons": "2",
"maximumPersons": "10",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 5,
"title": "Laser-game",
"activities": []
},
"remote": false
},
{
"id": 11,
"title": "Musée",
"description": "le musée est un lieu d'expériences mémorables et émouvantes quand les sens sont interpellés pour attirer, susciter la curiosité, amuser, émerveiller, faire comprendre.",
"minimalPersons": "2",
"maximumPersons": "100",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 6,
"title": "Activité culturelle",
"activities": []
},
"remote": false
},
{
"id": 12,
"title": "After Work",
"description": "Cet instant entre collègues permet de resserrer les liens, de souder les équipes, de créer une sorte d'émulation. C'est aussi un moment où l'on dresse un bilan, où l'on cherche à décompresser ensemble dans un lieu en soirée neutre et agréable, loin de l'ambiance du travail.",
"minimalPersons": "2",
"maximumPersons": "20",
"workingHours": false,
"minimalDuration": "Quelques heures",
"activityCategory": {
"id": 7,
"title": "After Work",
"activities": []
},
"remote": false
},
{
"id": 13,
"title": "Poker",
"description": "Le poker est une famille de jeux de cartes comprenant de nombreuses formules et variantes. Il se pratique à plusieurs joueurs avec un jeu généralement de cinquante-deux cartes et des jetons représentant les sommes misées. Les séquences de jeu alternent distribution de cartes et tours d'enchères.",
"minimalPersons": "5",
"maximumPersons": "50",
"workingHours": true,
"minimalDuration": "1/2 journées",
"activityCategory": {
"id": 8,
"title": "Jeux de cartes",
"activities": []
},
"remote": false
},
{
"id": 14,
"title": "Arcade",
"description": "Une salle d’arcade est un établissement de loisirs regroupant des appareils tels que des jeux d’arcade, des flippers, des baby-foots, des tables d'air hockey, des machines attrape-jouet ainsi que des billards.",
"minimalPersons": "10",
"maximumPersons": "50",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 9,
"title": "Jeux Vidéo",
"activities": []
},
"remote": true
},
{
"id": 15,
"title": "Honey Heist",
"description": "Y en a deux : OURS et CRIMINEL. Les deux commencent à 3. OURS sert à courir, escalader, péter des trucs, ignorer les dommages, effrayer les gens et autres trucs d’ours. CRIMINEL sert pour tous les autres trucs, ce que les ours ne font pas en général.",
"minimalPersons": "3",
"maximumPersons": "6",
"workingHours": true,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 10,
"title": "Jeux de Rôle sur Table",
"activities": []
},
"remote": true
},
{
"id": 16,
"title": "Karaoké",
"description": "Prends le micro et chante",
"minimalPersons": "2",
"maximumPersons": "110",
"workingHours": false,
"minimalDuration": "1/2 journée",
"activityCategory": {
"id": 11,
"title": "Karaoké",
"activities": []
},
"remote": false
}
]
请让我知道,如果有什么是失踪或一个错误已作出。
2条答案
按热度按时间wd2eg0qa1#
在
ActivityCategory
和Activity
之间有两个独立的关系,它们完全不相关。如果您希望上的是另一个的反转,则必须将
mappedBy
属性添加到@ManyToOne
或@OneToMany
注解中。请注意,没有
mappedBy
属性的一端定义了将保留到数据库的内容,而另一端将在从数据库重新加载信息后镜像该信息,由于一级缓存的原因,这不会在单个事务中发生。有关详细信息,请阅读一级缓存和双向关系。
k2arahey2#
要添加到Jens Schauder答案(顺便说一下,非常好的解释性答案)。
@OneToMany
应该知道如何MapActivityCategory
和Activity
。这可以像这样完成: