Search code examples
javapostgresqlactivejdbc

ActiveJDBC: save() generates insert only for auto-generated primary key?


I recently started using ActiveJDBC. I have the following table (postgresql)

CREATE TABLE users (
    id                   uuid PRIMARY KEY,
    email                text UNIQUE NOT NULL,
    password             text,
    <some more nullable columns>
    created_at           timestamp with time zone NOT NULL default (now() at time zone 'utc'),
    updated_at           timestamp with time zone
);

As you can see, the primary key is of type uuid and has no auto-generate value of any kind.

This is my User class which models the table :

public class User extends Model
{
    public User() {
        setId(UUID.randomUUID());  // sets value to primary key
    }
...
}

This is my attempt to create a new row and insert it :

    User u = new User();
    System.out.println(u.saveIt());

actually, I expected the insert to fail, since I did not set any value for mandatory email column. However, simply got false as return value. when I turned on logging, I saw that the framework generated an update sql instead of insert:

[main] INFO org.javalite.activejdbc.DB - Query: "UPDATE users SET email = ?, ..., updated_at = ? WHERE id = ?", with parameters: <null>, <null>, <null>, <null>, <null>, <null>, <null>, <2016-01-07 17:30:46.025>, <0621fbdb-5b95-4ee7-a474-8ee9165e2982>, took: 1 milliseconds

so I looked at the save() method inside org.javalite.activejdbc.Model class and saw this piece of code:

    if (getId() == null) {
        result = insert();
    } else {
        result = update();
    }

does this mean that id column has to be empty in order for an insert to be generated ? if this is true this is unacceptable, so I must be missing something.


Solution

  • @sharonbn, please, see this documentation page: http://javalite.io/surrogate_primary_keys. ActiveJDBC depends on autogenerated IDs. If the ID == null, the frameworks assumes this is a new record, and generates INSERT statement. If it is non-null, it is assumed the record already exists, and generates UPDATE.

    In your case, you will need to explicitly call user.insert() instead of user.saveIt(). This is an 'expert' mode in cases when developers want to be in control of ID management. Further, the method user.update() is private. So for you to insert a new record, you will be calling

    user.insert();

    and for updates:

    user.save(); // or: user.saveIt();

    , depending on what you want.