programing

Null이 아닌 속성이 과도 값을 참조함 - 현재 작업 전에 임시 인스턴스를 저장해야 합니다.

randomtip 2023. 4. 1. 22:53
반응형

Null이 아닌 속성이 과도 값을 참조함 - 현재 작업 전에 임시 인스턴스를 저장해야 합니다.

다음과 같은 2개의 도메인 모델과 1개의 Spring REST 컨트롤러가 있습니다.

@Entity
public class Customer{

@Id
private Long id;

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;

// other stuff with getters/setters

}

@Entity
public class Country{

@Id
@Column(name="COUNTRY_ID")
private Integer id;

// other stuff with getters/setters

}

스프링 레스트 컨트롤러:

@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {

   /**
    * Create new customer
    */
    @RequestMapping( method=RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    @ResponseBody
    public com.salesmanager.web.entity.customer.Customer createCustomer(@Valid @RequestBody   Customer customer, Model model, HttpServletRequest request, HttpServletResponse response) throws Exception {

        customerService.saveOrUpdate(customer);

        return customer;
    }

    // other stuff
}

아래의 JSON을 본체로 하여 위의 REST 서비스를 호출하려고 합니다.

{
    "firstname": "Tapas",
    "lastname": "Jena",
    "city": "Hyderabad",
    "country": "1"
}

Country 테이블에 국가 코드 1이 이미 있습니다.이 서비스를 호출하면 다음 오류가 발생합니다.

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation: com.test.model.Customer.country -> com.test.model.Country

어떤 도움이라도 감사합니다!

Cascade Type을 넣어보세요.모든.

@OneToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name="COUNTRY_ID", nullable=false) 

private Country country;

저도 비슷한 문제가 있었어요.2개의 엔티티:문서상태.문서에 관계가 있습니다.OneToMany상태(Status)를 사용하여 문서가 가지고 있는 상태 이력을 나타냅니다.

그래서...@NotNull @ManyToOne상태 내 문서 참조.

또한, 저는 문서의 실제 상태를 알아야 했습니다.그래서 이번에는 다른 관계가 필요했어@OneToOne,또한.@NotNull, 문서 .

문제는 두 엔티티 모두 첫 번째 엔티티를 어떻게 유지할 수 있느냐는 것이었습니다.@NotNull상대방에 대한 참조?

해결 방법은 다음과 같습니다.@NotNull로부터의 참조.actualStatus언급.이렇게 하면 두 엔티티를 모두 유지할 수 있었습니다.

같은 에러가 발생한 시나리오를 하나 더 추가해 보겠습니다.

존재하는 역참조가 늘이 아님을 확인합니다.

특히 제 경우엔,Mapstruct엔티티의 일부 필드를 업데이트합니다(예:

MyClass newInstance = //...
MyClass dbInstance = repository.findByField(someField);
MyClassMapper.MAPPER.update(dbInstance, newInstance);
repository.save(dbInstance);

그리고 제가 제대로 구현하지 못한MyClassMapper역참조를 주도하다dbInstance설정하는 필드null그들이 언제를 가리켜야 하는지dbInstance.

같은 에러가 발생하여 다음과 같이 해결했습니다.

첫 번째 엔티티:

    @Entity
    public class Person implements Serializable{
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int personId;
        private String name;
        private String email;
        private long phoneNumber;
        private String password;
        private String userType;
        @OneToOne(fetch = FetchType.LAZY, mappedBy = "personCustomer", cascade 
        = CascadeType.ALL)
        private Customer customer;

두 번째 엔티티:

@Entity
public class Customer implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int customerId;
    @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = 
    CascadeType.ALL)
    @JoinColumn(name = "person_customer")
    @JsonIgnore
    private Person personCustomer;

마이 컨트롤러:

@PostMapping("/customer/registration")
    public PersonCustomer addCustomer(@RequestBody Person person)
    {
        Customer customer = new Customer(person);
        person.setCustomer(customer);
        Customer cust = customerRepo.save(customer);
        logger.info("{}", cust);
        Optional<Person> person_Cust = 
        personRepo.findById(cust.getPersonCustomer().getPersonId());
        Person personNew = person_Cust.get();
        PersonCustomer personCust = new PersonCustomer();

        if(cust.equals(null))
        {   
            personCust.setStatus("FAIL");
            personCust.setMessage("Registration failed");
            personCust.setTimestamp(personCust.timeStamp());
        }
        personCust.setStatus("OK");
        personCust.setMessage("Registration OK");
        personCust.setTimestamp(personCust.timeStamp());
        personCust.setPerson(personNew);

        return personCust;
    }

"사람"을 붙이자 문제가 해결되었습니다.set Customer(고객);.양쪽 POJO 클래스에는 서로 참조가 있기 때문에 JPA 저장소 메서드(customerRepo.save(customer))를 사용하기 전에 서로 참조를 '설정'해야 합니다.

나도 똑같은 문제가 있었어.해결책은 다음과 같이 JSON을 전송하는 것입니다.

{
  "firstname": "Tapas",
  "lastname": "Jena",
  "city": "Hyderabad",
  "country": {"id":"1"}
}

그런 것 같다.@RequestBody는 고객 인스턴스가 국가 인스턴스를 참조하고 있기 때문에 단일 필드가 아닌 엔티티를 매핑하려고 합니다.

(나도 마찬가지로 2개의 엔티티가 결합되어 있습니다.DB에서 참조된 엔티티(고객의 경우 국가)에 대한 레코드가 이미 생성되었지만, json이 있는 엔티티(고객의 경우)에 동일한 오류 메시지가 표시되었습니다.캐스케이드 타입은요.모두 어쩔 수 없었지만, JSON의 상기의 변경에 의해 문제가 해결되었습니다.캐스케이드 추가 설정유형을 고려할 수 있습니다.)

변경해야 합니다.

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;

대상:

@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID")
private Country country;

nullable 설정을 삭제합니다.

언급URL : https://stackoverflow.com/questions/19074278/not-null-property-references-a-transient-value-transient-instance-must-be-save

반응형