2010-07-22 12 views
5

У меня есть веб-сервис JAX-RS, который использует классы сущностей JPA. У меня есть класс ресурсов, как это:NPE Thrown Marshalling Entity в JAX-RS

@Path("/entity") 
public class MyEntityResource 
{ 
    @GET 
    @Produces(MediaType.APPLICATION_XML) 
    @Path("/{entity}") 
    public MyEntity getMyEntity(@PathParam("entity") String entity) 
    { 
     log.debug("Entering getMyEntity with param: " + entity); 
     MyEntity entityObject = genericService.find(MyEntity.class, entity); 

     if (entityObject == null) 
     { 
      log.debug("Entity not found."); 
      throw new WebApplicationException(Response.Status.NOT_FOUND); 
     } 

     log.debug("Exiting getMyEntity"); 

     return entityObject; 
    } 
} 

Когда я запустить службу и сделать ПОЛУЧИТЬ вызов на объект, я получаю эту ошибку:

SEVERE: The response of the WebApplicationException cannot be utilized as the response is already committed. Re-throwing to the HTTP container 
javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException 
- with linked exception: 
[Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.XMLMarshalException 
Exception Description: An error occurred marshalling the object 
Internal Exception: java.lang.NullPointerException] 
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:151) 
... 
<snip> 
... 
Caused by: javax.xml.bind.MarshalException 
- with linked exception: 
[Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.XMLMarshalException 
Exception Description: An error occurred marshalling the object 
Internal Exception: java.lang.NullPointerException] 
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:271) 
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:171) 
    at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:149) 
    ... 32 more 
Caused by: Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.XMLMarshalException 
Exception Description: An error occurred marshalling the object 
Internal Exception: java.lang.NullPointerException 
    at org.eclipse.persistence.exceptions.XMLMarshalException.marshalException(XMLMarshalException.java:76) 
    at org.eclipse.persistence.oxm.XMLMarshaller.marshal(XMLMarshaller.java:502) 
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:269) 
    ... 34 more 
Caused by: java.lang.NullPointerException 
    at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConverted(ConversionException.java:69) 
... 
<snip> 
... 
    at org.eclipse.persistence.oxm.XMLMarshaller.marshal(XMLMarshaller.java:916) 
    at org.eclipse.persistence.oxm.XMLMarshaller.marshal(XMLMarshaller.java:468) 
    ... 35 more 

Нигде ни в одном из трассировки стека в любой из моих классов. Кроме того, оператор "Exiting getMyEntity" регистрируется до исключения.

Я понятия не имею, что бросает NPE или как отлаживать это.

Перед этой ошибкой я получил [com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: из моих сущностей класса JPA (EclipseLink), и я добавил аннотацию MOXy @XmlInverseReference к моему дочернему классу в методе родительского метода getter.

Любые мысли о том, что может быть причиной этого исключения?

ответ

4

Мы провели некоторые форума дискуссии по этому вопросу, а также в интересах других, которые находят этот пост ниже является правильной настройки использования @XmlInverseReference на нескольких уровнях:

Entity А

import java.io.Serializable; 
import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

import java.util.Set; 

@Entity 
@XmlRootElement 
public class EntityA implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String name; 
    private Set<EntityB> entityBs; 

    @Id 
    @XmlAttribute 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @OneToMany(mappedBy = "entityABean") 
    @XmlElement 
    public Set<EntityB> getEntityBs() { 
     return this.entityBs; 
    } 

    public void setEntityBs(Set<EntityB> entityBs) { 
     this.entityBs = entityBs; 
    } 

} 

Компания Б

import java.io.Serializable; 
import javax.persistence.*; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

import org.eclipse.persistence.oxm.annotations.XmlInverseReference; 

import java.util.Set; 

@Entity 
@XmlRootElement 
public class EntityB implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String name; 
    private Set<EntityC> entityCs; 
    private EntityA entityABean; 

    @Id 
    @XmlAttribute 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToOne 
    @JoinColumn(name = "EntityA") 
    @XmlInverseReference(mappedBy = "entityBs") 
    public EntityA getEntityABean() { 
     return this.entityABean; 
    } 

    public void setEntityABean(EntityA entityABean) { 
     this.entityABean = entityABean; 
    } 

    @OneToMany(mappedBy = "entityBBean") 
    @XmlElement 
    public Set<EntityC> getEntityCs() { 
     return this.entityCs; 
    } 

    public void setEntityCs(Set<EntityC> entityCs) { 
     this.entityCs = entityCs; 
    } 
} 

Предприятие С

import java.io.Serializable; 
import javax.persistence.*; 

import org.eclipse.persistence.oxm.annotations.XmlInverseReference; 

@Entity 
public class EntityC implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String name; 
    private EntityB entityBBean; 

    @Id 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToOne 
    @JoinColumn(name = "EntityB") 
    @XmlInverseReference(mappedBy = "entityCs") 
    public EntityB getEntityBBean() { 
     return this.entityBBean; 
    } 

    public void setEntityBBean(EntityB entityBBean) { 
     this.entityBBean = entityBBean; 
    } 
} 

Demo

import java.io.FileInputStream; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(EntityA.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     FileInputStream xml = new FileInputStream("src/test/jaxb/input.xml"); 
     EntityA a = (EntityA) unmarshaller.unmarshal(xml); 

     for(EntityB b : a.getEntityBs()) { 
      System.out.println(b.getEntityABean()); 
      for(EntityC c : b.getEntityCs()) { 
       System.out.println(c.getEntityBBean()); 
      } 
     } 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(a, System.out); 
    } 

} 

Демо - Выход

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

Input.xml

<?xml version="1.0" encoding="UTF-8"?> 
<entityA> 
    <entityBs> 
     <entityCs/> 
     <entityCs/> 
    </entityBs> 
    <entityBs> 
     <entityCs/> 
     <entityCs/> 
    </entityBs> 
</entityA> 

Этот вопрос также обрабатывается на форумах EclipseLink, для получения дополнительной информации см:

Ниже еще один пример использования @XmlInverseReference с моделью JPA

+0

В дополнение к вышесказанному, NPE был вызван из поля Timestamp в классе/элементе grandchild, который был нулевым. Я расширил XmlAdapter, чтобы обрабатывать сортировку Timestamps, и это бросило NPE. – sdoca

1

Включил ли вы файл jaxb.properties в свои классы сущностей?

Заканчивать ответ Блейза на этот вопрос: JAXB Mapping cyclic references to XML

Надеется, что это помогает. RG

+0

Из трассировки стека, файл jaxb.properties, кажется, на месте. –

+0

Спасибо за ответ. Да, у меня есть джакс.Свойства файла с этим содержимым: # Указывает, что реализация EclipseLink Moxy JAXB следует использовать javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory Я считаю, что это читается потому трассировки стека относится к: org.eclipse.persistence.jaxb.JAXBMarshaller.marshal (JAXBMarshaller.java:271) я видел другую должность, где я узнал о Moxy и @XmlInverseReference аннотации, которую я использовал в своем коде , – sdoca

 Смежные вопросы

  • Нет связанных вопросов^_^