@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
.
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.
Database | Strategy |
---|---|
H2 | Identity (also supports sequences) |
Postgres | Identity (as serial, also supports sequences) |
MySql | Identity |
Oracle | Sequences (also supports Identity) |
DB2 | Identity (also supports sequences) |
SQL Server | Identity |
SQLite | Identity |
SqlAnywhere | Identity |