2

I have a few JPA entities that are created and persisted in JAX-RS methods. I have a worker thread that processes some data about those entities in JPA over time and while I can pass in the Entity objects, I am unable to persist any changes to them because the EntitityManager in the thread that makes the changes is always null.

The class containing my worker thread is declared as such:

public final class EntityService {

@PersistenceContext(type = PersistenceContextType.EXTENDED)
EntityManager entityManager;

The EntityManager is always null and even if it's passed in from a JAX-RS method as by the time the thread gets a chance to attempt to use the EM, the EM is null as the JAX-RS method has terminated.

How can I get a valid Entity Manager into my Service pojo when injection isn't working? I'm using Hibernate and Wildfly 10

pirho
  • 11,565
  • 12
  • 43
  • 70
seanr8
  • 411
  • 1
  • 5
  • 15
  • Are you using @Transactional in your save method ? EntityManager should not be null, you should have a problem is your spring configuration or the way the bean is loaded – Woody Oct 13 '17 at 20:05
  • I don't have a spring configuration, I'm not using spring. It's Wildfly. Also, the EntityService class isn't a managed bean. – seanr8 Oct 13 '17 at 20:20

3 Answers3

1

EntityService needs to be managed in order to have EntityManager injected. For example: add @LocalBean annotation and inject EntityService to the REST service class.

Also i'm not sure if it is good idea to make class EntitySercice final.

pirho
  • 11,565
  • 12
  • 43
  • 70
  • 1
    +1 for *Also i'm not sure if it is good idea to make `class EntitySercice` `final`*. Also, `@LocalBean` should be also [`@Stateful` otherwise `EntityManager` could not be injected as `EXTENDED`](https://stackoverflow.com/questions/2547817/what-is-the-difference-between-transaction-scoped-persistence-context-and-extend/2548617#2548617) – Al-un Oct 14 '17 at 17:08
  • I do have the EntityService as final. I just forgot to include it with my minor obfuscation of my actual code when I wrote the question – seanr8 Oct 16 '17 at 13:49
0

Persistence context

In short, you can only inject an EntityManager into an EJB. If you're EJB is not Stateful, it won't work with an EXTENDED persistence context. Instead, you'll go with a transational one:

@Stateless
public class myService{

    @PersistenceContext(type = PersistenceContextType.TRANSACTION)
    protected EntityManager em;

}

I haven't tried this option but you can annotate your REST resource as Stateless which will allow you to inject an EntityManager

EntityManagerFactory

If you're not using EJB, then you'll need to inject the EntityManagerFactory as shown in this answer: (below is the copied code)

package com.test.service;

import java.util.*;
import javax.persistence.*;
import javax.ws.rs.*;

@Path("/service")
public class TestService {

    @PersistenceUnit(unitName = "test")
    private EntityManagerFactory entityManagerFactory;

    @GET
    public List get() {
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        try {
            // do something with entityManager
        } finally {
            entityManager.close();
        }
    }
}

Two remarks:

Al-un
  • 3,102
  • 2
  • 21
  • 40
0

I was having this issue as I had omit the starter-parent from my pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.6.RELEASE</version>
</parent>

Although I was using PersistenceContextType.EXTENDED rather than PersistenceContextType.TRANSACTION.

gregam3
  • 71
  • 2
  • 10