Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quarkus Hibernate-Reactive Type error for TypedQuery #537

Closed
Artyukin opened this issue Feb 4, 2021 · 9 comments
Closed

Quarkus Hibernate-Reactive Type error for TypedQuery #537

Artyukin opened this issue Feb 4, 2021 · 9 comments
Assignees

Comments

@Artyukin
Copy link

Artyukin commented Feb 4, 2021

While working on a Project with Quarkus and Hibernate-Reactive with Mutiny I'm getting a weird error when creating TypedQuerys that appears only on some Entities.
For Example the Query return mutinySession.createQuery("From Reaction", Reaction.class).getResults(); results in the following exeption:

javax.persistence.PersistenceException: org.hibernate.HibernateException: java.lang.IllegalArgumentException: Type specified for TypedQuery [de.hsos.uny.post.entity.Reaction] is incompatible with query return type [class de.hsos.uny.post.entity.Reaction]
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
	at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
	at org.hibernate.reactive.session.impl.ReactiveExceptionConverter.convert(ReactiveExceptionConverter.java:31)
	at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createReactiveQuery(ReactiveSessionImpl.java:316)
	at org.hibernate.reactive.mutiny.impl.MutinySessionImpl.createQuery(MutinySessionImpl.java:184)
	at io.quarkus.hibernate.reactive.runtime.ReactiveSessionProducer_ProducerMethod_createMutinySession_1321d110ee9e92bda147899150401e0a136779c7_ClientProxy.createQuery(ReactiveSessionProducer_ProducerMethod_createMutinySession_1321d110ee9e92bda147899150401e0a136779c7_ClientProxy.zig:311)
	at de.hsos.uny.post.boundary.rest.PostResource.GetReactions(PostResource.java:128)
	at de.hsos.uny.post.boundary.rest.PostResource_ClientProxy.GetReactions(PostResource_ClientProxy.zig:321)
	at de.hsos.uny.post.boundary.rest.PostResource$quarkusrestinvoker$GetReactions_230e290da4d708c585e2152839dc3be5cfb5b465.invoke(PostResource$quarkusrestinvoker$GetReactions_230e290da4d708c585e2152839dc3be5cfb5b465.zig:41)
	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:7)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:108)
	at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:47)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:17)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:7)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1038)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:137)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:132)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder.lambda$start$1(StaticResourcesRecorder.java:62)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1038)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:101)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:132)
	at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$1(StaticHandlerImpl.java:206)
	at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:327)
	at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:366)
	at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: org.hibernate.HibernateException: java.lang.IllegalArgumentException: Type specified for TypedQuery [de.hsos.uny.post.entity.Reaction] is incompatible with query return type [class de.hsos.uny.post.entity.Reaction]
	... 31 more
Caused by: java.lang.IllegalArgumentException: Type specified for TypedQuery [de.hsos.uny.post.entity.Reaction] is incompatible with query return type [class de.hsos.uny.post.entity.Reaction]
	at org.hibernate.internal.AbstractSharedSessionContract.resultClassChecking(AbstractSharedSessionContract.java:863)
	at org.hibernate.reactive.session.impl.ReactiveSessionImpl.createReactiveQuery(ReactiveSessionImpl.java:312)
	... 29 more

Not sure what could cause that since the class is actually quite minimal

@Entity
public class Reaction {
   @Id
   private long id;

   private String iconURL;

   @Transient
   @OneToMany(mappedBy = "react")
   private Collection<Postreactions> reactions;
   //Getters & Setters

}
The Workaround I found is a bit Hacky, but it works:
return mutinySession.createQuery("From Reaction").getResults().map(ent -> {return (Reaction)ent;});

@gavinking
Copy link
Member

Strange one.

By the way, instead of using map() you can pass a class object to createQuery(). (And that might even help you workaround this issue.)

@Artyukin
Copy link
Author

Artyukin commented Feb 4, 2021

Ah Sorry, I forgot to add it to the Query above, but sadly i was using it already, when the errors occured.

@gavinking gavinking self-assigned this Feb 10, 2021
@gavinking
Copy link
Member

I wrote this test class to attempt to reproduce the problem:

/* Hibernate, Relational Persistence for Idiomatic Java
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 * Copyright: Red Hat Inc. and Hibernate Authors
 */
package org.hibernate.reactive;

import io.vertx.ext.unit.TestContext;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import java.util.Collection;


public class TypedQueryBugTest extends BaseReactiveTest {

    @Override
    protected Configuration constructConfiguration() {
        Configuration configuration = super.constructConfiguration();
        configuration.addAnnotatedClass( Reaction.class );
        configuration.addAnnotatedClass( PostReaction.class );
        return configuration;
    }

    @Test
    public void testBug(TestContext context) {
        test(context, getMutinySessionFactory()
                .withSession( session -> session.persist( new Reaction() )
                        .chain( ()-> session.createQuery("From Reaction", Reaction.class)
                                .getResultList().invoke( list-> {
                                    context.assertEquals( 1, list.size() );
                                    list.forEach( reaction -> context.assertTrue(reaction instanceof Reaction));
                                } )
                        )
                )
        );
    }

    @Entity(name = "Reaction")
    public static class Reaction {
        @Id
        private long id;

        private String iconURL;

        @Transient
        @OneToMany(mappedBy = "react")
        private Collection<PostReaction> reactions;
        //Getters & Setters
    }

    @Entity(name = "PostReaction")
    public static class PostReaction {
        @Id
        private long id;
    }

}

And it passes. So there must be something extra going on here.

@gavinking
Copy link
Member

@Sanne could this be Quarkus-specific?

@Sanne
Copy link
Member

Sanne commented Feb 10, 2021

yes, the error message smells of classloader issue, which would depend on the runtime and how it's integrated.

It's strange as Quarkus has a flat classloader, with the exception of support for build and dev-mode, which generally shouldn't have an impact on query execution. We'll need to try reproducing this on Quarkus.

@gavinking
Copy link
Member

Right, when I first saw the issue, I thought "classloader". But then I saw Quarkus in the stack trace and decided that mustn't be the problem.

@gavinking
Copy link
Member

@Sanne this issue has turned into a bit of a zombie.

I doubt it's an issue with HR itself, if anything it's more likely something related to Quarkus.

Should we just, like, close it?

@DavideD
Copy link
Member

DavideD commented Jul 28, 2021

I'm fine with closing this issue. We can re-open it if it happens again

@Sanne
Copy link
Member

Sanne commented Jul 28, 2021

So let's remember that Quarkus has a "flat classloader" only when running the built application (so called "production" mode); otherwise there are multiple classloaders at play, especially when developing with live-reload.

This was most likely related to quarkusio/quarkus#18299

@Artyukin I'll close the issue, but if you could try doing this again after the next Quarkus release that would be great. If you still see this error, please report them to Quarkus. Thanks!

@Sanne Sanne closed this as completed Jul 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants