hibernate-reactive icon indicating copy to clipboard operation
hibernate-reactive copied to clipboard

2.0.5 upgrade and persist error.

Open KimDev88 opened this issue 2 years ago • 9 comments

This source is working.

public CompletionStage<Shop> save(Shop shop, Stage.Session session) {
        return session.persist(shop)
                .thenApply(unused -> shop);
    }

but upgrade hibernate-core to 2.0.5, this source is not working.

java.util.concurrent.CompletionException: org.hibernate.HibernateException: java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "org.hibernate.sql.results.graph.DomainResult.createResultAssembler(org.hibernate.sql.results.graph.FetchParentAccess, org.hibernate.sql.results.graph.AssemblerCreationState)" because the return value of "java.util.List.get(int)" is null
		at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
		at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
		at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:936)
		at java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:950)
		at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2340)
		at java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:144)
		at org.hibernate.reactive.session.impl.ReactiveSessionImpl.firePersist(ReactiveSessionImpl.java:734)
		at org.hibernate.reactive.session.impl.ReactiveSessionImpl.reactivePersist(ReactiveSessionImpl.java:718)
		at org.hibernate.reactive.stage.impl.StageSessionImpl.persist(StageSessionImpl.java:159)
		at com.bdpick.repository.ShopRepository.save(ShopRepository.java:29)
		at com.bdpick.service.ShopService.lambda$createShop$4(ShopService.java:121)
		at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1150)
		at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
		at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
		at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.unroll(AsyncTrampoline.java:131)
		at org.hibernate.reactive.util.async.impl.AsyncTrampoline$TrampolineInternal.lambda$unroll$0(AsyncTrampoline.java:126)
		at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
		at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
		at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
		at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
		at io.vertx.core.Future.lambda$toCompletionStage$3(Future.java:536)
		at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
		at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
		at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
		at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)

-- service class source --

@Transactional
    public Mono<Shop> createShop(@NonNull Map<String, Object> headerMap,
                                 @NonNull Flux<FilePart> files,
                                 @NonNull Flux<String> filesTypes,
                                 @NonNull Shop shop) {
        List<ShopImage> imageList = new ArrayList<>();
        String userId = jwtService.getUserIdByHeaderMap(headerMap);
        User user = new User();
        user.setId(userId);
        shop.setUser(user);

        return factory.withTransaction(session -> {
                    return shopRepository.findShopByRegisterNumber(shop, session)
                            .thenCompose(foundShop -> {
                                if (foundShop != null) {
                                    throw new RuntimeException(KEY_DUPLICATE_REGISTER);
                                }
                                List<FilePart> filePartList = files.toStream().toList();
                                List<String> fileTypeList = filesTypes.toStream().toList();
                                IntStream.range(0, Math.min(filePartList.size(), fileTypeList.size()))
                                        .mapToObj(i -> Tuple.of(filePartList.get(i), fileTypeList.get(i)))
                                        .forEach(tuple -> {
                                            String type = tuple.getString(1);
                                            ShopImage shopImage = new ShopImage();
                                            Image image = new Image();
                                            BdFile bdFile = BdUtil.uploadFile(tuple.get(FilePart.class, 0), type, BdConstants.DIRECTORY_NAME_IMAGES).block();

                                            image.setDisplayOrder(1L);
                                            image.setBdFile(bdFile);

                                            shopImage.setShop(shop);
                                            shopImage.setImage(image);
                                            shopImage.setType(ShopFileType.valueOf(type));
                                            imageList.add(shopImage);
                                        });
                                shop.setImageList(imageList);
                                return shopRepository.save(shop, session);
                            });
                })
                .thenApply(Mono::just)
                .exceptionally(Mono::error)
                .toCompletableFuture().join();
    }

-- working -- hibernate-core-6.2.5.Final.jar hibernate-reactive-core-2.0.4.Final.jar vertx-mysql-client-4.4.4.jar

-- not working -- hibernate-core-6.2.8.Final.jar hibernate-reactive-core-2.0.5.Final.jar vertx-sql-client-4.4.5.jar

KimDev88 avatar Sep 04 '23 15:09 KimDev88

@blafond Could you check this, please?

DavideD avatar Sep 05 '23 06:09 DavideD

yes

blafond avatar Sep 05 '23 13:09 blafond

@KimDev88 could you share your entity classes or point to test project that replicates this error?

blafond avatar Sep 05 '23 13:09 blafond

@blafond here : https://github.com/KimDev88/bdpick-api/blob/main/src/main/java/com/bdpick/domain/entity/shop/Shop.java

KimDev88 avatar Sep 06 '23 04:09 KimDev88

@KimDev88 is this still an issue with Hibernate Reactive 2.2.0.Final?

DavideD avatar Dec 01 '23 10:12 DavideD

@DavideD Yes... It's same.

implementation 'org.hibernate.orm:hibernate-core:6.4.0.Final'
implementation 'org.hibernate.reactive:hibernate-reactive-core:2.2.0.Final'
implementation 'io.vertx:vertx-mysql-client:4.5.0'
Caused by: org.hibernate.HibernateException: java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "org.hibernate.sql.results.graph.DomainResult.createResultAssembler(org.hibernate.sql.results.graph.FetchParentAccess, org.hibernate.sql.results.graph.AssemblerCreationState)" because the return value of "java.util.List.get(int)" is null
		at org.hibernate.reactive.session.impl.ReactiveExceptionConverter.convert(ReactiveExceptionConverter.java:28)
		at org.hibernate.reactive.session.impl.ReactiveSessionImpl.lambda$firePersist$11(ReactiveSessionImpl.java:736)
		at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
		... 100 more
	Caused by: java.util.concurrent.CompletionException: java.lang.NullPointerException: Cannot invoke "org.hibernate.sql.results.graph.DomainResult.createResultAssembler(org.hibernate.sql.results.graph.FetchParentAccess, org.hibernate.sql.results.graph.AssemblerCreationState)" because the return value of "java.util.List.get(int)" is null
		at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1194)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor.doExecuteQuery(StandardReactiveSelectExecutor.java:148)
		at org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor.executeQuery(StandardReactiveSelectExecutor.java:118)
		at org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor.list(StandardReactiveSelectExecutor.java:86)
		at org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor.list(StandardReactiveSelectExecutor.java:76)
		at org.hibernate.reactive.loader.ast.internal.DatabaseSnapshotExecutor.loadDatabaseSnapshot(DatabaseSnapshotExecutor.java:184)
		at org.hibernate.reactive.loader.ast.internal.ReactiveSingleIdEntityLoaderStandardImpl.reactiveLoadDatabaseSnapshot(ReactiveSingleIdEntityLoaderStandardImpl.java:47)
		at org.hibernate.reactive.persister.entity.impl.ReactiveAbstractEntityPersister.reactiveGetDatabaseSnapshot(ReactiveAbstractEntityPersister.java:262)
		at org.hibernate.reactive.engine.impl.ReactivePersistenceContextAdapter.reactiveGetDatabaseSnapshot(ReactivePersistenceContextAdapter.java:90)
		at org.hibernate.reactive.engine.impl.ForeignKeys.isTransient(ForeignKeys.java:329)
		at org.hibernate.reactive.engine.impl.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:254)
		at org.hibernate.reactive.engine.impl.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:135)
		at org.hibernate.reactive.engine.impl.ForeignKeys$Nullifier.lambda$nullifyTransientReferences$0(ForeignKeys.java:89)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.engine.impl.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:89)
		at org.hibernate.reactive.engine.impl.ReactiveEntityInsertAction.reactiveNullifyTransientReferencesIfNotAlready(ReactiveEntityInsertAction.java:64)
		at org.hibernate.reactive.engine.impl.ReactiveEntityInsertAction.reactiveMakeEntityManaged(ReactiveEntityInsertAction.java:81)
		at org.hibernate.reactive.engine.ReactiveActionQueue.lambda$addResolvedEntityInsertAction$6(ReactiveActionQueue.java:292)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.engine.ReactiveActionQueue.addResolvedEntityInsertAction(ReactiveActionQueue.java:290)
		at org.hibernate.reactive.engine.ReactiveActionQueue.lambda$addInsertAction$2(ReactiveActionQueue.java:258)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.engine.ReactiveActionQueue.addInsertAction(ReactiveActionQueue.java:255)
		at org.hibernate.reactive.engine.ReactiveActionQueue.addAction(ReactiveActionQueue.java:241)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.addInsertAction(AbstractReactiveSaveEventListener.java:374)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.lambda$reactivePerformSaveOrReplicate$5(AbstractReactiveSaveEventListener.java:292)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.reactivePerformSaveOrReplicate(AbstractReactiveSaveEventListener.java:292)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.lambda$reactivePerformSave$2(AbstractReactiveSaveEventListener.java:204)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.reactivePerformSave(AbstractReactiveSaveEventListener.java:204)
		at org.hibernate.reactive.event.impl.AbstractReactiveSaveEventListener.reactiveSaveWithGeneratedId(AbstractReactiveSaveEventListener.java:144)
		at org.hibernate.reactive.event.impl.DefaultReactivePersistEventListener.entityIsTransient(DefaultReactivePersistEventListener.java:189)
		at org.hibernate.reactive.event.impl.DefaultReactivePersistEventListener.persist(DefaultReactivePersistEventListener.java:109)
		at org.hibernate.reactive.event.impl.DefaultReactivePersistEventListener.reactiveOnPersist(DefaultReactivePersistEventListener.java:92)
		at org.hibernate.reactive.event.impl.DefaultReactivePersistEventListener.reactiveOnPersist(DefaultReactivePersistEventListener.java:64)
		at org.hibernate.event.service.internal.EventListenerGroupImpl.lambda$fireEventOnEachListener$0(EventListenerGroupImpl.java:153)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309)
		at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:144)
		at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:153)
		at org.hibernate.reactive.session.impl.ReactiveSessionImpl.firePersist(ReactiveSessionImpl.java:728)
		... 96 more
	Caused by: java.lang.NullPointerException: Cannot invoke "org.hibernate.sql.results.graph.DomainResult.createResultAssembler(org.hibernate.sql.results.graph.FetchParentAccess, org.hibernate.sql.results.graph.AssemblerCreationState)" because the return value of "java.util.List.get(int)" is null
		at org.hibernate.sql.results.jdbc.internal.StandardJdbcValuesMapping.resolveAssemblers(StandardJdbcValuesMapping.java:53)
		at org.hibernate.reactive.sql.results.internal.ReactiveResultsHelper.createRowReader(ReactiveResultsHelper.java:44)
		at org.hibernate.reactive.sql.exec.internal.StandardReactiveSelectExecutor.lambda$doExecuteQuery$4(StandardReactiveSelectExecutor.java:182)
		at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
		... 149 more

KimDev88 avatar Dec 04 '23 12:12 KimDev88

@DavideD But it doesn't work when I change to the previous version. I'll test it in more detail and talk to you again.

KimDev88 avatar Dec 04 '23 12:12 KimDev88

Sure, thanks. By the way @Transactional does not affect Hibernate Reactive, it would be better to remove the annotation

DavideD avatar Dec 04 '23 15:12 DavideD

You also don't need to use .join(), there are examples on the Mutiny documentation on how to covert fron Uni to Mono: https://smallrye.io/smallrye-mutiny/2.5.1/guides/converters/#converting-a-multi-into-a-flux-or-mono

DavideD avatar Dec 04 '23 16:12 DavideD