2016-04-28 6 views
7

HTTP PUTを使用して列挙型を含むエンティティを更新しようとすると、Jax-RS REST-Serviceの問題に直面しています。JAX-RS REST-Serviceを使用したHTTPの列挙

エンティティをJSONとしてエンコードするので、このJSONで使用している列挙型は文字列として配信されます。

私は、次のエラーを取得しています:

Exception [EclipseLink-43] (Eclipse Persistence Services - 2.6.2.qualifier): org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: Missing class for indicator field value [AGENT] of type [class java.lang.String]. 
Descriptor: XMLDescriptor(de.org.app.business.account.Account --> [DatabaseTable(account)]) 
    at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:940) 
    at org.eclipse.persistence.internal.oxm.QNameInheritancePolicy.classFromRow(QNameInheritancePolicy.java:278) 
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.classFromRow(TreeObjectBuilder.java:182) 
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.classFromRow(TreeObjectBuilder.java:1) 
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.initializeRecord(UnmarshalRecordImpl.java:512) 
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:748) 
    at org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader.parseRoot(JsonStructureReader.java:187) 
    at org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader.parse(JsonStructureReader.java:140) 
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:978) 
    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:708) 
    at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:643) 
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:339) 
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:668) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) 
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:74) 
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) 
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085) 
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874) 
    at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271) 
    at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.provide(EntityParamValueFactoryProvider.java:96) 
    at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71) 
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:94) 
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127) 
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:143) 
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) 
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) 
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) 
    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:305) 
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) 
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471) 
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336) 
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223) 
    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:416) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
    at java.lang.Thread.run(Thread.java:745) 

フィールド値AGENTは、エンティティのアカウントで列挙です。

列挙型を含むエンティティでのみこのエラーが発生しますが、それ以外の場合はHTTP PUTが正常に動作します。

「AGENT」はJSONの文字列として配信されるため、列挙型の値には解決できません。

簡単な回避策はありますか?

ありがとうございました!

いくつかのより多くのコードの編集:

さて、列挙型は次のように定義されています。このような

@XmlType(name = "type") 
@XmlEnum 
public enum AccountType implements TranslatableEnum { 
    @XmlEnumValue(value = "lov.account.type.customer") 
    CUSTOMER("lov.account.type.customer"), 
    @XmlEnumValue(value = "lov.account.type.agent") 
    AGENT("lov.account.type.agent") 
    //just getter/setter things following 
} 

のHTTP PUT REST-サービス:

@PUT 
@Path(value = "{id}") 
@Consumes(value = MediaType.APPLICATION_JSON) 
public void edit(@PathParam(value = "id") final String id, final T entity) { 
    getRepository().update(entity); 
} 

update-と機能:

public T update(@Observes @Update T entity) { 
    getEntityManager().merge(entity); 
    return entity; 
} 

提案はありますか?

+0

次の解決方法を試したことがありますか?http://stackoverflow.com/a/12292355/1346996? – aribeiro

+0

あなたの提案をありがとう、私はそれを試みたが、エラーは同じままです。 – EsSuch

+1

入ってくるjsonとそれを逆シリアル化するクラスを追加できますか? – Ilya

答えて

2

@XmlEnumValue annotationは、どの文字列値が注釈付き列挙定数にマップされるかを宣言します。あなたはその後、

@XmlEnumValue(value = "lov.account.type.customer") 
CUSTOMER("lov.account.type.customer") 

を書くとき、すなわちCUSTOMER定数はlov.account.type.customer文字列にマッピングされています。あなたはCUSTOMER定数がCUSTOMER文字列にマッピングされているかどう

だから、あなたは今、私はそのルートを参照してください

@XmlEnumValue(value = "CUSTOMER") 
CUSTOMER("lov.account.type.customer") 

または@XmlEnumValue注釈すなわち

@XmlEnum 
public enum AccountType implements TranslatableEnum { 
    CUSTOMER("lov.account.type.customer"), 
    AGENT("lov.account.type.agent") 
    //... 
} 


UPD を削除を作成する必要があります問題は継承です。継承されたクラスを逆シリアル化しようとすると、デフォルトでは@typeフィールドが使用され、どの入力がどの入力に対してインスタンス化されるかが決定されます。 this answerを参照してください。あなたの状況に応じていくつかの方法があります。

第一の方法(十分な汚れ)
あなたはあなたがAccountType定数との間の正確な関係を持っている場合は、1子クラス

第二の方法
を持っている場合のみ適用され@XmlDiscriminatorNode("fakeField")であなたのスーパータイプに注釈を付けることを試みることができ 子クラスでは、各子クラスに@XmlDiscriminatorValue注釈で注釈を付ける必要があります。
例:

@XmlRootElement 
public static class Parent { 
    AccountType type; 

    public AccountType getType() { 
     return type; 
    } 

    public void setType(AccountType type) { 
     this.type = type; 
    } 
} 


@XmlDiscriminatorValue("AGENT") 
public static class Agent extends Parent { 

} 

@XmlDiscriminatorValue("CUSTOMER") 
public static class Customer extends Parent { 

} 
+0

アドバイスありがとうございますが、それでも動作しません。その他の提案はありますか? – EsSuch

+0

同じ例外がありますか? – Ilya

+0

はい、100%同一です。 – EsSuch

1

それはまったく同じシナリオではありませんが、私はJSONと列挙型を使用してジャージーで同様の問題がありました。私はあなたの列挙型の定義で参照

ことの一つは、あなたが列挙

AGENT("lov.account.type.agent") 

のカスタム名を指定することである。しかし、あなたがJSONデータにエージェントを送っているようです。代わりに 'lov.account.type.agent'を送信してはいけませんか?

関連する問題