Вопрос:

Исключение нулевого указателя JPA при добавлении в список объектов для объекта, у которого есть @OneToMany

java hibernate jpa

636 просмотра

1 ответ

8 Репутация автора

У меня есть следующая проблема. Я использую Wildfly 11 в качестве сервера Java EE. У меня есть объект Customer, у которого есть список объектов Address. Я получаю исключение 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 --

У меня также есть стартовый компонент, который пытается создать адрес, и клиент добавляет адрес в список адресов клиента и сохраняет его.

Вот как это выглядит:

@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 Источник Размещён: 08.11.2017 11:45

Ответы (1)


1 плюс

660 Репутация автора

Решение

Вы получаете исключение нулевого указателя, потому что список адресов, которые вы пытаетесь добавить, не существует. Вы должны инициализировать это сначала. А также, List - это интерфейс на Java. Вам нужно создать экземпляр реализации интерфейса List.

Итак, вместо address.setCustomer(customer);вас должно быть:

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

И еще одна вещь. Таким образом, вы не сможете сохранить ваш адрес . Вы бы просто имели клиента . И вы не получите никаких исключений, потому что FOREIGN_KEY находится на стороне адреса так же, как вы отображали свои сущности (аннотация tour @JoinColumn находится на стороне адреса отношения).

Для того, чтобы обе сущности успешно сохранялись, вам нужно сохранить их обеими вот так.

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

Порядок, в котором вы сохраняете, не важен, потому что вы используете Java EE, а сервер приложений заботится о транзакциях, поэтому он фактически не будет фиксировать транзакцию до конца вашего кода, однако я думаю, что логичнее будет сохранить сущности в этом порядке.

Вы можете избежать em.persist(address);использования cascade=CascadeType.ALLсвойства аннотации @OneToMany в вашем списке адресов.

Итак, было бы: @OneToMany(mappedBy="customer",cascade=CascadeType.ALL)

Таким образом, когда вы сохраняете Клиента , адрес также сохраняется.

Автор: user3362334 Размещён: 08.11.2017 11:56
Вопросы из категории :
32x32