@Id

Mark a property as the @Id property.

@Entity
public class Contact {

  @Id
  long id;

  ...
}

@GeneratedValue

When we annotate a property with @Id Ebean will automatically assign an appropriate Id generator if the type is a number type or UUID type.

That is, with Ebean it is effectively redundant to also add the @GeneratedValue annotation.

This behaviour can be disabled using idGeneratorAutomatic configuration property.

@Id
long id;

// ... is effectively the same as

@Id @GeneratedValue
long id;

idGeneratorAutomatic

We can disable the automatic generation of Id values by configuring idGeneratorAutomatic to be false.

configure via properties:

ebean.idGeneratorAutomatic=false

configure via code:

DatabaseConfig.setIdGeneratorAutomatic(false)

With idGeneratorAutomatic disabled then we need to explicitly add the @GeneratedValue to every @Id property that we want to have generated values via Database Identity or Sequence.

Alternatively we can use @Identity with type=APPLICATION to explicitly specify that the id value will be supplied by the application.

@Identity

Ebean additionally has an @Identity annotation when we want to use to specify the starts value, cache value and generated by default|always options for database identity or sequence.

We want to use this to specifically set the cache option when the associated table is expected to get a high load of inserts and we want to let databases that support it to have higher than normal id caching to reduce contention around generated id values/sequences. Postgres, Oracle and NuoDB all support setting the identity cache option. The downside to larger cache for id values is the potential for larger gaps in the id values if the database is restarted.

@Id @Identity(start=10000, cache=500)
long id;

We can also specify @Identity on the class - typically when the id property is inherited from a MappedSuperclass.

@Entity
@Identity(start=10000, cache=500)
public class Contact {

  @Id
  long id;

  ...
}

UUID

If the @Id type is UUID then Ebean will automatically assign an appropriate Id generator to that property.

// an appropriate UUID based Id generator
// is automatically assigned
@Id
UUID id;

UUID and @GeneratedValue

If we have a UUID that is NOT the @Id we can add @GeneratedValue and then Ebean will assign a appropriate UUID generator to it.

/** The Id property using DB Identity or Sequence */
@Id @GeneratedValue
private long id;

/** Alternate unique UUID property */
@GeneratedValue @Column(unique = true)
private UUID uid;

String

If the @Id type is String then Ebean assumes that the id value is supplied by the application. No Id generator is assigned to the Id property in this case.

@Id
String code;

An example of this could be ISO Country codes used as a primary key for Country.

Entities with no @Id property

We can model entity beans without any @Id property. The 2 cases for this are when modelling views and when modelling tables that are "insert only" representing a log of events or similar.

Views

When the entity bean is modelled to a @View often the view will not have column(s) that equates to a primary key.

Example - entity based on a view with @Id property
@Entity
@View(name = "machine_stats")
public class MachineStats {

  @ManyToOne
  Machine machine;

  LocalDate date;

  @Sum  // equivalent to @Aggregation("sum(totalKms)")
  long totalKms;

  @Sum
  long hours;

  @Max
  BigDecimal rate;

  @Aggregation("sum(cost)")
  BigDecimal totalCost;

  @Aggregation("max(totalKms)")
  BigDecimal maxKms;

Tables with no primary key

When modelling a "append only" table where we do not need a primary key then we can desire not having an @Id property and no actual primary key. We can desire this when we want to avoid the cost of the primary key index (that the application will never need or use).

For Postgres we would often use table partitioning for this type of "append only" events type table via @DbPartition.

Example - append only table with no primary key / no @Id property
/**
 * Append only table with no Id property, no primary key (no primary key index).
 */
@DbPartition(mode = DAY, property = "eventTime")
@Entity
@Table(name = "machine_log")
public class MachineLog {

  @Index
  @NotNull
  protected Instant eventTime;

  @DbForeignKey(noConstraint = true)
  @ManyToOne(optional = false)
  protected Machine machine;

  ...

Custom Id Generator

There is support for registering and using a custom Id generator.

1. Implement io.ebean.config.IdGenerator

public class ModUuidGenerator implements IdGenerator {

  @Override
  public Object nextValue() {
    return ModUUID.newShortId();
  }

  @Override
  public String getName() {
    return "shortUid";
  }
}

2. Register with ServerConfig

We register the IdGenerator with ServerConfig by using addClass() or add(IdGenerator idGenerator) or setIdGenerators(List idGenerators).

Note that if you are using classpath scanning to find entity beans that this will also automatically find implementations of IdGenerator and automatically register them so in this case you don't need to register the IdGenerator manually with ServerConfig.

3. @GeneratedValue

We can then tell Ebean to use our custom IdGenerator by using the @GeneratedValue with the generator being the name of our custom IdGenerator.

@Id @GeneratedValue(generator = "shortUid")
String id;

No lazy loading

Note that @Id properties never invoke lazy loading.

Database platform

All the supported databases use either Identity or Sequences (or allow both) and Ebean will choose the appropriate Id generation strategy based on the database platform.

DatabaseStrategy
H2Identity (also supports sequences)
PostgresIdentity (as serial, also supports sequences)
MySqlIdentity
OracleSequences (also supports Identity)
DB2Identity (also supports sequences)
SQL ServerIdentity
SQLiteIdentity
SqlAnywhereIdentity