Expected behavior
When using insert() with InsertOptions, especially with ON CONFLICT DO NOTHING, I would like to obtain the number of affected rows.
For example, an API equivalent to:
int affectedRows = database.insert(bean, InsertOptions.ON_CONFLICT_NOTHING);
This would allow applications to atomically determine whether the row was actually inserted:
int affectedRows = database.insert(
bean,
InsertOptions.ON_CONFLICT_NOTHING
);
boolean inserted = affectedRows > 0;
A different method/signature would also work if changing the existing insert() API is undesirable.
The important part is exposing the JDBC/database affected row count when using InsertOptions.
This is particularly useful for implementing atomic createIfAbsent() operations without requiring:
- a separate
SELECT / exists() before the insert;
- exception-based duplicate detection;
- or manually written SQL.
For PostgreSQL, for example:
INSERT INTO fruit (...)
VALUES (...)
ON CONFLICT (...) DO NOTHING
naturally provides the required information:
1 affected row when the row was inserted;
0 affected rows when the conflict caused the insert to be skipped.
Actual behavior
Currently:
database.insert(bean, InsertOptions.ON_CONFLICT_NOTHING);
returns void.
Therefore, although Ebean correctly generates and executes INSERT ... ON CONFLICT DO NOTHING, the caller cannot determine whether:
- the row was inserted; or
- the insert was skipped because of a conflict.
This makes it impossible to implement an atomic operation such as:
boolean createIfAbsent(Fruit fruit)
using the generated Ebean insert alone.
Steps to reproduce
var options = InsertOptions.builder()
.onConflictNothing()
.build();
var fruit1 = new Fruit();
fruit1.setId("apple");
database.insert(fruit1, options);
// Insert the same unique/primary-key value again
var fruit2 = new Fruit();
fruit2.setId("apple");
database.insert(fruit2, options);
Both calls return void, so there is no way for the caller to distinguish the first insert from the second no-op.
Ideally, the affected row count should be exposed so the first operation can report 1 and the second 0.
PS: I also consider it useful in operations like, update, save, merge, etc.
Expected behavior
When using
insert()withInsertOptions, especially withON CONFLICT DO NOTHING, I would like to obtain the number of affected rows.For example, an API equivalent to:
This would allow applications to atomically determine whether the row was actually inserted:
A different method/signature would also work if changing the existing
insert()API is undesirable.The important part is exposing the JDBC/database affected row count when using
InsertOptions.This is particularly useful for implementing atomic
createIfAbsent()operations without requiring:SELECT/exists()before the insert;For PostgreSQL, for example:
naturally provides the required information:
1affected row when the row was inserted;0affected rows when the conflict caused the insert to be skipped.Actual behavior
Currently:
returns
void.Therefore, although Ebean correctly generates and executes
INSERT ... ON CONFLICT DO NOTHING, the caller cannot determine whether:This makes it impossible to implement an atomic operation such as:
using the generated Ebean insert alone.
Steps to reproduce
Both calls return
void, so there is no way for the caller to distinguish the first insert from the second no-op.Ideally, the affected row count should be exposed so the first operation can report
1and the second0.PS: I also consider it useful in operations like, update, save, merge, etc.