Chris Smith
Chris Smith

Reputation: 3012

Get id of domain object after creation

I'm working on a checkout, when the user goes to make a purchase, a Purchase object is created and saved to the database. I then take the id of the object and send it off to PayPal to generate a button (that way I can identify the purchase later on). However, when I attempt to retrive the id, it returns null.

I've tried flushing it before I access the id, but it still doesn't seem to be working.

Here is my domain object:

package website

import java.time.Instant
import java.time.temporal.ChronoUnit

class Purchase {
    String buttonId
    final Instant expires
    private boolean complete

    User user
    Product product

    Purchase(Product product, User user) {
        this.product = product
        this.user = user

        expires = Instant.now().plus(1, ChronoUnit.DAYS)
    }

    void completePurchase() {
        // confirm that the purchase hasn't been completed already
        if (complete) {
            throw new PurchaseAlreadyCompleteException()
        }

        complete = true
    }

    boolean isComplete() {
        return complete
    }

    static class ButtonIdAlreadyInitializedException extends RuntimeException {}

    static class PurchaseAlreadyCompleteException extends RuntimeException {}
}

Here is the code I am running:

Purchase purchase = new Purchase(product, user)
purchase.save(flush: true)
println 'purchase id: ' + purchase.id

Upvotes: 1

Views: 1639

Answers (2)

Steve Hole
Steve Hole

Reputation: 358

You need to capture the result of the purchase.save() method. It returns the updated domain object with the resolved id inside. Therefore your code should look like:

Purchase purchase = new Purchase(product, user)
purchase = purchase.save(flush: true)
if (!purchase || purchase.hasErrors()) {
    log.error("Failed to commit purchase - probable validation errors')
}
println 'purchase id: ' + purchase.id

Note that if you set the failOnError: true flag in the save method, then it will throw an exception if there are validation or hibernate/SQL errors that prevent the saving of the method. I find I like exception handling better than the soft checks that I provided above.

Also, as you have no constraints block in your domain definition, all fields will be nullable: false by default, so you MUST provide a value for buttonId or the domain will fail to validate and the purchase.save() method call will fail.

Upvotes: 1

Dónal
Dónal

Reputation: 187389

The ID is null because your object is not being saved. The reason it's not being saved is because you're not assigning a value to buttonId, and this property is required. You can verify this with:

Purchase purchase = new Purchase(product, user)
purchase.save(flush: true, failOnError: true) // will throw an exception if saving fails
println 'purchase id: ' + purchase.id

Upvotes: 4

Related Questions