Spring中的数据JPA外键不能持续存在

时间:2018-06-07 01:51:42

标签: spring jpa spring-data

我正在尝试使用Spring数据CrudRepository来保存包含一些子实体的父实体,但是当我“保存”父项时,我在子表中获取外键约束OID时遇到了问题。

因此,在下面的示例中,使用提供的JSON调用控制器将持久保存Ocean和2子Fish。但是Fish表中的FK OID未设置。

这里是对控制器的JSON请求开始的代码。 JSON请求

{
     "name":"Atlantic",
     "fishes": [
     {
         "name": "blue fin tuna"
     },
     {
        "name": "great white shark"
     }
     ]
}

OCEAN ENTITY

@Entity
public class Ocean {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long oid;
private String name;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = 
"ocean")
private Set<Fish> fishes; //yeah maybe a  bad example

鱼类实体

@Entity
public class Fish {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long fid;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "oid", nullable = false, updatable = false, insertable = 
true)
private Ocean ocean;
private String name;

CONTROLLER

@PostMapping("/god/ocean")
public Ocean createOcean(@RequestBody Ocean ocean) throws BadRequestException 
{
    LOG.info("createOcean()");
    return oceanDao.save(ocean);
}

REPOSITORY

public interface IOceanDao extends CrudRepository<Ocean, Long> {
}

MySql TABLES

CREATE TABLE IF NOT EXISTS `mydb`.`OCEAN` (
`OID` INT NOT NULL AUTO_INCREMENT COMMENT '',
`NAME` VARCHAR(45) NOT NULL COMMENT '',
 PRIMARY KEY (`OID`)  COMMENT '');

CREATE TABLE IF NOT EXISTS `mydb`.`FISH` (
`FID` INT(11) NOT NULL AUTO_INCREMENT COMMENT '',
`OID` INT(11) NULL  COMMENT '',
`NAME` VARCHAR(45) NOT NULL COMMENT '',
PRIMARY KEY (`FID`)  COMMENT '',
CONSTRAINT `FK_OID`
FOREIGN KEY (`OID`)
REFERENCES `mydb`.`OCEAN` (`OID`));

2 个答案:

答案 0 :(得分:1)

在遇到JsonManagedReference之前,我遇到了同样的问题。

尝试更改您的实体,使其包含如下内容:

在海洋实体中:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = 
"ocean")
@JsonManagedReference
private Set<Fish> fishes;

在“鱼”实体中:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "oid", nullable = false, updatable = false, insertable = 
true)
@JsonBackReference
private Ocean ocean;

我无法找到这种方法的工作原理,所以如果您知道:)

答案 1 :(得分:0)

使用CascadeType.PERSIST让EntityManager自动保留所有子实体,请尝试更改Ocean实体,如下所示

@Entity
public class Ocean {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long oid;

private String name;    
@OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, mappedBy ="ocean")
private Set<Fish> fishes;