I'am using Play Framework to build a simple Product API with ORM EBean
This is my specification:
- Java 1.8
- Eclipse 2020-06
- Play 2.8.13
- Scala 2.13.6
- Ebean 5.2.4
I followed the code from several sources:
- https://github.com/siddharths067/ebeancrud
- 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.