오늘도 시작된 오류타임~!
심지어 이거 전에 마주친 오류임 ㅎ~!ㅋㅋㅋㅋ!!!!!!!!!! 🖕🖕🖕🖕
그때 적어놨으면 쉽게 해결했을텐데
또 오류 기록 안해서 같은 오류도 두번 검색해서 찾아내쥬 ㅎㅎㅋ~! 내 수준 알만하고~~~
전에 상품을 등록할때 회원의번호도 함께 저장되게 하기 위해서 상품TABLE과 회원TABLE을 조인할때 마주했던 오류이다.
이번에 배송정책TABLE에 회원번호도 저장하려고 하니 뜬 오류이니... 같은 방법으로 해결하면 되것지 머....
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : growto.entity.DeliveryEntity.memberEntity -> growto.entity.MemberEntity at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:379) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:169) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:159) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:149) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:82) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:489) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3303) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2438) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:449) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
해당 오류는 @OneToMany
@ManyToOne
애너테이션을 사용할 때 뜨는 오류라고 한다..
FK 영속화 문제라고도 한다..
FK가 없는 상태에서 데이터를 저장할 때 발생하는 에러!
이러한 문제를 해결하기 위해서는
영속성전이를 해주면 되는데
매핑을 위한 애너테이션들에 cascade 설정을 진행해주면 간단하게 해결 가능하다~!
cascade=CascadeType.ALL
그렇다면 CascadeType에는 어떤것들이 있을까?
종류 | 설명 |
---|---|
CascadeType.PERSIST | 하위 엔티티까지 영속성 전달 엔티티를 생성하고, 연관 엔티티를 추가한 상태로 영속화할 때 연관 엔티티도 함께 persist()가 수행된다. |
CascadeType.MERGE | 하위 엔티티까지 병합 작업 지속 트랜잭션이 종료되고 detach 상태에서 연관 엔티티를 추가하거나 변경된 이후에 부모 엔티티가 merge를 수행하게 되면 변경사항이 연관 엔티티에도 적용된다. |
CascadeType.REMOVE | 하위 엔티티까지 제거 작업 지속 엔티티를 삭제할 때 이 필드에 보유된 엔티티도 삭제한다. |
CascadeType.REFRESH | 데이터베이스로부터 인스턴스 값을 다시 읽어옴 (새로고침) 엔티티를 새로고칠 때 이 필드에 보유된 엔티티도 새로고친다. |
CascadeType.DETACH | 영속성 컨텍스트에서 엔티티 제거 부모 엔티티가 detach()를 수행하게 되면 연관된 엔티티도 detach()상태가 되어 변경사항이 반영되지 않는다. |
CascadeType.ALL | 상위 엔티티에서 하위 엔티티로 모든 작업을 전파 모든 cascade를 적용시킨다. |
이때 대갈쓰를 스쳐가는 한가지가,
나 로그인상태가 아니라 회원에 대한 정보를 못가져 오는구나...
그도 그럴게.. 저장할때의 controller코드에서 memberNo를 가져오는 코드는 이것이니까,,!
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String userEmail = authentication.getName(); Long memberId = (Long)memberService.getMemberIdByEmail(userEmail);
casecadeType 지정 안해주고 그냥 로그인하니까 너무 저장 잘되는거임 ^^~!
...
에혀...
아~~~주 잘 저장된다.. 오류 없이..
안녕하세요? 바보입니다?