quarkus: Hibernate Reactive / Reactive Messaging Transaction issue on constraint violation
Describe the bug
I have a very simple application using RestEasy Reactiv, Reactive Messaging (no connector, just plain in-memory), and Hibernate Reactive with PostgreSQL.
My application has an endpoint doing this:
@Channel("database")
MutinyEmitter<Person> emitter;
@POST
public Uni<Response> upload(Person person) {
return emitter.send(person)
.replaceWith(Response.accepted().build())
.onFailure().recoverWithItem(t ->
Response.status(Response.Status.BAD_REQUEST).entity(t.getMessage()).build()
);
}
Basically, it gets a Person
and sends it to the database
channel.
The database
channel is read as follows:
@Incoming("database")
public Uni<Void> write(Person person) {
return Panache.withTransaction(person::persist);
}
Everything works fine until I add a constraint in my entity and that constraint gets violated:
@Entity
public class Person extends PanacheEntity {
@Column(unique = true)
public String name;
}
It works until I deliberately send a payload violating the constraint. I got the 400 error, but any subsequent request gets the same issue, with the same error message:
> http POST :8080 name=a
HTTP/1.1 202 Accepted
content-length: 0
> http POST :8080 name=a # Exception expected
HTTP/1.1 400 Bad Request
Content-Type: application/octet-stream
content-length: 555
Multiple exceptions caught:
[Exception 0] javax.persistence.PersistenceException: org.hibernate.HibernateException: io.vertx.pgclient.PgException: { "message": "duplicate key value violates unique constraint \"uk_is4vd0f6kw9sw4dxyie5cy9fa\"", "severity": "ERROR", "code": "23505", "detail": "Key (name)=(a) already exists.", "file": "nbtinsert.c", "line": "656", "routine": "_bt_check_unique", "schema": "public", "table": "person", "constraint": "uk_is4vd0f6kw9sw4dxyie5cy9fa" }
[Exception 1] io.vertx.core.VertxException: Transaction already completed
> http POST :8080 name=b
HTTP/1.1 400 Bad Request
Content-Type: application/octet-stream
content-length: 555
Multiple exceptions caught:
[Exception 0] javax.persistence.PersistenceException: org.hibernate.HibernateException: io.vertx.pgclient.PgException: { "message": "duplicate key value violates unique constraint \"uk_is4vd0f6kw9sw4dxyie5cy9fa\"", "severity": "ERROR", "code": "23505", "detail": "Key (name)=(a) already exists.", "file": "nbtinsert.c", "line": "656", "routine": "_bt_check_unique", "schema": "public", "table": "person", "constraint": "uk_is4vd0f6kw9sw4dxyie5cy9fa" }
[Exception 1] io.vertx.core.VertxException: Transaction already completed
So even when sending b
, it still complains about a
. It seems like it didn’t clean up after the transaction rollback.
I have checked that all the calls used the same MutinySession, but the transaction objects are different.
To Reproduce
To reproduce, just run the test included in the project above ^ Or in a terminal
mvn clean quarkus:dev
and, in another terminal:
http POST :8080 name=bob # expected 202
http POST :8080 name=bob # expected 400 - name is not unique
http POST :8080 name=tom # expected 202, but got 400, with the same error message than the previous request
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 17 (16 by maintainers)
It seems it’s a bug in Hibernate Reactive, when we close the session we don’t set the boolean that decides if it’s open or close. I’m going to fix it
the ‘MutinySession’ should not be reused after an exception happened: it should be closed.
On Sun, 16 May 2021, 18:31 Clement Escoffier, @.***> wrote: