使用Play时,为什么我的List <string>从数据库中获取时为空?

时间:2016-11-11 16:10:26

标签: java intellij-idea playframework nullpointerexception ebean

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

这些是一些规格。

  1. Intellij IDEA 2016.2.5
  2. 播放2.5.9
  3. Windows 10
  4. Java Version 8 Update 111
  5. Ebean 3.0.2
  6. ArrayList是String类型的List。

    当我想保存它时,正确地给出了值,但是当我想从数据库加载它时,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”这一行,因为否则我会在注射时遇到错误(或类似的东西)。

    使用以下代码接收填充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)
    

    有谁知道这会怎么样?

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

    非常感谢!

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

1 个答案:

答案 0 :(得分:1)

@ 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;
}

还将select的名称更改为name =“sectorNames []”

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

如果你需要控制器方法,这里是:

 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()));
    }