java - 为什么在使用 Play 时从数据库获取 List<String> 时它是空的?

标签 java intellij-idea playframework nullpointerexception ebean

好的,我正在使用 Play 框架创建一个 Web 应用程序。 我正在尝试将 ArrayList 添加到模型中并使用 Ebean 保存它。

这些是一些规范。

  1. Intellij IDEA 2016.2.5
  2. Play 2.5.9
  3. Windows 10
  4. Java 版本 8 更新 111
  5. Ebean 3.0.2

ArrayList 是 String 类型的列表。

当我想保存它时,给出的值是正确的,但是当我想从数据库加载它时,Play 指出 ArrayList 为空。

这基本上是我尝试保存的模型:

@Entity
public class Strike extends Model{

  public Strike()
  {
  }

  //@OneToMany(cascade = CascadeType.ALL, targetEntity = String.class)
  public List<String> sectors = new ArrayList<>();

  public static Finder<Integer, Strike> find = new Finder<>(Strike.class);

  public static List<Strike> getAllStrikes()
  {
    List<Strike> strikes = Ebean.find(Strike.class).findList();
    return strikes;
  }

  public List<String> getSectors() {
    return sectors;
  }

  public void setSectors(List<String> sectors) {
    this.sectors = sectors;
  }
}

“@OneToMany”行已被注释,否则我会收到注入(inject)错误(或类似的错误)。

使用以下代码接收填充 ArrayList 的数据:

Strike strike = formFactory.form(Strike.class).bindFromRequest().get();
strike.save();

HTML 代码如下所示:

<div class="selectize-control form-inline">
    <select multiple class="form-control input-full-width selectized" name="sectors[]" id="sectors" placeholder="Select sectors...">
       <option id="0" value="Number 0" >Number 0</option>
       <option id="1" value="Number 1" >Number 1</option>
       <option id="2" value="Number 2" >Number 2</option>
       <option id="3" value="Number 3" >Number 3</option>
    </select>
</div>

将输出写入控制台时,我得到:["Number 0","Number 1","Number 2","Number 3"]

但是,当尝试执行以下操作时,我收到 NullPointerException:

System.out.println(toJson(new Model.Finder(Strike.class).all()));

具体来说,这个错误:

[error] application - ! @72386p78b - Internal server error, for (GET) [/strikes] ->

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.NullPointerException]]
        at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
        at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
        at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
        at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
        at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
        at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
        at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
        at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
        at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: java.util.concurrent.CompletionException: java.lang.NullPointerException
        at java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
        at java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
        at java.util.concurrent.CompletableFuture.uniApply(Unknown Source)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(Unknown Source)
        at java.util.concurrent.CompletableFuture.postComplete(Unknown Source)
        at java.util.concurrent.CompletableFuture.completeExceptionally(Unknown Source)
        at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:21)
        at scala.concurrent.java8.FuturesConvertersImpl$CF.apply(FutureConvertersImpl.scala:18)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
        at scala.concurrent.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:63)
Caused by: java.lang.NullPointerException: null
        at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.createReference(BeanPropertyAssocMany.java:634)
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptor.lazyLoadMany(BeanDescriptor.java:1887)
        at com.avaje.ebeaninternal.server.core.DefaultBeanLoader.refreshBeanInternal(DefaultBeanLoader.java:279)
        at com.avaje.ebeaninternal.server.core.DefaultBeanLoader.loadBean(DefaultBeanLoader.java:240)
        at com.avaje.ebeaninternal.server.core.DefaultServer.loadBean(DefaultServer.java:484)
        at com.avaje.ebean.bean.EntityBeanIntercept.loadBeanInternal(EntityBeanIntercept.java:785)
        at com.avaje.ebean.bean.EntityBeanIntercept.loadBean(EntityBeanIntercept.java:750)
        at com.avaje.ebean.bean.EntityBeanIntercept.preGetter(EntityBeanIntercept.java:845)
        at models.Strike._ebean_get_sectors(Strike.java:6)
        at models.Strike.getSectors(Strike.java:277)

有人知道这是怎么发生的吗?

最重要的是,如何修复它?

将不胜感激!

如果您需要更多信息,请询问:)

最佳答案

@911DidBush 已回答您的问题

我只是添加我自己的解决方案

您的 Strike 实体具有覆盖的保存方法

package models;

import com.avaje.ebean.Model;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Strike extends Model {

    public static Finder<Long, Strike> find = new Finder<>(Strike.class);

    @Id
    public Long id;

    @OneToMany(cascade = CascadeType.ALL)
    public List<Sector> sectors = new ArrayList<>();

    @Transient
    public List<String> sectorNames = new ArrayList<>();

    @Override
    public void save(){
        sectorNames.stream().forEach(name->{
            Sector sector = new Sector();
            sector.name = name;
            sectors.add(sector);
        });
        super.save();
    }
}

用于存储扇区的新扇区实体

package models;

import com.avaje.ebean.Model;
import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Sector extends Model{

    @Id
    public Long id;

    @ManyToOne
    @JsonIgnore
    public Strike strike;

    public String name;
}

还将选择的名称更改为 name="sectorNames[]"

<select multiple class="form-control input-full-width selectized" name="sectorNames[]" id="sectors" placeholder="Select sectors...">

如果您需要 Controller 方法,这里是:

 public Result save(){
        Form<Strike> strikeForm = formFactory.form(Strike.class).bindFromRequest();
        if(strikeForm.hasErrors()){
            return badRequest(strikeForm.errorsAsJson());
        }
        strikeForm.get().save();
        return ok(Json.toJson(Strike.find.all()));
    }

关于java - 为什么在使用 Play 时从数据库获取 List<String> 时它是空的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40551914/

相关文章:

java - 图像从一侧移动到另一侧

java - @InjectMocks 通过构造函数和 setter 注入(inject) @MockBean 无法正常工作

android - 如何设置 Android Studio 以便在离线时(断开与互联网的连接)进行编译

java - 如何为未映射到实体的表编写原始 Play 查询

java - 使用 JsonView 将 POJO 转换为 JsonNode

java - 编码名称是 UTF8 还是 UTF-8?

java - 如何使用 Java 套接字检测数据丢失?

intellij-idea - 想法 : How to suppress warnings for spelling typos?

java - jsf:请求的资源不可用

java - 玩Scala模板,定义对象变量