1

I have a web service that throws an exception when called. It fails with marshalling my entity. Can anyone see what im doing wrong. (I have omitted lots of code for readability)

My entities

@Entity
@Table(name="Question", schema="exam")
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Question extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @ManyToMany
    @JoinTable(name="Questions_Answers", schema="relation",
            joinColumns=@JoinColumn(name="questionId", referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(name="answerId", referencedColumnName="id"))
    private List<Answer> answers = new ArrayList<Answer>(); 



    public List<Answer> getAnswers(){
        return this.answers;
    }

    public void setAnswers(List<Answer> answers){
        this.answers = answers;
    }   


}


@Entity
@Table(name="Answer", schema="exam")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="AnswerType", discriminatorType=DiscriminatorType.STRING)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlSeeAlso({MultipleAnswer.class})
public abstract class Answer extends BaseEntity {

    private static final long serialVersionUID = 1L;    

    @ManyToMany(mappedBy="answers")
    private List<Question> questions = new ArrayList<Question>();


    @XmlTransient
    public List<Question> getQuestions() {
        return questions;
    }

    public void setQuestions(List<Question> questions) {
        this.questions = questions;
    }   
}

@Entity
@Table(name="MultipleAnswer", schema="exam")
@DiscriminatorValue(value="MULTIPLE_CHOICE")
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class MultipleAnswer extends Answer {

    private static final long serialVersionUID = 1L;

    public MultipleAnswer(){

    }   

    @Column(name="answer")
    private String answer;  

    @Column(name="answerExplanation")
    private String answerExplanation;

    @Column(name="isCorrect")
    private boolean isCorrect;  

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    public String getAnswerExplanation() {
        return answerExplanation;
    }

    public void setAnswerExplanation(String answerExplanation) {
        this.answerExplanation = answerExplanation;
    }

    public boolean isCorrect() {
        return isCorrect;
    }

    public void setCorrect(boolean isCorrect) {
        this.isCorrect = isCorrect;
    }   
}

Web service

@POST
@Path("/save")
@Consumes({MediaType.APPLICATION_JSON})
public void saveQuestion(Question question) {
    log.warning("Title: " + question.getTitle());
    log.warning("Number of answers: " + question.getAnswers().size());
}

Exception

Exception [EclipseLink-44] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class indicator field from database row [UnmarshalRecordImpl()].
Descriptor: XMLDescriptor(se.questify.entities.exam.Answer --> [DatabaseTable(answer)])
    at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:957)
    at org.eclipse.persistence.internal.oxm.XMLRelationshipMappingNodeValue.processChild(XMLRelationshipMappingNodeValue.java:83)
    at org.eclipse.persistence.internal.oxm.XMLCompositeCollectionMappingNodeValue.startElement(XMLCompositeCollectionMappingNodeValue.java:184)
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:834)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:421)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:241)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:179)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:972)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:425)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:375)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:705)
    at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:580)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:181)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:72)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
    at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:245)
    at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.get(EntityParamValueFactoryProvider.java:96)
    at org.glassfish.jersey.server.internal.inject.AbstractHttpContextValueFactory.provide(AbstractHttpContextValueFactory.java:66)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:722)
4

1 回答 1

0

你的班级Question有一个ListAnswer由于Answer是一个抽象类,因此您需要在相应值上使用类型指示符,如下所示以避免异常。

{
   "answers" : [ {
      "type" : "multipleAnswer",
      "correct" : false
   }, {
      "type" : "multipleAnswer",
      "correct" : true
   } ]
}
于 2013-10-11T18:00:27.937 回答