작성
·
376
0
"not-null property references a null or transient value : com.example.orderservice.jpa.OrderEntity.orderId; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.example.orderservice.jpa.OrderEntity.orderId"
이 오류는 com.example.orderservice.jpa.OrderEntity
클래스의 orderId
속성이 null 또는 임시 값으로 설정되어 있을 때 발생합니다. 즉, orderId
속성에는 null이 허용되지 않는데, null이나 임시 값으로 설정되었기 때문에 오류가 발생합니다.
application.yml
server:
port: 0
spring:
application:
name: order-service
h2:
console:
enabled: true
settings:
web-allow-others: true
path: /h2-console
sql:
init:
mode: always
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show_sql: true
defer-datasource-initialization: true
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb
main:
allow-bean-definition-overriding: true
eureka:
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
logging:
level:
com.example.orderservice: DEBUG
OrderEntity
@Data
@Entity
@Table(name = "orders")
public class OrderEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 120, unique = true)
private String productId;
@Column(nullable = false)
private Integer qty;
@Column(nullable = false)
private Integer unitPrice;
@Column(nullable = false)
private Integer totalPrice;
@Column(nullable = false)
private String userId;
@Column(nullable = false, unique = true)
private String orderId;
@Column(nullable = false, updatable = false, insertable = false)
@ColumnDefault(value = "CURRENT_TIMESTAMP")
private Date createAt;
}
OrderDto
@Data
public class OrderDto implements Serializable {
private String productId;
private Integer qty;
private Integer unitPrice;
private Integer totalPrice;
private String orderId;
private String userId;
}
ResponseOrder
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseOrder {
private String productId;
private Integer qty;
private Integer unitPrice;
private Integer totalPrice;
private Date createAt;
private String orderId;
}
OrderService
public interface OrderService {
OrderDto createOrder(OrderDto orderDetails);
OrderDto getOrderByOrderId(String orderId);
Iterable<OrderEntity> getOrdersByUserId(String userId);
}
OrderServiceImpl
@Service
public class OrderServiceImpl implements OrderService{
OrderRepository orderRepository;
@Autowired
public OrderServiceImpl(OrderRepository orderRepository){
this.orderRepository = orderRepository;
}
@Override
public OrderDto createOrder(OrderDto orderDto){
orderDto.setUserId(UUID.randomUUID().toString());
orderDto.setTotalPrice(orderDto.getQty() * orderDto.getUnitPrice());
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderEntity orderEntity = mapper.map(orderDto, OrderEntity.class);
orderRepository.save(orderEntity);
OrderDto returnValue = mapper.map(orderEntity, OrderDto.class);
return returnValue;
}
@Override
public OrderDto getOrderByOrderId(String orderId) {
OrderEntity orderEntity = orderRepository.findByOrderId(orderId);
OrderDto orderDto = new ModelMapper().map(orderEntity, OrderDto.class);
return orderDto;
}
@Override
public Iterable<OrderEntity> getOrdersByUserId(String userId) {
return orderRepository.findByUserId(userId);
}
}
OrderController
@RestController
@RequestMapping("/order-service")
public class OrderController {
Environment env;
OrderService orderService;
@Autowired
public OrderController(Environment env, OrderService orderService) {
this.env = env;
this.orderService = orderService;
}
@GetMapping("/health_check")
public String status(){
return String.format("It's Working in Order Service on PORT %s",
env.getProperty("local.server.port"));
}
// http://127.0.0.1:0/order-service/{user_id}/orders/
@PostMapping("/{userId}/orders")
public ResponseEntity<ResponseOrder> createOrder(@PathVariable("userId") String userId,
@RequestBody RequestOrder orderDetails){
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderDto orderDto = mapper.map(orderDetails, OrderDto.class);
orderDto.setUserId(userId);
OrderDto createOrder = orderService.createOrder(orderDto);
ResponseOrder responseOrder = mapper.map(createOrder, ResponseOrder.class);
return ResponseEntity.status(HttpStatus.CREATED).body(responseOrder);
}
@GetMapping("/{userId}/orders")
public ResponseEntity<List<ResponseOrder>> getOrder(@PathVariable("userId") String userId){
Iterable<OrderEntity> orderList = orderService.getOrdersByUserId(userId);
List<ResponseOrder> result = new ArrayList<>();
orderList.forEach(v -> {
result.add(new ModelMapper().map(v, ResponseOrder.class));
});
return ResponseEntity.status(HttpStatus.OK).body(result);
}
}
다 똑같이 쳤는데 뭐가 문제일까요?
답변 1
0
OrderServiceImpl createOrder에
orderDto.setUserId(orderDto.getUserId()); 추가해주니까 됩니다만. 강사님이 코딩하신 것에는 이 코드가 없었거든요? 뭔 차이일까요?
버전문제인가요?
OrderServiceImpl
orderDto.setUserId(orderDto.getUserId()); 추가
springboot : <version>2.7.13</version>
spring-cloud: <spring-cloud.version>2021.0.7</spring-cloud.version>
제가 사용중인 버전입니다.
@Override
public OrderDto createOrder(OrderDto orderDto){
orderDto.setOrderId(UUID.randomUUID().toString());
orderDto.setUserId(orderDto.getUserId()); // 이 부분이 추가한 부분입니다
orderDto.setTotalPrice(orderDto.getQty() * orderDto.getUnitPrice());
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
OrderEntity orderEntity = mapper.map(orderDto, OrderEntity.class);
orderRepository.save(orderEntity);
OrderDto returnValue = mapper.map(orderEntity, OrderDto.class);
return returnValue;
}
제가 한 것처럼 코딩후 postman으로 data입력한 뒤 h2-console들어가면
이렇게 강사님이 하신 것처럼 생성됩니다.
안녕하세요, 이도원입니다.
올려주신 오류는 nullable=true로 되어 있는 Property에 null이 지정되어서 발생하는 오류입니다. 제가 공유해 드린 코드에도 OrderController에서 ordeDto.setUserId(userId)를 처리하는 부분이 있습니다. 따라서 OrderServiceImpl 에서는 orderDto.setUserId(orderDto.getUserId()); 가 필요하지 않습니다.
한가지 의문스러운 점은 올려주신 오류는 orderId에 대해 not-null property references a null or transient value 오류가 발생했는데, userId에 대한 처리를 하니 오류가 없어졌다는 부분이네요. 작업하신 코드를 공유해 주시면 해당 버전으로 다시 테스트 해 보도록 하겠습니다.
제가 작업한 order-service의 버전은 아래와 같습니다 .
spring-boot: 2.7.6
spring-cloud: 2021.0.3
감사합니다.