본문 바로가기
Error Handling Log

Hibernate에러: object references an unsaved transient instance - save the transient instance before flushing

by GGShin 2022. 7. 14.

두번 정도 마주친적이 있는  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://stackoverflow.com/questions/2302802/how-to-fix-the-hibernate-object-references-an-unsaved-transient-instance-save

 

How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error

I receive following error when I save the object using Hibernate object references an unsaved transient instance - save the transient instance before flushing

stackoverflow.com

 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rorean&logNo=221479709787 

 

[JPA]object references an unsaved transient instance - save the transient instance before flushing

JPA로 초기 데이터 만들다가 만난 에러..! @OneToMany나 @ManyToMany인 상황에서 흔히 만나는 에...

blog.naver.com

 

https://bcp0109.tistory.com/344

 

JPA 관련 Hibernate 에러: object references an unsaved transient instance - save the transient instance before flushing

에러 로그 TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing 원인 JPA 연관 관계 테스트 중에 발생했습니다. FK 로 사용되는..

bcp0109.tistory.com

 

반응형