首页 > 解决方案 > OneToOne ConstraintViolation 同时保存新记录,PK 提供

问题描述

我们有一个名为 EntityCustomers的 Entity 与 Entity 有 OneToOne 关系Address

CustomerPK 应手动定义。Address' PK 应该是自动定义的。

因此,在Customer我省略了@GeneratedValue并且我提供的是手动值。但是,在尝试保存时,出现以下错误:

2018-11-07 10:42:17.810 ERROR 1257 --- [nio-8080-exec-2] o.h.i.ExceptionMapperStandardImpl        : HHH000346: Error during managed flush [Validation failed for classes [br.com.customers.entity.Address] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='não pode ser nulo', propertyPath=street, rootBeanClass=class br.com.customers.entity.Address, messageTemplate='{javax.validation.constraints.NotNull.message}'}

问题是address.street正在提供,我不明白为什么 JPA 抱怨它是空的......

这是我要保存的 JSON 正文。(它被正确反序列化,因为地址不为空)

{
    "customer_Id": 50,
    "name": "name",
    "company_name": "company_name",
    "email": "email@provider.com",
    "business_phone": "(00) 1111-2222",
    "mobile_phone": "(00) 1111-2222",
    "document": "123456789",
    "state_registration_number": "ISENTO",
    "state_registration_type": "NO_CONTRIBUTOR",
    "city_registration_number": "ISENTO",
    "classification": "AUTO",
    "address": {
        "street": "STREET NAME",
        "number": "NUMBER",
        "complement": "COMPLEMENT",
        "zip_code": "ZIP_CODE",
        "neighborhood": "NEIGHBORHOOD",
        "city": "CITY",
        "state": "STATE"
    }
}

以下是客户实体:

@Data
@Entity(name = "X_CUSTOMERS")
public class Customer {

    @Id
    private int customer_Id;

    @NotNull
    private String name;

    private String company_name;

    private String email;

    private String business_phone;

    private String mobile_phone;

    @NotNull
    private String document;

    private String state_registration_number;

    private String state_registration_type;

    private String city_registration_number;

    @NotNull
    private String classification;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinColumn(name = "address_id")
    private Address address;

}

在这里,地址实体:

@Data
@Entity(name = "X_ADDRESS")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int address_Id;

    @NotNull
    private String street;

    private String number;

    private String complement;

    private String zip_code;

    private String neighborhood;

    private String city;

    private String state;

}

我究竟做错了什么?谢谢!!!


添加代码确实保留了实体:

客户资料库:

public interface CustomerRepository extends JpaRepository<Customer, Integer> {

}

坚持:

@RestController
@RequestMapping("/customers")
public class CustomersController {

    private CustomerRepository customerRepository;

    public CustomersController(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }

    @PostMapping
    public Customer postCustomer(@RequestBody Customer customer) {
        return customerRepository.save(customer);
    }


}

标签: springhibernatespring-bootjpa

解决方案


通过阅读 Hibernate 文档,保存操作仅保留具有自动生成的 id 的实体。因此,如果您打算自己设置 id,那么您需要的是更改您的插入方法以进行持久化。而且由于您的客户的 id 不是自动生成的,所以这可能是问题所在。您可以在此博客中阅读更多内容。

@PostMapping
public Customer postCustomer(@RequestBody Customer customer) {
    return customerRepository.persist(customer);
}

希望能帮助到你。


推荐阅读