Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- http 버전별 개선점
- AWS Spring MySQL Redis
- php 통신흐름
- jwt 탄생배경
- 배열 컬렉션 변환
- 스프링 값 받아오기
- 데이터베이스 언어 종류
- Test NullPointerException
- ajax 통신
- Java Roadmap
- Java 로드맵
- 네트워크 구성 요소
- 주요 네트워크 종류
- AWS EC2 Spring 서버
- 테스트 필드주입 Null
- php 통신
- unknown database
- mod_php vs php-fpm
- jwt 특징
- 데이터베이스 설계 순서
- ajax 단점
- 컬렉션 배열 변환
- http 변화
- php 통신구조
- ajax 특징
- ajax 장점
- 스프링 데이터 전달
- 화살표 함수 this
- 스프링 HTTP 통신
- http 버전별 단점
Archives
- Today
- Total
zkvn99
[Java Spring] TransientPropertyValueException 본문
Hibernate와 JPA를 사용하여 데이터베이스에 엔터티를 저장하려고 할 때 발생하는 예외
19:46:14.178 [http-nio-8888-exec-5] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : laundry.daeseda.entity.order.OrderEntity.address -> laundry.daeseda.entity.user.AddressEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : laundry.daeseda.entity.order.OrderEntity.address -> laundry.daeseda.entity.user.AddressEntity] with root cause
org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : laundry.daeseda.entity.order.OrderEntity.address -> laundry.daeseda.entity.user.AddressEntity
클라이언트 측에서 JSON으로 DTO 객체를 넘겨준 것을 그대로 Entity로 만들고 그걸 외래키로 설정해서 문제가 발생한 것 같다
@Entity
@Table(name = "orders")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderEntity extends BaseTimeEntity {
@Id
@Column(name = "order_id")
@GeneratedValue
private Long orderId;
@ManyToOne
@JoinColumn(name = "user_id")
private UserEntity user;
@ManyToOne
@JoinColumn(name = "address_id")
private AddressEntity address;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
@Column
private List<ClothesCountEntity> clothesCounts;
@Enumerated(EnumType.STRING)
@Column
private OrderStatus orderStatus;
@Column
private int totalPrice;
@Column
private String washingMethod;
@Column
private LocalDate pickupDate;
@Column
private LocalDate deliveryDate;
@Column
private String deliveryLocation;
}
곰곰히 생각해보니 OrderEntity에 address 속성이 영속화 되지 않은 주소 엔티티를 참조하고 있어서 발생한 것이다
주문을 할 때마다 DB에 쿼리문을 날리는 양이 많아질까봐 줄이고 줄이다가 이렇게 된것이다..
Transient 상태의 엔티티는 JPA 관점에서는 데이터베이스와 관련이 없으며, 영속성 컨텍스트에 존재하지 않는 것으로 취급된다
다양한 해결방법이 있겠지만, 이번 목표는 Entity 클래스에서 Setter를 사용하지 않는 것이기에 욕심을 버리고 DB 접근으로 해결했다
@Transactional
public void requestOrder(OrderDto orderDto) {
String currentUserEmail = SecurityUtil.getCurrentUsername().get();
UserEntity currentUser = userRepository.findByUserEmail(currentUserEmail).orElse(null);
if (currentUser != null) {
AddressEntity address = addressRepository.findById(orderDto.getAddress().getAddressId())
.orElseThrow(() -> new EntityNotFoundException("주소를 찾을 수 없습니다. ID: " + orderDto.getAddress().getAddressId()));
OrderEntity orderEntity = OrderEntity.builder()
.user(currentUser)
.address(address)
.deliveryLocation(orderDto.getDeliveryLocation())
.totalPrice(orderDto.getTotalPrice())
.orderStatus(OrderStatus.ORDER)
.washingMethod(orderDto.getWashingMethod())
.pickupDate(orderDto.getPickupDate())
.deliveryDate(orderDto.getDeliveryDate())
.build();
orderEntity = orderRepository.save(orderEntity);
List<ClothesCountDto> clothesCountDtoList = orderDto.getClothesCount();
System.out.println(clothesCountDtoList != null);
if (clothesCountDtoList != null) {
for (ClothesCountDto clothesCountDto : clothesCountDtoList) {
ClothesEntity clothesEntity = clothesRepository.findById(clothesCountDto.getClothes().getClothesId())
.orElseThrow(() -> new EntityNotFoundException("의류를 찾을 수 없습니다. ID: " + clothesCountDto.getClothes().getClothesId()));
ClothesCountEntity clothesCount = ClothesCountEntity.builder()
.clothes(clothesEntity)
.count(clothesCountDto.getCount())
.order(orderEntity)
.build();
orderClothesRepository.save(clothesCount);
}
}
}
}
이전 소스가 없어서 아쉽지만 주문 부분에서 DTO로 받아온 값을 통해서 주소를 조회한 값을 주문 Entity에 넣어주었다
'Trouble Shooting > Java' 카테고리의 다른 글
[Java Spring] Test NullPointerException (0) | 2023.09.17 |
---|