当前位置: 首页 > 知识库问答 >
问题:

在PostConstruct中使用事务

聂炜
2023-03-14

我将HiberNate与Panache一起使用,并且需要在应用程序启动时添加用户。为此,我使用@Startup注释我的bean,然后我有一个带有注释@PostCon结构体的方法。

目前,我正在使用以下代码:

@Startup
@ApplicationScoped
class AuthService {
    @Inject
    lateinit var userRepository: UserRepository

    @PostConstruct
    fun init() {
        logger.info("Creating admin user")

        val user = User(
            "Admin", ADMIN_NAME, BcryptUtil.bcryptHash(ADMIN_PASS), mutableSetOf(Role.ADMIN)
        )

        Panache.withTransaction {
            userRepository.persist(user)
        }.subscribe().with({
            logger.info("Done")
        }, { fail ->
            logger.error("Failed admin creation: $fail")
        })
    }
}

据我发现,当调用此方法时,不能保证所有内容都已经设置好,我想这就是为什么它有时会失败并出现错误会话/实体管理器已关闭的原因。我已经检查过这个问题,但由于它是针对 Spring 的,因此该方法不起作用,我没有找到任何类似的东西 Quarkus。

我是否缺少任何解决方案,或者有更好的方法来解决这个问题?

共有1个答案

松旻
2023-03-14

这应该是可行的(我是用Java写的,因为我不熟悉Kotlin):

    @PostConstruct
    public void init() {
        logger.info( "Creating admin user" );

        User user = new User(
            "Admin", ADMIN_NAME, BcryptUtil.bcryptHash(ADMIN_PASS), mutableSetOf(Role.ADMIN)
        );

        Panache
                .withTransaction( () -> userRepository.persist( user ) )
                .onItemOrFailure().invoke( (v, e ) -> {
                        if (e != null) {
                            logger.info( "Done!" );
                        }
                        else {
                            logger.errorf( "Failed admin creation: %s", e );
                        }
                } )
                .await().indefinitely();
    }

请注意,该代码不是被动的。.await()。infinitely()将阻塞线程,直到操作完成。

正确的方法应该是这样的:

    @PostConstruct
    public Uni<Void> init() {
       ...
       return Panache.withTransaction(...);
    }

但这在夸克中目前不起作用。

 类似资料:
  • 问题内容: 构造bean之后,我想使用EntityManager从数据库中检索数据。在构造函数中是不可能的,因为EntityManager是在调用构造函数之后注入的。所以我试图用@PostConstruct注释的方法来做。根据API,在完成所有注入后将调用PostConstruct方法。执行查询是可行的,但是它总是返回一个空列表。如果我在其他方法中使用相同的查询,它将返回正确的结果。有人知道,为什

  • 我正在为Java11实现一个模块,并希望使用JSR250中的注释(javax.annotation.PostConstruct和javax.annotation.PreDestroy)。 我已经更改了根据依赖项从: 对此: 这个工件此行: 因此,我尝试将其添加到我的模块信息中。java文件: 但是,我得到了一个错误的导入: 错误消息是: 我已经研究了以下相关问题,但仍无法解决我的问题: 我不能在J

  • 我想在我的应用程序开始时读取文本数据夹具(CSV文件),并将其放入数据库。 为此,我创建了一个带有初始化方法的PopulationService(@PostConstruct注释)。 我还希望它们在单个事务中执行,因此我在同一个方法上添加了@Transactional。 然而,@Transactional似乎被忽略了:事务在我的低级DAO方法中启动/停止。 那么我需要手动管理交易吗?

  • 在使用Spring5、JUnit4.11和JDK8运行一些集成测试之前,我尝试使用@sqlgroup执行一些SQL语句。 直到今天,当我用@PostConstruct注释在我的“ConfigurationComponent”bean上添加一些初始配置时,一切都完美无缺地工作着。 当@PostConstruct方法调用依赖于数据库的bean时,测试失败,因为hiberante(因此数据库)找不到预加

  • 这是示例代码。在使用mockito或@Beofre注释之前,一切似乎都很好。现在它可以正确地模拟对象,但某些工厂没有正确地自动连接。 在莫基托之前,一切都很顺利。