0
votes

I'am using Play Framework to build a simple Product API with ORM EBean

This is my specification:

  1. Java 1.8
  2. Eclipse 2020-06
  3. Play 2.8.13
  4. Scala 2.13.6
  5. Ebean 5.2.4

I followed the code from several sources:

  1. https://github.com/siddharths067/ebeancrud
  2. https://www.youtube.com/watch?v=6yxJuRng9bU&list=PLYPFxrXyK0Bx9SBkNhJr1e2-NlIq4E7ED&index=22

Product Model:

package models;

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

import io.ebean.Finder;
import io.ebean.Model;

@Entity
public class Product extends Model {
    @Id
    private int id;
    
    private String name;
    private String category;
    private int quantity;
    private double price;
    
    public static Finder<Integer, Product> find = new Finder<Integer, Product>(Product.class);
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Product Controller:

package controllers;

import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;

import models.Product;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Result;

public class ProductController extends Controller {

    public Result index() {
        List<Product> products = Product.find.all();
        return ok(Json.toJson(products));
    }
    
    public Result store(Http.Request request) {
        JsonNode productJSON = request.body().asJson();
        Product product = Json.fromJson(productJSON, Product.class);
        product.save();
        return ok("Product has stored");
    }
    
    public Result show(Integer id) {
         Product product = Product.find.byId(id);
        return ok("oke");
    }
    
    public Result update(Http.Request request, Integer id) {
        JsonNode productJSON = request.body().asJson();
    
        Product oldProduct = Product.find.byId(id);
        Product newProduct = Json.fromJson(productJSON, Product.class);
        
        oldProduct.setName(newProduct.getName());
        oldProduct.setCategory(newProduct.getCategory());
        oldProduct.setQuantity(newProduct.getQuantity());
        oldProduct.setPrice(newProduct.getPrice());
        oldProduct.update();
        
        return ok("Product has updated");
    }
    
    public Result destroy(Integer id) {
        Product product = Product.find.byId(id);
        product.delete();
        return ok("Product has deleted");
    }
}

But why I got following exception when retrieve all data from database to JSON:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[RuntimeException: java.lang.IllegalArgumentException: No serializer found for class io.ebeaninternal.server.transaction.DefaultPersistenceContext and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.ebean.common.BeanList[0]->models.Product["_ebean_intercept"]->io.ebean.bean.EntityBeanIntercept["persistenceContext"])]]
        at play.api.http.HttpErrorHandlerExceptions$.$anonfun$convertToPlayException$2(HttpErrorHandler.scala:381)
        at scala.Option.map(Option.scala:242)
        at play.api.http.HttpErrorHandlerExceptions$.convertToPlayException(HttpErrorHandler.scala:380)
        at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:373)
        at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:264)
        at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:430)
        at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:422)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:454)
        at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:63)
        at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:100)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: No serializer found for class io.ebeaninternal.server.transaction.DefaultPersistenceContext and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.ebean.common.BeanList[0]->models.Product["_ebean_intercept"]->io.ebean.bean.EntityBeanIntercept["persistenceContext"])
        at play.libs.Json.toJson(Json.java:94)
        at controllers.ProductController.index(ProductController.java:17)
        at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$4(Routes.scala:202)
        at play.core.routing.HandlerInvokerFactory$$anon$6.resultCall(HandlerInvoker.scala:142)
        at play.core.routing.HandlerInvokerFactory$$anon$6.resultCall(HandlerInvoker.scala:141)
        at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$3$$anon$4$$anon$5.invocation(HandlerInvoker.scala:115)
        at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:119)
        at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:33)
        at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:175)
        at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:672)
Caused by: java.lang.IllegalArgumentException: No serializer found for class io.ebeaninternal.server.transaction.DefaultPersistenceContext and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.ebean.common.BeanList[0]->models.Product["_ebean_intercept"]->io.ebean.bean.EntityBeanIntercept["persistenceContext"])
        at com.fasterxml.jackson.databind.ObjectMapper.valueToTree(ObjectMapper.java:3232)
        at play.libs.Json.toJson(Json.java:92)
        at controllers.ProductController.index(ProductController.java:17)
        at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$4(Routes.scala:202)
        at play.core.routing.HandlerInvokerFactory$$anon$6.resultCall(HandlerInvoker.scala:142)
        at play.core.routing.HandlerInvokerFactory$$anon$6.resultCall(HandlerInvoker.scala:141)
        at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$3$$anon$4$$anon$5.invocation(HandlerInvoker.scala:115)
        at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:119)
        at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:33)
        at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:175)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class io.ebeaninternal.server.transaction.DefaultPersistenceContext and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: io.ebean.common.BeanList[0]->models.Product["_ebean_intercept"]->io.ebean.bean.EntityBeanIntercept["persistenceContext"])
        at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
        at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1277)
        at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
        at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:71)
        at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:33)
        at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
        at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)
        at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
        at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
        at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)

I tried to use getter and setter on my Product model but still not work.