두번 정도 마주친적이 있는 object references an unsaved transient instance - save the transient instance before flushing 에러인데, 어떤 에러이고 어떻게 해결할 수 있는지 알아보려고 합니다.
org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.TransientPropertyValueException:
//(1)
object references an unsaved transient instance
- save the transient instance before flushing :
com.codestates.order.entity.OrderCoffee.order -> com.codestates.order.entity.Order;
nested exception is java.lang.IllegalStateException:
org.hibernate.TransientPropertyValueException:
object references an unsaved transient instance
- save the transient instance before flushing :
com.codestates.order.entity.OrderCoffee.order
-> com.codestates.order.entity.Order //(2)
에러 내용을 끊어서 살펴보면
(1) 부분에서 어떤 문제인지 알려주고 있습니다. object가 저장되어 있지 않은 transient instance를 참조한다고 하네요. 그러니 flushing 전에 해당 transient instance를 저장하라고 알려줍니다.
정확히는 이해를 못했지만 무언가 object와 연관이 있는 instance가 저장이 안되었는데 참조 시도를 하니 문제가 발생했다는 것 같습니다. 에러 메세지에서 알려준 것처럼 해당 instance가 왜 저장이 안되었는지 확인하고 저장될 수 있도록 조치해야겠습니다.
에러에 대해서 알아보니,
해당 에러는 PK-FK 관계가 있는 entity들을 mapping 해둘 때, FK에 해당하는 entity 객체가 DB에 저장되지 않아서 생기는 오류라고 합니다.
보통은 이런 경우에 부모 entity에서 cascade attribute를 지정해주면 된다고 합니다.
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
//...
@OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
private List<OrderCoffee> orderCoffees = new ArrayList<>();
//...
}
public class OrderCoffee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderCoffeeId;
//...
@ManyToOne
@JoinColumn(name = "ORDER_ID")
private Order order;
//...
}
그런데 저는 이미 그렇게 설정을 해놓았는데도 해당 에러를 만나게 됬습니다. 추측되는 원인은 Entity간 mapping을 담당하던 mapper class에서 잘못된 방식으로 객체를 생성하고 사용하려 해서 그랬던 것 같습니다.
에러가 나는 코드를 핵심적인 부분만 뽑아내면 아래와 같은데
@Mapper(componentModel = "spring")
public interface OrderMapper {
default OrderCoffee orderCoffeeDtoToOrderCoffee(OrderCoffeeDto orderCoffeeDto) {
OrderCoffee orderCoffee = new OrderCoffee();
//...
Order order = new Order();
//...
orderCoffee.addOrder(order);
return orderCoffee;
}
}
여기서 Order가 부모 entity, OrderCoffee가 자식 entity로 서로 1 : N 관계에 있습니다.
그런데 mapper에서 자식 entity인 OrderCofee가 저장되지 않은 order entity를 ordercofee의 멤버 변수에 할당하고
그 상태로 Service 계층에 가서 저장을 시도하려다 보니 에러가 발생했던 것으로 보입니다.
orderCoffeeDtoToOrderCoffee method를 사용하지 않고 다른 방안으로 에러를 없애기는 했지만, 이 method를 살릴 수 있는 방안은 없을 지 한 번 탐구해 봐야 될 것 같습니다.
참고자료
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rorean&logNo=221479709787
https://bcp0109.tistory.com/344
'Error Handling Log' 카테고리의 다른 글
QueryDsl-required a bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' 해결방법 (2) | 2022.10.08 |
---|---|
Parameter 2 of constructor in ... that could not be found error (0) | 2022.09.27 |
.gitignore 파일에 등록된 파일이 이미 commit되어 있는 경우 (0) | 2022.09.05 |
Circular Dependencies error (0) | 2022.07.25 |
Content type 'text/plain;charset=UTF-8' not supported 에러 (0) | 2022.07.03 |