hibernate / hibernate-reactive

A reactive API for Hibernate ORM, supporting non-blocking database drivers and a reactive style of interaction with the database.
https://hibernate.org/reactive
Apache License 2.0
436 stars 92 forks source link

2.0.5 upgrade and persist error. #1748

Open KimDev88 opened 1 year ago

KimDev88 commented 1 year ago

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

DavideD commented 1 year ago

@blafond Could you check this, please?

blafond commented 1 year ago

yes

blafond commented 1 year ago

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

KimDev88 commented 1 year ago

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

DavideD commented 10 months ago

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

KimDev88 commented 10 months ago

@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 commented 10 months ago

@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.

DavideD commented 10 months ago

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

DavideD commented 10 months ago

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