9

This question arised from my work on a Grails application, but it applies to pretty much every web application developed in layers. Here's a simple example:

class OrderService {

    // Option 1
    def shipOrder(Order order) {
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

    // Option 2
    def shipOrder(long orderId) {
        def order = Order.get(orderId)
        order.status = OrderStatus.SHIPPED
        emailService.sendShipmentEmail(order)
        // ...
    }

}

Is any of these options documented as being better than the other one?

TylerH
  • 20,799
  • 66
  • 75
  • 101
André Willik Valenti
  • 1,702
  • 14
  • 21

1 Answers1

9

I tend to prefer ids, since you sometimes want to use pessimistic locking, and then it's easy to change Order.get(orderId) to Order.lock(orderId). Locking has to happen in a transaction, so using the first approach you'd lock after reading, running the small risk of update in-between.

Sometimes it's necessary to load the instance outside of the service, e.g. to test for existence in the controller, so the second approach can feel like it wastes a database call. But you can change the get() call to an exists() call and only check for the existence of the id, rather than loading the entire instance just to see if it's there.

Note that you should use long orderId in your method signature since allowing a null id doesn't make sense.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
  • +1 Absolute postmortem of the use case. Especially `exists()`, I see that a lot in my workplace. :) – dmahapatro Jul 03 '13 at 19:01
  • 1
    Interesting. I didn't knew about `exists()`. –  Jul 03 '13 at 19:33
  • Me neither. Also, I heard Groovy treated long and Long the same (differently from Java). Now I just confirmed that long can't be null, indeed! Changed the code above. Thanks! – André Willik Valenti Jul 03 '13 at 20:45
  • @AndréValenti Objects can be null, primitive datatypes cannot. If you provide `Long id` there is a possibility of `id` being sent as `null`. The possibility is eradicated when `long id` is used. – dmahapatro Jul 03 '13 at 20:51
  • @dmahapatro I knew Java was that way, but thought Groovy treated everything as objects. – André Willik Valenti Jul 04 '13 at 12:55
  • It does, but it really just autoboxes for you (even in 1.4 before it was available in Java). So for example you can call methods on primitives (e.g. 4.times { ... } ). But it doesn't extend to nullability - you cannot have a null primitive. – Burt Beckwith Jul 04 '13 at 13:59
  • @BurtBeckwith Now that's a peculiar behavior! – André Willik Valenti Jul 15 '13 at 19:37