quarkusquarkus-hibernate-orm

UnknownEntityTypeException: Unable to locate persister: java.lang.String


I don't know what I'm missing. I wanted to move all JPA operations to a *Dao class, e.g.

package org.acme;

import org.acme.model.Gift;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;

@ApplicationScoped
public class GiftDao {

    @Inject
    EntityManager entityManager;

    public void addGift(String name) {
        Gift gift = new Gift();
        gift.setName(name);
        entityManager.persist(name);
    }
}

But when I call the addGift method, a UnknownEntityTypeException occurs with a message "Unable to locate persister: java.lang.String":

java.lang.IllegalArgumentException: Unable to locate persister: java.lang.String
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:764)
        at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:745)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.persist(TransactionScopedSession.java:146)
        at org.hibernate.engine.spi.SessionLazyDelegator.persist(SessionLazyDelegator.java:282)
        at org.hibernate.Session_OpdLahisOZ9nWRPXMsEFQmQU03A_Synthetic_ClientProxy.persist(Unknown Source)
        at org.acme.GiftDao.addGift(GiftDao.java:20)
        at org.acme.GiftDao_ClientProxy.addGift(Unknown Source)
        at org.acme.GreetingResource.hello(GreetingResource.java:31)
        at org.acme.GreetingResource_Subclass.hello$$superforward(Unknown Source)
        at org.acme.GreetingResource_Subclass$$function$$3.apply(Unknown Source)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:136)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:107)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:38)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:61)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:32)
        at io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(Unknown Source)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
        at org.acme.GreetingResource_Subclass.hello(Unknown Source)
        at org.acme.GreetingResource_ClientProxy.hello(Unknown Source)
        at org.acme.GreetingResource$quarkusrestinvoker$hello_e747664148511e1e5212d3e0f4b40d45c56ab8a1.invoke(Unknown Source)
        at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:635)
        at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1521)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.hibernate.UnknownEntityTypeException: Unable to locate persister: java.lang.String
        at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.getEntityDescriptor(MappingMetamodelImpl.java:394)
        at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1512)
        at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:314)
        at org.hibernate.event.internal.EntityState.getEntityState(EntityState.java:64)
        at org.hibernate.event.internal.DefaultPersistEventListener.entityState(DefaultPersistEventListener.java:114)
        at org.hibernate.event.internal.DefaultPersistEventListener.persist(DefaultPersistEventListener.java:87)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79)
        at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)
        at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127)
        at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:761)
        ... 34 more

I simply use Quarkus and the initial GreetingResource, e.g.

package org.acme;

import org.acme.model.Gift;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
@ApplicationScoped
public class GreetingResource {

    @Inject
    GiftDao giftDao;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Transactional
    public String hello() {
        giftDao.addGift("Foobar");
        return "Hello from Quarkus REST";
    }
}

But what I really don't get is, that if I directly access the EntityManager in the GreetingResource, it work's:

package org.acme;

import org.acme.model.Gift;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
@ApplicationScoped
public class GreetingResource {

    @Inject
    private EntityManager entityManager;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Transactional
    public String hello() {
        Gift gift = new Gift();
        gift.setName("Foobar");
        entityManager.persist(gift);
        return "Hello from Quarkus REST";
    }
}

It's as simple as it could be and still it doesn't work? What am I'm missing? Is this a issue with CDI scopes?

I'm using Maven 3.9, Quarkus 3.22.2 and Java 21+.

Best regards, Billie


Solution

  • I assume you need to do:

    public void addGift(String name) {
        Gift gift = new Gift();
        gift.setName(name);
        entityManager.persist(gift);
    }
    

    instead of entityManager.persist(name);