Java - Spring Boot - Hibernate - JPA(@ManyToOne 发布错误)
Posted
技术标签:
【中文标题】Java - Spring Boot - Hibernate - JPA(@ManyToOne 发布错误)【英文标题】:Java - Spring Boot - Hibernate - JPA (Error with post @ManyToOne) 【发布时间】:2021-07-26 22:36:30 【问题描述】:我有两个模型,一个给客户,一个给卖家,在客户表中我只需要一个卖家,已经在卖家表中,我可以为一个卖家有多个客户。
但是当我尝试添加新客户并设置销售人员的 ID 时,它就不起作用了。
代码如下:
卖家型号:
package com.crud.spring.jpa.postgresql.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@AllArgsConstructor
@Getter
@Setter
@Table(name = "sellers", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
public class Seller
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "code")
private long code;
@Column(name = "name")
private String name;
public Seller()
客户端模型:
package com.crud.spring.jpa.postgresql.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
@Entity
@AllArgsConstructor
@Getter
@Setter
@Table(name = "clients", uniqueConstraints = @UniqueConstraint(columnNames = "code"))
public class Client
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "code")
private long code;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "seller_id", referencedColumnName = "id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private Seller seller;
public Client()
客户端控制器:
@PostMapping("/clients")
public ResponseEntity createClients(@RequestBody Client client)
return this.service.createClients(client);
客户服务:
public ResponseEntity createClients(Client client)
try
client = this.repository.save(client);
return new ResponseEntity(client, HttpStatus.OK);
catch (Exception e)
return new ResponseEntity(e, HttpStatus.INTERNAL_SERVER_ERROR);
后卖家:
发布客户:
错误是:
"entityName": "com.crud.spring.jpa.postgresql.model.Client", "propertyName": "seller", "message": "not-null property references a 空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller", "localizedMessage": "非空属性引用空或瞬态 值:com.crud.spring.jpa.postgresql.model.Client.seller", "suppressed": [] "message": "not-null 属性引用了一个 null 或 瞬态值:com.crud.spring.jpa.postgresql.model.Client.seller; 嵌套异常是 org.hibernate.PropertyValueException: not-null 属性引用空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller",
enter code here
"localizedMessage": "not-null 属性引用了 null 或 瞬态值:com.crud.spring.jpa.postgresql.model.Client.seller; 嵌套异常是 org.hibernate.PropertyValueException: not-null 属性引用空值或瞬态值: com.crud.spring.jpa.postgresql.model.Client.seller",
【问题讨论】:
【参考方案1】:尝试使用 json "seller":"id":15
insted of "seller_id":15
【讨论】:
不要这样做。我如何这样工作: "code": 1, "name": "Eduardo", "seller_id": 15 "code": 1, "name": "Eduardo","seller":"id":15
你应该这样尝试,因为当你引用卖家时,你引用了一个你会通过它的 id 找到的类
我设法改善了帖子中代码的可视化,您可以再检查一下吗?【参考方案2】:
所以,有一些更正: 当您的有效载荷包含现有卖家的 id 时:
-
使用有效负载发送现有卖家 ID
"code" : 216,
"name" : "addclientforseller5",
"seller" :
"id" : 5
-
在您的服务实现中添加此代码
public Client createClients(Client client)
Long sellerId = client.getSeller().getId();
Optional<Seller> existingSeller = sellerRepository.findById(sellerId);
if (existingSeller.isPresent())
Seller savedSellerObject = existingSeller.get();
client.setSeller(savedSellerObject);
else
// throw exception
return clientSellerRepository.save(client); // you can return ResponseEntity also
当您的有效负载包含卖家对象以创建新卖家时,请执行以下操作:
-
有效负载应如下所示
"code" : 112,
"name" : "Pure",
"seller" :
"code" : 1111,
"name" : "Guava"
-
将此代码添加到您的服务实现中
@Autowired
ClientRepository clientRepository;
@Autowired
SellerRepository sellerRepository;
public Client createClients(Client client)
Seller seller = new Seller();
seller.setCode(client.getSeller().getCode());
seller.setName(client.getSeller().getName());
Seller savedSeller = sellerRepository.save(seller);
client.setSeller(savedSeller);
return clientRepository.save(client);
-
从客户端类的卖方字段中删除 @JsonIngnore。
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "seller_id", referencedColumnName = "id")
@OnDelete(action = OnDeleteAction.CASCADE)
//@JsonIgnore
private Seller seller;
【讨论】:
不要这样做。我该如何工作:``` "code": 1, "name": "Eduardo", "seller_id": 15 `` 无法在有效负载中按照您的意愿发送请求。 我设法改进了帖子中代码的可视化,您可以再检查一下吗? 好的。如果我的回答解决了您的问题。请投票。 我不能只引用 ID 而不是客户端中的整个卖家对象吗?【参考方案3】:我已经模拟了您的代码并有以下观察结果以使其正常工作。
从客户端模型中移除 @JsonIgnore 注解 Jpa 基于对象引用而不是单独的值工作。因此,您可能需要修改客户端服务代码。 try
Optional<Seller> seller = sellerRepository.findById(client.getSeller().getId());
if(seller.isPresent())
client.setSeller(seller.get());
client = this.repository.save(client);
return new ResponseEntity(client, HttpStatus.OK);
catch (Exception e)
return new ResponseEntity(e, HttpStatus.INTERNAL_SERVER_ERROR);
在上面的代码中,我们使用请求客户端模型中的卖家 ID 并从 db 中获取卖家对象。然后我们设置对客户端模型的引用。
为 createClient 传递 Json 输入,如图所示
"id": 1,
"code": 2,
"name": "Client_1",
"seller":
"id": 1
注意:您必须先创建一个有效的卖家,然后才能通过传递卖家 ID 创建客户端。
【讨论】:
以上是关于Java - Spring Boot - Hibernate - JPA(@ManyToOne 发布错误)的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot入门 数据库访问之spring data jpa