从其他实体检索ID时的Spring Boot JPA反序列化问题
Posted
技术标签:
【中文标题】从其他实体检索ID时的Spring Boot JPA反序列化问题【英文标题】:Spring boot JPA deserialization problem when retrieving ID from other entity 【发布时间】:2020-10-17 06:02:30 【问题描述】:我正在创建一个 Web 程序,以使用 spring boot、tomcat 和 JPA 映射存储占用级别。 我已经创建了成员模型/服务/控制器,当我尝试对其进行更新、创建、删除或从中获取信息时,它可以正常工作。
但也没有创建商店,当我使用 ownerId 创建商店时,我收到一条错误消息:
错误信息
[org.springframework.http.converter.HttpMessageNotReadableException:JSON 解析错误:无法构造com.project.so2.models.Member
的实例(尽管至少存在一个创建者):没有字符串参数构造函数/工厂方法可以从字符串值反序列化('1');嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造 com.project.so2.models.Member
的实例(尽管至少存在一个 Creator):没有从字符串值反序列化的字符串参数构造函数/工厂方法('1')
在 [来源:(PushbackInputStream); line: 4, column: 18] (通过引用链: com.project.so2.models.Store["owner_id"])]
我已经尝试查找类似的问题,但我没有看到任何适用的解决方案。
模型
商店
@Entity(name = "Store")
@Table(name = "store")
@SequenceGenerator(name = "store_id")
public class Store
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "store_id")
@Column(name = "id")
private long id;
//many stores to one owner
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OnDelete(action = OnDeleteAction.CASCADE)
@JoinColumn(name = "owner_id", referencedColumnName = "id")
private Member owner_id;
//one store to many occupation level
@OneToMany(mappedBy = "store")
private List<Occupation> store_occupation;
@OneToOne(mappedBy = "store")
private Location location;
@Column(name = "name")
private String name;
@Column(name = "square_footage")
private String square_footage;
public Store()
会员
@Entity(name = "Member")
@Table(name = "member")
@SequenceGenerator(name = "member_id")
public class Member
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_id")
@Column(name = "id")
private long id;
@Enumerated(EnumType.STRING)
@Column(name = "role")
private Role role;//customer|admin|store_owner
@Column(name = "mail", unique = true)
private String mail;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "owner_id")
private List<Store> stores;
/**
* REALM to store passwords
*/
@CreationTimestamp
@Temporal(javax.persistence.TemporalType.DATE)
private Date createdAt;
@UpdateTimestamp
private Date updateAt;
存储控制器
@RestController
@RequestMapping("/store")
@ControllerAdvice()
@CrossOrigin
public class StoreController
@Autowired
private StoreService storeservice;
@PostMapping("/create")
public ResponseEntity<HttpStatus> createStore(@RequestBody Store store)
try
this.storeservice.saveStore(store);
return new ResponseEntity<>(HttpStatus.CREATED);
catch (Exception e)
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
商店服务
@Service
public class StoreService
@Autowired
private StoreRepository storeRepository;//
public void saveStore(Store store)
this.storeRepository.save(store);
请求负载:
"name": "Pingo Azedo",
"square_footage": "25m^2",
"owner_id":
"member_id": "1"
老实说,我不明白这个问题,也不知道如何解决它。如果有人可以提供帮助,将不胜感激!
【问题讨论】:
可以发一下全班商店和会员吗? 我刚刚做了,只是省略了 getter 和 setter @Hưng Chu 你能贴出异常的堆栈跟踪吗? 刚刚这样做了@YohanAloka 这可能是请求负载的问题,您也可以发布请求负载吗? 【参考方案1】:您正试图从 json 中反序列化成员,但杰克逊不知道如何仅使用“member_id”填写此成员,并且错误很明显是“找不到带有 String 的构造函数”。因此,为了获取成员 ID,您需要添加新的类请求 dto,例如:
String name;
String footage;
Long owner_id;
在您的控制器中使用您的新类,现在使用 owner_id,使用存储库在您的数据库中找到它,然后将其设置到您的商店。
【讨论】:
【参考方案2】:您需要在有效负载中使用属性名称,而不是列名称。如下更改您的请求负载,
"name": "Pingo Azedo",
"square_footage": "25m^2",
"owner_id":
"id" : 1
【讨论】:
以上是关于从其他实体检索ID时的Spring Boot JPA反序列化问题的主要内容,如果未能解决你的问题,请参考以下文章
JPA Spring Boot 微服务 - 使用两个多对一映射持久化实体时的无限循环