【问题标题】:PersistenceContext not injecting EntityManagerPersistenceContext 不注入 EntityManager
【发布时间】:2017-05-19 17:59:39
【问题描述】:

我在尝试通过注释 PersistenceContext 访问 EntityManager 时遇到 NullPointerException

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;

    ...
}

我的persistence.xml在路径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>

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...
}

像这样直接获取EntityManager没有问题:

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

我尝试在 jetty 和 tomEE 中运行它。

在我看来,ejb-stuff 不起作用。我在这里缺少什么(这一切都是新的)?

【问题讨论】:

  • 你在用弹簧吗??如果有,则打印完整的堆栈跟踪
  • 不,我还没有使用弹簧。堆栈跟踪仅显示我的应用程序和服务器的初始化方法。 NPE 是根本原因。
  • 看看这个链接...我认为使用'@'stateless bean的配置问题看看stackoverflow.com/questions/8544935/…

标签: java postgresql hibernate jpa


【解决方案1】:
如果持久单元是 RESOURCE_LOCAL,则必须使用

EntityManagerFactory

@PersistenceUnit    
private EntityManagerFactory emf;

您可以参考this 问题和答案以获得完整的详细信息。

【讨论】:

  • 谢谢你的链接很有帮助!我添加了这两行,但现在在访问 emf 时得到了 NullPointerException。所以我会坚持获取 emf 的程序化版本。这样我也可以保证只有一个 EntityManager (就像你的链接中建议的那样)。
【解决方案2】:

有时会发生这种情况,因为 PersistenceAnnotationBeanPostProcessor 没有被 Spring 注册。 要解决这个问题,您可以手动定义它,如下所示:

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

默认的PersistenceAnnotationBeanPostProcessor 将由&lt;context:annotation-config/&gt;&lt;context:component-scan/&gt; XML 标记注册。

【讨论】:

    【解决方案3】:

    您在哪里获取 persistence.xml 文件?如果您在 java 中进行配置(而不是 XML 配置),我知道如何获取它

    @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;
    }
    

    您还需要设置数据源:

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

    另外,您需要在配置文件上添加@EnableTransactionManagement 注释

    如果你想摆脱persistence.xml并需要完全在java中进行持久性配置,那么你需要将上面返回的LocalContainerEntityManagerFactoryBean替换为:

    @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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-10
      • 2016-01-30
      • 2019-06-15
      • 2017-05-28
      • 2016-07-18
      • 2023-03-23
      • 2018-01-20
      • 2016-10-07
      • 1970-01-01
      相关资源
      最近更新 更多