【问题标题】:Entity Design using JPA使用 JPA 进行实体设计
【发布时间】:2021-04-10 07:51:59
【问题描述】:

我有 3 个实体 -

  1. 课程

  2. 模块

  3. 时间线 课程是具有以下属性的独立实体: 课程 - (id Integer Primary Key, course_name)

    @Id @Column(name = "id") 整数课程 ID; @Column(name = "course_name") 字符串课程名称;

接下来是另一个实体模块, 模块中的每一行都与一门课程相关,因此模块和课程之间存在一对一的关系。 模块 - (module_id, module_name, module_type, duration)

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "module_id")
Integer module_id;
@Column(name = "module_name")
String module_name;
@Column(name = "duration")
Integer duration;
@ManyToOne
@JoinColumn(name="timeline_id", nullable=false)
private Timeline timeline;

现在,next 是一个时间线实体,它也与课程相关,即每个时间线 id 都属于一个课程 id,但一个时间线 id 可以属于多个 module_id,因此下面的代码:

@Id
@Column(name = "timeline_id")
Integer timelineId;
@OneToMany( mappedBy = "timeline" )
private List<Module> module;
@OneToOne( cascade = CascadeType.ALL)
private Course course;

你能告诉我这里的错误是什么吗? ModuleRepository:

@Repository
public interface ModuleRepository extends JpaRepository<Module, Integer>{
    public List<Module> findAllByTimelineTimelineId(Integer timelineId);
}

IModuleService

public interface IModuleService {
     public List<Module> findByTimelineId(Integer timelineId);
}

ModuleServiceImpl

public List<Module> findByTimelineId(Integer timelineId) {
        // TODO Auto-generated method stub
        return moduleRepo.findAllByTimelineTimelineId(timelineId);
    }

控制器

@RequestMapping("/gettimeline/{timeline_id}")
             public List<Module> findByTimelineId(@PathVariable Integer timeline_id){
                    return moduleService.findByTimelineId(timeline_id);
            }

现在当我在 Postman 中运行这个网址时:http://localhost:8083/gettimeline/1

我得到一个无限循环,我无法解码错误,OneToMany 映射是否有任何问题,我是 JPA 新手:

[{"module_id":1,"module_name":"Sleep","duration":10,"timeline":{"timelineId":1,"module":[{"module_id":1,"module_name":"Sleep","duration":10,"timeline":{"timelineId":1,"module":[{"module_id":1,"module_name":"Sleep","duration":10,"timeline":{"timelineId":1,"module":[{"module_id":1,"module_name":"Sleep","duration":10,"timeline":{"timelineId":1,"module":[{"module_id":1,"module_name":"Sleep","duration":10,"timeline":{"timelineId":1,"module":[

请帮忙,提前谢谢你:)

【问题讨论】:

  • 嗨。无限循环问题是由一对多关系引起的。您应该实现视图模型类,其中拥有方 VM 具有多方集合,但不是相反。如果您添加了为您的 repo 代码获得的错误消息,我可以查看它。 BR
  • 嘿@RoarS。实际上没有错误。上面给出了一个无限循环。我是JPA的新手,请您详细说明您所说的内容。谢谢你:)
  • 嗨。在我下面的答案中添加了课程。请注意,我只包含了相关代码,您可以在 VM 类中添加更多字段。
  • 为了避免无限循环,您需要延迟获取实体。为此,通过定义诸如 @OneToMany( mappedBy = "timeline", fetch = FetchType.LAZY ) 和 @ManyToOne(fetch = FetchType.LAZY) 之类的提取类型来修改您的实体关系注释,并将 @Transactional 注释添加到您的服务实现类获取惰性引用的实体。

标签: spring-boot hibernate spring-mvc jpa spring-data-jpa


【解决方案1】:

无限循环问题是由一对多关系引起的。有几种方法可以解决这个问题,但我发现如下所示的视图模型类是最简洁的方法。

请注意,一对多关系的拥有方不包含在下面的代码中,只有多对一。这可以反过来做,但从你的代码来看,我想这就是你想要的。

TimelineVM 类

package no.mycompany.myapp.misc;

import lombok.Data;
import lombok.NoArgsConstructor;
    
@Data
@NoArgsConstructor
public class TimelineVM {

    private Integer timelineId;

    public TimelineVM(Timeline timeline) {
        this.timelineId = timeline.getTimelineId();
    }
}

ModuleVM 类

package no.mycompany.myapp.misc;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class ModuleVM {

    private Integer module_id;
    private String module_name;
    private Integer duration;
    private TimelineVM timeline;

    public ModuleVM(Module module) {
        this.module_id = module.getModule_id();
        this.module_name = module.getModule_name();
        this.duration = module.getDuration();
        this.timeline = new TimelineVM(module.getTimeline());
    }
}

控制器方法

@RequestMapping("/gettimeline/{timeline_id}")
public List<ModuleVM> findByTimelineId(@PathVariable Integer timeline_id){
  return moduleService.findByTimelineId(timeline_id).stream().map(ModuleVM::new).collect(Collectors.toList());
}

【讨论】:

    猜你喜欢
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多