I've pushed a quick prototype for the annotation design to my [GH fork|https://github.com/gunnarmorling/hibernate-orm/commit/b7fb92faca7708d3516510de49fa1a94fe6184ad#diff-11].
The idea is to leave 3) (value generation via default value/trigger) to {{@Generated}} as it is today. 1) and 2) would be provided by the design presented in that commit. The main SPI is {{ValueGenerator}} which basically can be implemented by invoking a Java routine for determining the value or an SQL function.
An implementation also specifies when the value generation takes place (INSERT, ALWAYS) and the strategy to choose (VM, DB (selects a value from a function and passes it to the SQL) or DM_EMBED (selects a function inline within the SQL). Note that these values could be taken from the generator's annotation and thus be specified by the user if feasible. For pure Java-based generators there is one implementation of that general SPI which delegates to another simpler SPI type {{VmValueGenerator}} which just returns a value.
Some usage examples:
{code} public class Giraffe {
@GeneratedValue(type = MyNameGenerator.class, when = GenerationTime.ALWAYS) private String name;
@FunctionValue(function = "MY_CUSTOM_FUNCTION", when = GenerationTime.INSERT, embed = false) private Date customCreated;
@CreationTimestamp(strategy = ValueGenerationStrategy.DB) private Date created; } {code}
Here,
* the generator for {{@GeneratorValue}} delegates to said simplified SPI {{VmValueGenerator}}. * The generator for {{@FunctionValue}} makes some aspects of the general {{ValueGenerator}} contract configurable via the annotation, namely the function name, when to invoke the generator and the strategy (limited to the two options reasonable for functions, i.e. fetch beforehand or embed the function call into the SQL) * The generator for {{@CreationTimestamp}} either invokes an SQL function or retrieves the timestamp based on the given strategy value.
|