在我的Spring Boot项目中,我有两个模型,即Building和Location。我正在尝试创建一个属于建筑物的新位置。
这些是我的模特:
位置模型
public class Location implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Getter
private Integer id;
@NonNull
@Getter
@Setter
private String name;
@NonNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "building_id")
@JsonBackReference("building-location")
@ToString.Exclude
@Getter
@Setter
private Building building;
@Getter
@Setter
@Version
@Column(name = "lock_version")
private Integer lockVersion;
}
建筑模型
public class Building implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Getter
private Integer id;
@NonNull
@Size(max = 10)
@Getter
@Setter
private String name;
@OneToMany(mappedBy = "building")
@JsonManagedReference("building-location")
@ToString.Exclude
@Getter
private List<Location> locations = new ArrayList<>();
@Getter
@Setter
@Version
@Column(name = "lock_version")
private Integer lockVersion;
}
这是我的控制人
@PostMapping(value = "/")
@ResponseBody
public ResponseEntity<Response> createLocation(@Valid @RequestBody Location location) {
Location createdLocation = locationRepository.save(location);
return ResponseEntity.ok(
new Response(ResponseTypeEnum.Success, createdLocation)
);
}
这是请求正文:
{
"name": "Kitchen",
"building": {
"id": 9
}
}
我遇到的问题是JPA无法识别建筑对象,因此当我尝试保存位置时,出现以下异常:
SQLException Column 'building_id' cannot be null. Query is: insert into location (building_id, lock_version, name) values (?, ?, ?), parameters [<null>,0,'Yoga Room']
。
如果我使用findById
从数据库中获取建筑物,然后在Location对象中设置建筑物属性,则该属性将起作用,但我不想获取该对象以保存Location实例。我只想传递外键并保存新实例。
我可以使用JPA吗?
答案 0 :(得分:1)
尝试在Location类中添加buildingId字段
public class Location implements Serializable {
...
@Getter
@Setter
@Column(name = "building_id")
@JsonProperty("building_id")
private Integer buildingId;
...
}
然后您可以随身发送请求
{
"name": "Kitchen",
"building_id": 9
}
答案 1 :(得分:0)
您无法在JPA中执行此操作,但是,如果您不想访问Building实体的数据库,则可以选择一种替代解决方案,那就是加载引用:
Building b = buildingRepository.getOne(buildingId);
location.setBuilding(b);
Location createdLocation = locationRepository.save(location);
请记住,所有内容都必须在同一笔交易中。
getOne
javadoc:
返回对具有给定标识符的实体的引用。
答案 2 :(得分:0)
该异常声称存在一个空'building_id'
,这意味着传递的id
对象的building
是null
或未正确设置。
那是因为当您尝试save
实例时,JPA会尝试根据您的请求设置Location
属性,因此它需要设置building
但这不能做到这一点,因为您尚未在id
实体中为setter
定义id
方法。
您需要更改代码以添加带有lombok批注的setter方法:
Building
答案 3 :(得分:0)
对我有用的解决方案如下:
$result= $query->queryOne();
$this->setAttributes($result);