尝试将 Json 存储在 DB 中时,Ebean 'No service implementation found for SpiJsonService'

Posted

技术标签:

【中文标题】尝试将 Json 存储在 DB 中时,Ebean \'No service implementation found for SpiJsonService\'【英文标题】:Ebean 'No service implementation found for SpiJsonService' when trying to store Json in DB尝试将 Json 存储在 DB 中时,Ebean 'No service implementation found for SpiJsonService' 【发布时间】:2019-01-13 11:59:32 【问题描述】:

我正在尝试将模型的一部分作为 Json 存储在我的数据库中。 Ebean 应该有这个助手:

@DbJson
public Map<String, Object> jsonContent;

但是当我尝试存储我的 bean 时,它只有在我不给它 jsonContent 字段时才有效。一旦我尝试设置它,我就会收到以下错误:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.ExceptionInInitializerError]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:251)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:178)
    at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:343)
    at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:341)
    at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:414)
    at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
Caused by: java.util.concurrent.CompletionException: java.lang.ExceptionInInitializerError
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1592)
    at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1582)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.ExceptionInInitializerError: null
    at io.ebeaninternal.server.type.ScalarTypeJsonMap.formatValue(ScalarTypeJsonMap.java:166)
    at io.ebeaninternal.server.type.ScalarTypeJsonMap.bind(ScalarTypeJsonMap.java:148)
    at io.ebeaninternal.server.type.ScalarTypeJsonMap$Clob.bind(ScalarTypeJsonMap.java:55)
    at io.ebeaninternal.server.deploy.BeanProperty.bind(BeanProperty.java:648)
    at io.ebeaninternal.server.persist.dml.DmlHandler.bindInternal(DmlHandler.java:226)
    at io.ebeaninternal.server.persist.dml.DmlHandler.bind(DmlHandler.java:198)
    at io.ebeaninternal.server.persist.dmlbind.BindableProperty.dmlBind(BindableProperty.java:54)
    at io.ebeaninternal.server.persist.dmlbind.BindableList.dmlBind(BindableList.java:62)
    at io.ebeaninternal.server.persist.dml.InsertMeta.bind(InsertMeta.java:162)
    at io.ebeaninternal.server.persist.dml.InsertHandler.bind(InsertHandler.java:97)
Caused by: java.lang.IllegalStateException: No service implementation found for SpiJsonService?
    at io.ebean.text.json.EJson.init(EJson.java:31)
    at io.ebean.text.json.EJson.<clinit>(EJson.java:23)
    at io.ebeaninternal.server.type.ScalarTypeJsonMap.formatValue(ScalarTypeJsonMap.java:166)
    at io.ebeaninternal.server.type.ScalarTypeJsonMap.bind(ScalarTypeJsonMap.java:148)
    at io.ebeaninternal.server.type.ScalarTypeJsonMap$Clob.bind(ScalarTypeJsonMap.java:55)
    at io.ebeaninternal.server.deploy.BeanProperty.bind(BeanProperty.java:648)
    at io.ebeaninternal.server.persist.dml.DmlHandler.bindInternal(DmlHandler.java:226)
    at io.ebeaninternal.server.persist.dml.DmlHandler.bind(DmlHandler.java:198)
    at io.ebeaninternal.server.persist.dmlbind.BindableProperty.dmlBind(BindableProperty.java:54)
    at io.ebeaninternal.server.persist.dmlbind.BindableList.dmlBind(BindableList.java:62)
[INFO] [08/06/2018 16:03:23.475] [Thread-2] [CoordinatedShutdown(akka://sbt-web)] Starting coordinated

我的 bean 看起来像这样:

@Entity
@Table(name = "my_table")
public class MyBean extends AManageableModel 

    public static final Finder<Long, Configuration> find = new Finder<>(MyBean.class);

    @Constraints.Required
    public String name;

    @Constraints.Required
    @JsonProperty("some_property")
    public String someProperty;

    @DbJson
    @JsonProperty("json_content")
    public Map<String, Object> jsonContent;


当我使用以下 Json 在 DB 中创建一行时,它可以工作(jsonContentnull):


  "name": "test 1",
  "some_property": "some property content"

但是当我使用以下 Json 时:


  "name": "test 1",
  "some_property": "some property content",
  "json_content": 
    "test":"test",
    "test2":"test2"
  

它崩溃了(有关完整的 stackTrace,请参见帖子的开头)。

使用 Jackson 完成序列化:

Json.fromJson(jsonData, MyBean.class);

【问题讨论】:

一般来说,如果你的问题没有得到解答,并且错误/问题发生了变化,最好透明地重写它。在开头添加更新没有任何价值,因为大多数读者不会看到原版,而且它已经更新的事实会增加混乱(之前的问题是什么?)。如果你想让读者看到原来的问题,那就把“更新”或“编辑”作为标题放在底部,然后把你的新内容放在后面(这样,事情就按正确的时间顺序排列了)。读者通常不会查阅编辑历史来查看以前的版本。 你发现问题了吗?我有同样的错误:( @apflieger 我在发布后几个小时回复了这篇文章(请参阅我自己接受的答案)。基本上,我不得不将Map&lt;String,Object&gt; 更改为Map&lt;String,String&gt;。我怀疑 Map 需要包含可序列化的对象。 我很惊讶它解决了这个问题,因为异常是关于加载类 EJson,它发生在反序列化之前。您没有更改其他内容,例如移动电话Json.fromJson(jsonData, MyBean.class); 吗?我通过在应用程序启动线程中进行无用的调用EJson.write(new Object()); 来强制在该线程中加载类,从而解决了我的代码中的问题。我怀疑这是一个线程/类加载问题。在某些 CompletableFuture 异步内容中发生类的加载失败,和你一样 我很确定我不必诉诸预加载课程,但这是几个月前的事了,我很长时间没有从事这个项目了,很遗憾,我不会能够回忆更多。无论如何感谢您的反馈和意见,这可能会在未来有所帮助! 【参考方案1】:

好的,所以使用:

Map<String,String> jsonContent

而不是:

Map<String,Object> jsonContent

对我有用,所以我怀疑“对象”需要扩展可序列化的东西。

编辑: 所以,2 年后,我不得不使用 Map&lt;String,Object&gt; jsonContent 出于不相关的原因,同样的问题又回来了。这是一个肮脏的解决方案,在应用程序启动时调用它:

try 
  EJson.write(new Object());
 catch (IOException e1) 
  e1.printStackTrace();

这会强制 EJson 加载,问题就消失了....但是该死的脏吗。

【讨论】:

以上是关于尝试将 Json 存储在 DB 中时,Ebean 'No service implementation found for SpiJsonService'的主要内容,如果未能解决你的问题,请参考以下文章

将类型存储在 DB 中时的最大 MIMEType 长度

子项目中的 Ebean 模型类未增强

将数据存储在 JSON 文件中时出现类型错误。(KivyMD Python)

存储在本地存储中时 json 中不需要的反斜杠

Play Framework - Ebean - 没有为类“类名”注册 ScalarType

播放框架 Ebean BigDecimal 分数