spring boot REST Api中的一对多关系

如何解决spring boot REST Api中的一对多关系

我正在使用 Spring Boot 创建一个 REST API。在这个 API 中,我在 签入访客 之间建立了一对多的关系。我创建了一个用于签入的控制器并使用 spring JPA 的保存功能。 save 方法同时更新checkinguest 表,但对于guest 表,guest 表中的签入外键 没有被添加,而是显示为空。请有人帮助我。我需要同时创建访客和签到。

签到模型

@Data
@Entity
public class Checkin {

    @Id
    private Long id;

    private Integer no_of_guests;

    @OneToMany(mappedBy = "checkin",cascade = CascadeType.ALL)
    private List<Guest> guests;
}

访客模型

@Data
@Entity
public class Guest {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long guest_id;

    private String name;

    private String mobile_no;

    private String address;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "guest_checkin_id",nullable = false )
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private Checkin checkin;

}

签到控制器

@RestController
@RequestMapping("/checkin")
public class CheckinController {

    private final CheckinRepository checkinRepo;
    private final GuestRepository guestRepo;

    public CheckinController(CheckinRepository checkinRepo,GuestRepository guestRepo){
        this.checkinRepo = checkinRepo;
        this.guestRepo = guestRepo;
    }

    @PostMapping("/add")
    ResponseEntity<Object> roomCheckin(@RequestBody Checkin checkin){
         if(checkinRepo.save(checkin) != null){
            return ResponseEntity.accepted().body("Checkin Successfull");
        }
        return ResponseEntity.unprocessableEntity().body("Failed to Checkin");
    }
}

解决方法

使用实体类作为视图模型类可能有点棘手,尤其是在 CheckinGuest 之间存在双向一对多关系的情况下。

让我们首先验证实体类和存储库是否如所描述的那样工作。为了进行测试运行,我必须为类 @GeneratedValue 中的 id 字段添加 Checkin

其他变化:

我在下面添加了一个测试类 CheckinRepositoryTest 以验证代码。


如前所述,使用实体类作为视图模型类可能很棘手,因此下一步将引入两个新的视图模型类:CheckinVMGuestVM,以及一个新的服务类 {{ 1}} 将负责保存 GuestServiceCheckin 实例。代码如下所示。

请注意,我只为 Guest 类添加了骨架,我将它留给您来实现。 GuestService 中的代码指示如何实现它。

有了视图模型类,CheckinRepositoryTest 应该被删除。


所有部分都启动并运行后,您应该向新的视图模型类添加验证,以及一些验证行为的集成测试。如果您遵循 TDD,您将在途中添加测试。

您还应该查看您的控制器方法,并针对成功和失败情况使用适当的状态代码。


嘉宾班

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)

GuestVM 类

package no.mycompany.myapp.misc;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;

@Getter
@Setter
@Entity
public class Guest {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long guest_id;

    private String name;

    private String mobile_no;

    private String address;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "guest_checkin_id",nullable = false)
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private Checkin checkin;
}

签到类

package no.mycompany.myapp.misc;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class GuestVM {

    private long id;
    private String name;
    private String mobile_no;
    private String address;

    public GuestVM(Guest guest) {
        this.id = guest.getGuest_id();
        this.name = guest.getName();
        this.mobile_no = guest.getMobile_no();
        this.address = guest.getAddress();
    }
}

CheckinVM 类

package no.mycompany.myapp.misc;

import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Getter
@Setter
@Entity
public class Checkin {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Integer no_of_guests;

    @OneToMany(mappedBy = "checkin",cascade = CascadeType.ALL)
    private Set<Guest> guests = new HashSet<>();
}

签入仓库

package no.mycompany.myapp.misc;

import lombok.Getter;
import lombok.Setter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.stream.Collectors;

@Getter
@Setter
@NoArgsConstructor
public class CheckinVM {

    private long id;
    private List<GuestVM> guests;

    public CheckinVM(Checkin checkin) {
        this.id = checkin.getId();
        this.guests = checkin.getGuests().stream().map(GuestVM::new).collect(Collectors.toList());
    }
}

CheckinRepositoryTest

package no.mycompany.myapp.misc;

import org.springframework.data.jpa.repository.JpaRepository;

public interface CheckinRepository extends JpaRepository<Checkin,Long> { }

CheckinService 类:这个交给你来实现

package no.mycompany.myapp.misc;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@DataJpaTest
public class CheckinRepositoryTest {

    @Autowired
    TestEntityManager testEntityManager;

    @Autowired
    CheckinRepository checkinRepository;

    @Test
    public void test() {

        // create instances
        var checkinInDb = new Checkin();
        var guestInDb = new Guest();

        // add relations
        guestInDb.setCheckin(checkinInDb);
        checkinInDb.getGuests().add(guestInDb);

        // save check-in
        checkinRepository.save(checkinInDb);

        // verify that check-in has one guest
        var checkin = testEntityManager.find(Checkin.class,checkinInDb.getId());
        assertThat(checkin.getGuests().size()).isEqualTo(1);

        // verify that guest is connected to a check-in
        var guest = testEntityManager.find(Guest.class,guestInDb.getGuest_id());
        assertThat(guest.getCheckin()).isNotNull();
    }
}

控制器类

package no.mycompany.myapp.misc;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class CheckinService {

    private final CheckinRepository checkinRepository;

    public CheckinVM saveCheckin(CheckinVM checkin) {
        return null; // TODO: implement this
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-