Using Quarkus for a small REST project. The main entity is a Bookmark, which has @Entity, @Id and so on annotations. The REST service methods directly delegate to a data service or DAO. The DAO's 4 or so GET methods all work fine, fetching Bookmarks that are loaded from import.sql
. The one POST method executes with no error but Hibernate doesn't execute the SQL insert, though it does call hibernate_sequence to get the primary key for the should-be-inserted object, and does set the new pkey on the in-memory object (all researched with temporary print statements, shown below). Also, prePersist method on the entity gets called but postPersist on same class does not.
Happens on both H2 and PostgreSQL.
Here is an excerpt from the REST service:
@ApplicationScoped
public class BookmarksDaoJpa implements BookmarksService {
@Inject EntityManager em;
public List<Topic> topics() {
return em.createQuery("from Topic t order by t.description", Topic.class).getResultList();
}
// Other GET methods omitted, they work
// Inserts into database, returns new pkey #
@Transactional(value= Transactional.TxType.REQUIRED)
public long postBookmark(Bookmark bookmark) throws Exception {
if (bookmark.getId() == 0) {
System.out.println("Persisting " + bookmark);
em.persist(bookmark);
} else {
System.out.println("Merging " + bookmark);
em.merge(bookmark);
}
// em.flush();
System.out.println("bookmark.getId() = " + bookmark.getId());
return bookmark.getId();
}
Here is the output from the Quarkus run, showing what happens when I POST an entity:
Hibernate: insert into bookmark(id, topic_id, url, text) values(4, 'pol', 'http://huff.puff.com', 'Breaking: Another politician told the truth!')
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2023-03-01 08:09:28,465 INFO [io.quarkus] (Quarkus Main Thread) bookmarks.rest 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.16.3.Final) started in 3.514s. Listening on: http://localhost:8086
2023-03-01 08:09:28,467 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2023-03-01 08:09:28,468 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, jdbc-postgresql, narayana-jta, resteasy, resteasy-jackson, smallrye-context-propagation, vertx]
BookmarksResource.onBeginTransaction: TransactionImple < ac, BasicAction: 0:ffffc0a82a2d:142f:63ff4e97:0 status: ActionStatus.RUNNING >
Persisting Bookmark(#0, topic tech, url https://dev/null, text Puff the fractal dragon)
Bookmark.prePersist: id = 0
Hibernate: call next value for hibernate_sequence
bookmark.getId() = 10
BookmarksResource.onBeforeEndTransaction
2023-03-01 08:09:43,238 WARN [io.agr.pool] (executor-thread-0) Datasource '<default>': Closing open connection prior to commit
BookmarksResource.onAfterEndTransaction
Full code including test script is at https://github.com/IanDarwin/bookmarks-backend
So the question is: WHY is Hibernate giving up mid-transaction but not throwing an exception?
A side issue, probably related: The tracing from the @Observes Transaction methods show the transaction is in effect up until the end of the method. Yet if I uncomment the em.flush() in the middle, it says there is no transaction in effect.
I've used JPA multiple times and persist normally does persist, so I assume I've made some booboo, but I can't see it after staring at this for far too long. As this is only my 2nd Quarkus app, I am not sure if my problem is with Quarkus or with JPA. I have scrutinized the configs of both and, with the lack of any output at all (either an SQL trace or an error message), it is difficult to know where to look. TIA if you can point it out.
Grrr. My persistence.xml didn't specify transaction-type="JTA"
and on Quarkus it apparently defaults to RESOURCE-LOCAL
and then fails silently.
Obviously it should report an error, but it doesn't.