1

I come from a Java background. I'm having a bit of a dilemma, OrderDetail needs an Order before saving it and I need Order needs OrderDetail as well. I thought the best approach was first creating the Order and with this, I will get the Order ID which I pass to the OrderDetail objects that are being created. Now the issue is that orderDetails is a val and cannot be reassigned, so order.orderDetails = orderDetails does not work. A fix would be changing orderDetails to a var in the JPA Object class, but I feel this defeats the purpose of removing as much mutability as possible.

@RestController
@RequestMapping("/order")
class OrderController(val orderRepository: OrderRepository, val productRepository: ProductRepository) {
    //    @GetMapping
    //    fun findOrdersByUser(): Iterable<ViewOrder> = orderRepository.findAll().map { it.toView() };

    @PostMapping
    fun create(@RequestBody createOrderRequest: CreateOrderRequest): ResponseEntity<ViewOrder> {
        val order = orderRepository.save(
            Order(
                status = OrderStatus.CONFIRMED,
                orderPlacedDate = Date(),
                totalPrice = BigDecimal.ZERO,
                totalWeight = BigDecimal.ZERO,
            )
        )

        val orderDetails = createOrderRequest.products.mapNotNull {
            productRepository.findById(it.productId).orElse(null)?.let { product ->
                OrderDetail(
                    product = product,
                    quantity = it.quantity,
                    currencyCode = CurrencyCode.DZD,
                    uom = product.uom,
                    price = product.price * it.quantity,
                    order = order
                )
            }
        }

        // Update order
        order.orderDetails = orderDetails
        orderRepository.save(order)

        return ResponseEntity.status(HttpStatus.CREATED).body(order.toView())
    }
} 
1
  • This looks like an example of a circular dependency. Is there any reason why OrderDetail needs to be a property of Order? If Order and OrderDetail are always instantiated together I think they should be a a single class instead. Commented Jul 10 at 20:22

1 Answer 1

0

Since you didn't provide the data structure of the classes involved I assume the type of order to be a data class with val properties defined in the constructor.

Data classes have some additional features regular classes don't have, for instance, an automatically generated copy function. That creates a new object with all (constructor) properties copied over to the new object. You can also replace any of the properties with new values:

// Update order
val newOrder = order.copy(
    orderDetails = orderDetails,
)
orderRepository.save(newOrder)

This new object is also immutable and resembles the original order, except that it has one changed property the orderDetails. This is the usual way to emulate changing immutable objects in Kotlin.

Not the answer you're looking for? Browse other questions tagged or ask your own question.