3

I am getting a NullPointerException when trying to access the EntityManager via annotation PersistenceContext

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;

@Stateless
public class UserService {

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

    ...
}

My persistence.xmlin path src/main/webapp/META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/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_1_0.xsd">
    <persistence-unit name="jcrdb" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!-- <jta-data-source>jdbc/jcrdb</jta-data-source> -->
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <!-- this tell Hibernate to update the DDL when it starts, very useful 
                for development, dangerous in production -->
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="javax.persistence.logging.level" value="INFO" />
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:5432/jcrdb" />
            <property name="javax.persistence.jdbc.user" value="jcr_admin" />
            <property name="javax.persistence.jdbc.password" value="q1w2e3r4" />
            <!-- <property name="tomee.jpa.factory.lazy" value="true" />-->
        </properties>
    </persistence-unit>
</persistence>

The User-class:

@Entity
@Table(name = "Users")
public class User {

    @Id
    @GeneratedValue(generator = "increment")
    @GenericGenerator(name = "increment", strategy = "increment")
    private int UserId;
    private String alias;
    private String email;
    @OneToOne(fetch = FetchType.LAZY)
    private Person person;
    @OneToMany
    private List<Role> roles;

    public User() {

    }

    // constructor, getters, setters...
}

There is no problem getting the EntityManager directly like this:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jcrdb");
em = entityManagerFactory.createEntityManager();

I tried running this in jetty and tomEE.

It seems to me that the ejb-stuff isn't working. What am I missing here (new to all this)?

sotix
  • 822
  • 1
  • 8
  • 23
  • are you using spring ?? Print a full stack trace if you have – goodyzain Jan 05 '17 at 09:08
  • No I am not using spring yet. The stack trace only shows the initialization methods of my app and the server. The NPE is the root cause. – sotix Jan 05 '17 at 09:52
  • have a look on this link...I think the problem with the configurations using '@'stateless bean have a look http://stackoverflow.com/questions/8544935/problems-in-injecting-entity-manager-into-stateless-bean – goodyzain Jan 05 '17 at 10:03

3 Answers3

2

EntityManagerFactory must be used if the persistent unit is RESOURCE_LOCAL.

@PersistenceUnit    
private EntityManagerFactory emf;

You might refer to this question and answers for the full detail.

Community
  • 1
  • 1
Quincy
  • 4,393
  • 3
  • 26
  • 40
  • Thank you the link was very helpful! I added the two lines but now get a NullPointerException on accessing emf. So I will stick to the programmatic version of getting the emf. This way I can also assure to only have one EntityManager (like it was suggested in your link). – sotix Jan 05 '17 at 09:51
1

Sometimes this happens because PersistenceAnnotationBeanPostProcessor is not registered by Spring. To fix that you can define it manually as follows:

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

A default PersistenceAnnotationBeanPostProcessor will be registered by the <context:annotation-config/> and <context:component-scan/> XML tags.

Eugene Maysyuk
  • 2,977
  • 25
  • 24
0

Where are you picking up that persistence.xml file? I know how you can pick it up if you have your configuration in java (instead of XML configuration)

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
LocalContainerEntityManagerFactoryBean factory =
new LocalContainerEntityManagerFactoryBean();
factory.setPersistenceXmlLocation(
"classpath:...../persistence.xml"
);
//factory.setPersistenceUnitName("whatever");
factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factory.setDataSource(this.springJpaDataSource());
return factory;
}

You will also need to setup DataSource:

@Bean
public DataSource springJpaDataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:mysql://localhost/ABCXYZ");
dataSource.setUsername("tomcatUser");
dataSource.setPassword("password1234");
return dataSource;
}

Also, you will need @EnableTransactionManagement annotation over the configuration file

If you want to get rid of persistence.xml and need to make persistence configuration totally in java, then you will need to replace above that returns LocalContainerEntityManagerFactoryBean with this:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
{
Map<String, Object> properties = new Hashtable<>();
properties.put("javax.persistence.schema-generation.database.action",
"none");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
LocalContainerEntityManagerFactoryBean factory =
new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(adapter);
factory.setDataSource(this.springJpaDataSource());
factory.setPackagesToScan("com.wrox.site.entities");
factory.setSharedCacheMode(SharedCacheMode.ENABLE_SELECTIVE);
factory.setValidationMode(ValidationMode.NONE);
Configuring Persistence in Spring Framework ❘ 605
factory.setJpaPropertyMap(properties);
return factory;
}
Faraz
  • 6,025
  • 5
  • 31
  • 88