Feature Request: Insert with InsertOptions expose affected row count
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.5k
- Forks
- 267
- Avg merge
- 3d 20h
- Merged PRs (30d)
- 5
Description
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:
1affected row when the row was inserted;0affected 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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the database.insert(bean, InsertOptions...) entry point and how the JDBC insert result is currently handled. Expose the affected row count for ON_CONFLICT_NOTHING, with completion demonstrated by distinguishing 1 inserted row from 0 skipped rows in the existing insert behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, sql
- Domain
- backend, databases
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100