【问题标题】:JPA Null Pointer Exception when adding to a list of entities to an entity that have @OneToMany将实体列表添加到具有 @OneToMany 的实体时出现 JPA 空指针异常
【发布时间】:2017-11-08 23:45:18
【问题描述】:

我有以下问题。我使用 Wildfly 11 作为我的 Java EE 服务器。我有一个具有地址实体列表的客户实体。当我尝试将地址列表设置给我的客户时,我收到 NullPointerException

我的地址实体:

@Entity
public class Address {

@Id
@GeneratedValue
private long id;

private String street;
private String houseNumber;

@ManyToOne
@JoinColumn
private Customer customer;
-- constructor, getters, setters --

我的客户可以有多个地址:

@Entity
public class Customer {

@Id
@GeneratedValue
private long id;

private String name;

@OneToMany(mappedBy="customer")
private List<Address> adresses;
-- constructor, getters, setters --

我还有一个启动 bean,它尝试创建地址,并且客户将地址添加到客户地址列表并保留客户。

如下所示:

@Startup
@Singleton
public class StartupBean {

    @PersistenceContext
    private EntityManager em;

    @PostConstruct
    private void init () {
        Address address = new Address();
        address.setStreet("Example Street");
        address.setHouseNumber("123");

        Customer customer = new Customer();
        customer.setName("Bob");
        customer.getAdresses().add(address);
        address.setCustomer(customer);

        em.persist(customer);
    }

现在,当我尝试将我的项目部署到 Wildfly 11 时,我在以下行收到 NullPointerException:customer.getAdresses().add(address);

这是完整的堆栈跟踪: 01:00:26,529 错误 [org.jboss.msc.service.fail] (ServerService 线程池

-- 210) MSC000001: Failed to start service jboss.deployment.subunit."my_project-ear.ear"."my_project-ejb-0.0.1-SNAPSHOT.jar".component.StartupBean.START: org.jboss.msc.service.StartException in service jboss.deployment.subunit."my_project-ear.ear"."my_project-ejb-0.0.1-SNAPSHOT.jar".component.StartupBean.START: java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
    at org.jboss.as.ee.component.ComponentStartService$1.run(ComponentStartService.java:57)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
    at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
    at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:163)
    at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:134)
    at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:88)
    at org.jboss.as.ejb3.component.singleton.SingletonComponent.getComponentInstance(SingletonComponent.java:124)
    at org.jboss.as.ejb3.component.singleton.SingletonComponent.start(SingletonComponent.java:138)
    at org.jboss.as.ee.component.ComponentStartService$1.run(ComponentStartService.java:54)
    ... 6 more
Caused by: javax.ejb.EJBException: java.lang.NullPointerException
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:188)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:277)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:354)
    at org.jboss.as.ejb3.tx.LifecycleCMTTxInterceptor.processInvocation(LifecycleCMTTxInterceptor.java:74)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.weld.injection.WeldInjectionContextInterceptor.processInvocation(WeldInjectionContextInterceptor.java:43)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ee.concurrent.ConcurrentContextInterceptor.processInvocation(ConcurrentContextInterceptor.java:45)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:60)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ejb3.component.singleton.StartupCountDownInterceptor.processInvocation(StartupCountDownInterceptor.java:25)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:53)
    at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:161)
    ... 11 more
Caused by: java.lang.NullPointerException
    at com.example.test.businesslogic.StartupBean.init(StartupBean.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptor.java:96)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.weld.interceptors.Jsr299BindingsInterceptor.doLifecycleInterception(Jsr299BindingsInterceptor.java:122)
    at org.jboss.as.weld.interceptors.Jsr299BindingsInterceptor.processInvocation(Jsr299BindingsInterceptor.java:111)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:509)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:73)
    at org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:89)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.weld.injection.WeldInjectionInterceptor.processInvocation(WeldInjectionInterceptor.java:53)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ee.component.ManagedReferenceFieldInjectionInterceptorFactory$ManagedReferenceFieldInjectionInterceptor.processInvocation(ManagedReferenceFieldInjectionInterceptorFactory.java:107)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ee.component.AroundConstructInterceptorFactory$1.processInvocation(AroundConstructInterceptorFactory.java:28)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.weld.injection.WeldInterceptorInjectionInterceptor.processInvocation(WeldInterceptorInjectionInterceptor.java:56)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.weld.interceptors.Jsr299BindingsCreateInterceptor.processInvocation(Jsr299BindingsCreateInterceptor.java:105)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275)
    ... 26 more

【问题讨论】:

  • 您好 Jacques Blanc,欢迎来到 StackOverflow。如果您可以发布完整的堆栈跟踪,那将非常有帮助。另外,我建议您在问题的前几行中说明您的问题(然后在最后重复,就像您已经完成的那样)
  • 您好,感谢您的建议。我将编辑问题并添加堆栈跟踪

标签: java hibernate jpa


【解决方案1】:

您收到空指针异常,因为您尝试添加的地址列表不存在。你必须先初始化它。而且,List 是 Java 中的一个接口。您需要实例化 List 接口的实现。

因此,您应该使用 address.setCustomer(customer); 而不是:

    List<Address> addresses = new ArrayList<>();
    addresses.add(address);
    customer.setAdresses(addresses);

还有,另一件事。这样您就不会保留您的 Address 条目。您将只拥有 Customer。而且您不会遇到任何异常,因为 FOREIGN_KEY 位于 Address 一侧,就像您映射实体一样(游览 @JoinColumn 注释位于关系的 Address 一侧)。

为了使两个实体都成功持久化,您需要像这样持久化它们。

em.persist(address);
em.persist(customer);

您坚持的顺序并不重要,因为您使用 Java EE,并且应用程序服务器负责事务,所以它实际上不会提交事务,直到您的代码结束,但我认为它更重要按此顺序保留实体是合乎逻辑的。

您可以通过在地址列表的@OneToMany 注释上使用cascade=CascadeType.ALL 属性来避免em.persist(address);

所以,应该是:@OneToMany(mappedBy="customer",cascade=CascadeType.ALL)

这样当你持久化客户时,地址也会被持久化。

【讨论】:

    猜你喜欢
    • 2015-12-04
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多