0

I am trying to use @PersistenceContext to have Container-Managed Persistence with no lucks for couple of days now, I have searched every single related question. I am using:
- IntelliJ14
- Jersey 2
- JPA 2
- webapp schema 3.1
- EJB 3

I have tried so many things nothing worked for me, it only works if I use the transaction type is "Resource_Local" with creating EntityManagerFactory myself. I have looked at all similar questions here, please any help would be appreciated! I am getting this error:

Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=PersistenceManager,parent=UserController,qualifiers={},position=-1,optional=false,self=false,unqualified=null,454129121)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74) [hk2-locator-2.4.0-b25.jar:]
    at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:214) [hk2-locator-2.4.0-b25.jar:]
    at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:237) [hk2-locator-2.4.0-b25.jar:]
    ... 56 more

here is my current code:
web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

  <display-name>Rest</display-name>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.mudhar.rest.controller</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="mudhar" transaction-type="JTA">
        <class>com.mudhar.rest.model.User</class>
        <properties>
            <property name="hibernate.enable_lazy_load_no_trans" value="true" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/mudhardb" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        </properties>
    </persistence-unit>
</persistence>

Service Resource:

package com.mudhar.rest.controller;

import com.mudhar.rest.dao.PersistenceManager;
import com.mudhar.rest.model.RequestBody;
import com.mudhar.rest.model.User;

import javax.ejb.EJB;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.sql.Timestamp;

@Path("/user")
public class UserController {

    @Inject
    PersistenceManager persistenceManager;

    @POST
    @Path("/get")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(RequestBody body) {

        String idUser = body.getIdUser();

        EntityManager em = persistenceManager.getEntityManager();
        em.getTransaction().begin();

        User user = em.find(User.class, Long.valueOf(idUser));

        em.getTransaction().commit();
        em.close();
        return user;
    }

    @PUT
    @Path("/add")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public String addUser(User user){

        System.out.println(user.toString());
        String result = "Success";
        EntityManager em = persistenceManager.getEntityManager();
        em.getTransaction().begin();
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        user.setTimestamp(timestamp);
        try {
            em.merge(user);
            em.getTransaction().commit();
        }catch (Exception e){
            e.printStackTrace();
            result = "Failed";
        }

        em.close();
        return result;

    }

}

PersistenceManager.java

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;

@Stateless
public class PersistenceManager {

    @PersistenceContext(unitName = "mudhar")
    private EntityManager em;


    public EntityManager getEntityManager() {
        return em;
    }
    public void close() {
        em.close();
    }
}

pom.xml

<properties>
    <jersey2.version>2.19</jersey2.version>
    <jaxrs.version>2.0.1</jaxrs.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- JAX-RS -->
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>${jaxrs.version}</version>
    </dependency>
    <!-- Jersey 2.19 -->
    <dependency>
      <groupId>org.glassfish.jersey.containers</groupId>
      <artifactId>jersey-container-servlet</artifactId>
      <version>${jersey2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-server</artifactId>
      <version>${jersey2.version}</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.1-api -->
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
      <version>1.0.0.Final</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
    <dependency>
      <groupId>org.glassfish.jersey.media</groupId>
      <artifactId>jersey-media-json-jackson</artifactId>
      <version>2.19</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.ejb/ejb-api -->
    <dependency>
      <groupId>javax.ejb</groupId>
      <artifactId>ejb-api</artifactId>
      <version>3.0</version>
      <scope>provided</scope>
    </dependency>


  </dependencies>
  <build>
    <finalName>DealderRest</finalName>
  </build>
</project>
newmudhar
  • 11
  • 6
  • The persistence xml you have defined is for application managed datasource. Typically, for container managed datasource, the configuration will lie outside your application (for glassfish, go to glassfish admin and change the jdbc connection with the name `mudhar`) – maress Aug 07 '17 at 16:50
  • I have the transaction type as JTA which means it should be a container managed – newmudhar Aug 07 '17 at 17:10
  • Did you try to directly inject an EntityManager using @PersistenceContext into UserController? Or why do you say, that the PersistenceContext is the problem? The error signals that PersistenceManager is not available. – aschoerk Aug 07 '17 at 18:09
  • I just tried it and I've got java.lang.NullPointerException – newmudhar Aug 07 '17 at 23:29
  • Have you added Jersey jars to your project? – Steve C Aug 08 '17 at 12:57
  • yes I did, sorry forgot to include pom.xml...see in the post...just added pom – newmudhar Aug 09 '17 at 01:29

2 Answers2

0

I think you're missing an AbstractBinder implementation like this answer suggests for the same exception.

ytg
  • 1,755
  • 2
  • 23
  • 41
  • Thank you...Although my error is similar I think that one is slightly different...and I have aleady tried it just to make sure and it didn't work with same error – newmudhar Aug 07 '17 at 12:52
0

I'm guessing that you're building a WAR file and deploying to GlassFish or Payara.

In any case, you need to add <scope>provided</scope> to the following dependencies:

  • javax.ws.rs-api
  • hibernate-jpa-2.1-api

and completely remove:

  • jersey-container-servlet
  • jersey-server
  • jersey-media-json-jackson

These jars are replacing the server implementations with code that does not have the integration required to be able to inject entity managers or EJBs.

Completely remove the web.xml file as it is redundant.

Finally, I recommend that you forget about your PersistenceManager class for now and change UserController as follows:

@Stateless
@Path("/user")
public class UserController {

    @PersistenceContext(unitName = "mudhar")
    private EntityManager em;

    @POST
    @Path("/get")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(RequestBody body) {

        String idUser = body.getIdUser();    
        User user = em.find(User.class, Long.valueOf(idUser));    
        return user;
    }

    @PUT
    @Path("/add")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public String addUser(User user){

        System.out.println(user.toString());
        String result = "Success";
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        user.setTimestamp(timestamp);
        user = em.merge(user);
        return result;

    }

}

You can see that this is much simpler. Note that it has been annotated @Stateless so it's now an EJB, so you get transaction management and other features for the price of one line of code.

Note that if you're using GlassFish/Payara then the JPA implementation will be EclipseLink and not Hibernate.

Steve C
  • 18,876
  • 5
  • 34
  • 37
  • even that didn't work for me, I am using JBoss, I gave up currently on the CDI and doing application managed persistence, it is annoying but nothing worked for me unfortunately. if anyone has any other suggestions I am down to try anything! – newmudhar Aug 26 '17 at 21:43
  • Have a look at my answer to [Java EntityManager null with @PersistenceContext](https://stackoverflow.com/questions/45889496/java-entitymanager-null-with-persistencecontext/45891252#45891252), which is similar to your issue and works on WildFly – Steve C Aug 27 '17 at 02:27