将 Quarkus 用于小型 REST 项目。主要实体是一个Bookmark,里面有@Entity、@Id等注解。 REST 服务方法直接委托给数据服务或 DAO。 DAO 的 4 个左右的 GET 方法都工作正常,获取从
import.sql
加载的书签。一个 POST 方法执行时没有错误,但 Hibernate 不执行 SQL 插入,尽管它确实调用 hibernate_sequence 来获取应该插入的对象的主键,并在内存中的对象上设置新的 pkey (所有研究都使用临时打印语句,如下所示)。此外,实体上的 prePersist 方法会被调用,但同一类上的 postPersist 方法不会被调用。
发生在 H2 和 PostgreSQL 上。
这里是 REST 服务的摘录:
@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();
}
这是 Quarkus 运行的输出,显示了当我发布实体时发生的情况:
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
包括测试脚本在内的完整代码位于https://github.com/IanDarwin/bookmarks-backend
所以问题是:为什么 Hibernate 放弃中间事务而不抛出异常?
一个可能相关的附带问题:来自@Observes Transaction 方法的跟踪显示事务在方法结束之前一直有效。然而,如果我在中间取消注释 em.flush() ,它会说没有有效的交易。
我多次使用 JPA 并且坚持通常确实坚持,所以我假设我做了一些蠢事,但在盯着它看太久之后我看不到它。因为这只是我的第二个 Quarkus 应用程序,所以我不确定我的问题是出在 Quarkus 还是 JPA。我仔细检查了两者的配置,由于根本没有任何输出(SQL 跟踪或错误消息),因此很难知道去哪里查看。 TIA,如果你能指出的话。
呃。我的 persistence.xml 没有指定
transaction-type="JTA"
并且在 Quarkus 上它显然默认为 RESOURCE-LOCAL
然后默默地失败。
明明是应该报错的,但是并没有