【问题标题】:Foreign key is null : Hibernate Spring外键为空:Hibernate Spring
【发布时间】:2020-03-16 11:04:20
【问题描述】:

我尝试将对象 Run 保存到数据库。我定义了 Run 和 City 之间的关系。一个城市可以有很多次运行。我遇到了 city_id 的问题。一片空白。

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Column 'city_id' cannot be null

我的实体和控制器: 城市

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "cities")
public class City {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "city_id")
    private long id;
    @OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Run> runs = new ArrayList<>();
    private String name;
}

运行

@Entity
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "runs")
public class Run {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @Column(name = "name_run")
    private String nameRun;
    @Column(name = "distance")
    private double distance;
    @Column(name = "date")
    private Date date;
    @Column(name = "my_time")
    private String myTime;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "city_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonIgnore
    private City city;
}

控制器


@CrossOrigin
@RestController
@RequestMapping("/api/")
public class RunController {

    private RunRepository runRepository;
    private RunService runService;

    public RunController(RunRepository runRepository, RunService runService) {
        this.runRepository = runRepository;
        this.runService = runService;
    }

    @GetMapping("runs")
    public ResponseEntity<List<Run>> getRuns() {
        return runService.getRuns();
    }

    @PostMapping("runs")
    public ResponseEntity addRun(@RequestBody Run run) {

        return new ResponseEntity<>(runRepository.save(run), HttpStatus.OK);
    }
}

我想将运行保存在数据库中。 我的测试请求如下所示:

{ "nameRun": "测试", “距离”:“5.0”, "日期":"2020-12-12", "我的时间":"50:40", “城市”:“测试1” }

Intelijj 中评估表达式的结果:

为什么城市 = null?这里是映射错误吗?

【问题讨论】:

  • 你使用什么数据库?您能否提供您的citiesruns 表定义(ddl sql)。

标签: java hibernate hibernate-mapping


【解决方案1】:

您可以尝试使用此 json,但您需要在 json 中传递城市 ID。

{
    "nameRun": "test",
    "distance": "5.0",
    "date": "2020-12-12",
    "myTime": "50:40",
    "city": {
        "id": 1,
        "name": "test1"
    }
}

谢谢

【讨论】:

  • 此请求无效。我得到了列“city_id”不能为空
【解决方案2】:

首先,请使用Long 作为id。最好也加上@Entity注解。

@Entity
public class City {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "city", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Run> runs = new ArrayList<>();

}

@Entity
public class Run {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private City city;

}

保存Run时需要设置city_id

最简单的方法就是创建一个假的瞬态City 并为其设置id。

City city = new City();
city.setId(1L);

Run run = new Run();
run.setCity(city);

repository.save(run);

显然你应该在数据库中有一个id 1L 的城市。

其他选项是

  1. 使用类似于 session.load() Hibernate 的 Spring 存储库来创建 City,而无需从数据库中加载它。
  2. 完全按 ID 加载 City 实体。

【讨论】:

    【解决方案3】:

    如果你想保存任何运行类,

    Run run = new Run();
    City city = new City();
    city.getRuns().add(run);
    runRepository.save(run);
    

    如果你想保存任何运行类,首先你需要插入到(Arraylist)城市类的运行变量,如city.getRuns().add(run),然后你可以运行存储库.保存(运行)。

    我的样品也在这里。你可以看看myclasses。

    第一类叫做Patient

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Entity
    @ToString
    @Table(name = "aapatient")
    public class Patient {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
        @SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
        @Column(name = "patientid")
        private Long patientid;
        private String name;
        private String lastname;  
    
        @OneToMany(mappedBy = "patient", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        private List<Problem> problems; 
    }
    

    名为问题的第二类就是这个。

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    @Entity
    @Table(name="aaproblem")
    public class Problem{
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AA_PATIENT_SEQ")
        @SequenceGenerator(sequenceName = "AA_PATIENT_SEQ", allocationSize = 1, name = "AA_PATIENT_SEQ")
        @Column(name = "problemid")
        private Long problemid;
        private String problemName;
        private String problemDetail; 
    
        @Temporal(TemporalType.TIMESTAMP)
        Date creationDate;
    
        @NotNull
        @ManyToOne(optional = true, fetch = FetchType.LAZY)
        @JoinColumn(name = "patient_id")
        private Patient patient;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 2016-08-15
      • 2020-08-01
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 1970-01-01
      相关资源
      最近更新 更多