cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Hugi Thordarson <h...@karlmenn.is>
Subject Re: Cayenne and Spring?
Date Wed, 10 Jan 2018 01:11:51 GMT
Hi Fredrik.

Jackson is attempting to serialize an entire universe of java objects accessible from DataObject
(including everything returned by getObjectContext() (and then everything that comes with
that)) and obviously it doesn't know how to turn these into JSON.
You could solve this by creating custom Jackson serializers for your DataObject subclasses,
but I'd sincerely recommend just creating separate classes for modeling your web service return
types. It's easy to do and that way your JSON API design won't change with your DB design.

Cheers,
- hugi


> On 9 Jan 2018, at 20:51, Fredrik Widengren <fredrik.widengren@gmail.com> wrote:
> 
> Thanks for your help!
> 
> Below you can see my controller which is basically the Spring Boot "Hello
> World" REST example, plus my Cayenne test.
> When I access http://localhost:8080/greeting, I get the JSON result below:
> 
> {"id":1,"content":"Hello, World!"}
> 
> When I access http://localhost:8080/recipe/id=15, I'm directed to a Spring
> Boot default error page. But in the log I can see that Cayenne works fine,
> the object is fetched as it should.
> 
> *// SPRING BOOT LOG*
> 2018-01-09 21:41:04.733  INFO 6128 --- [io-8080-exec-38]
> o.a.cayenne.log.CommonsJdbcEventLogger   : Detected and installed adapter:
> org.apache.cayenne.dba.mysql.MySQLAdapter
> 2018-01-09 21:41:04.734  INFO 6128 --- [io-8080-exec-38]
> o.a.cayenne.log.CommonsJdbcEventLogger   : --- transaction started.
> 2018-01-09 21:41:04.930  INFO 6128 --- [io-8080-exec-38]
> o.a.cayenne.log.CommonsJdbcEventLogger   : SELECT `t0`.`Comment`,
> `t0`.`ID`, `t0`.`ID_privileges`, `t0`.`Instruction`, `t0`.`Name`,
> `t0`.`No_of_servings`, `t0`.`Rating`, `t0`.`Source`, `t0`.`Timestamp`,
> `t0`.`Username` FROM `foodbase`.`recipes` `t0` WHERE `t0`.`ID` = ? [bind:
> 1->ID:13]
> 2018-01-09 21:41:05.338  INFO 6128 --- [io-8080-exec-38]
> o.a.cayenne.log.CommonsJdbcEventLogger   : === returned 1 row. - took 579
> ms.
> 2018-01-09 21:41:05.339  INFO 6128 --- [io-8080-exec-38]
> o.a.cayenne.log.CommonsJdbcEventLogger   : +++ transaction committed.
> 2018-01-09 21:41:05.642  WARN 6128 --- [io-8080-exec-38]
> .w.s.m.s.DefaultHandlerExceptionResolver : Failed to write HTTP message:
> org.springframework.http.converter.HttpMessageNotWritableException: Could
> not write JSON: No serializer found for class
> org.apache.cayenne.tx.TransactionFilter and no properties discovered to
> create BeanSerializer (to avoid exception, disable
> SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is
> com.fasterxml.jackson.databind.JsonMappingException: No serializer found
> for class org.apache.cayenne.tx.TransactionFilter and no properties
> discovered to create BeanSerializer (to avoid exception, disable
> SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain:
> model.Recipes["objectContext"]->org.apache.cayenne.access.DataContext["channel"]->org.apache.cayenne.access.DataDomain["filters"]->java.util.Collections$UnmodifiableRandomAccessList[0])
> 2018-01-09 21:41:05.965 ERROR 6128 --- [io-8080-exec-38]
> o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet
> dispatcherServlet threw exception
> 
> 
> I have tested also to disable SerializationFeature.FAIL_ON_EMPTY_BEANS, as
> suggested in the exception, with no luck.
> 
> *// Class GreetingController*
> package hello;
> 
> import java.util.List;
> import java.util.concurrent.atomic.AtomicLong;
> 
> import org.apache.cayenne.ObjectContext;
> import org.apache.cayenne.configuration.server.ServerRuntime;
> import org.apache.cayenne.configuration.server.ServerRuntimeBuilder;
> import org.apache.cayenne.query.ObjectSelect;
> import org.springframework.web.bind.annotation.RequestMapping;
> import org.springframework.web.bind.annotation.RequestParam;
> import org.springframework.web.bind.annotation.RestController;
> 
> import model.Recipes;
> import model.auto._Recipes;
> 
> @RestController
> public class GreetingController {
> 
>    // Cayenne context
>    ServerRuntime cayenneRuntime =
> ServerRuntimeBuilder.builder().addConfig("cayenne-project.xml").build();
>    ObjectContext context = cayenneRuntime.newContext();
> 
>    // Hello World example variables
>    private static final String template = "Hello, %s!";
>    private final AtomicLong counter = new AtomicLong();
> 
>    @RequestMapping("/greeting")
>    public Greeting greeting(@RequestParam(value="name",
> defaultValue="World") String name) {
>        return new Greeting(counter.incrementAndGet(),
>                            String.format(template, name));
>    }
> 
>    @RequestMapping("/recipe")
>    public Recipes getRecipe(@RequestParam(value="id") int id) {
> 
>        List <Recipes> recipesList =
> ObjectSelect.query(Recipes.class).where(Recipes.ID.eq(new
> Long(id))).select(context);
> 
>        return recipesList.get(0);
> 
>    }
> }
> 
> 2018-01-09 9:00 GMT+01:00 Andrus Adamchik <andrus@objectstyle.org>:
> 
>> To clarify, I realize you are using Spring, but Spring is many things. So
>> maybe you can post here the relevant code (of a REST endpoint?), so that we
>> can advise on serialization.
>> 
>> Andrus
>> 
>> 
>>> On Jan 9, 2018, at 10:04 AM, Andrus Adamchik <andrus@objectstyle.org>
>> wrote:
>>> 
>>> What technology are you using to serialize your data to JSON? Do you
>> have a code example?
>>> 
>>> Andrus
>>> 
>>> 
>>>> On Jan 9, 2018, at 9:24 AM, Fredrik Widengren <
>> fredrik.widengren@gmail.com> wrote:
>>>> 
>>>> Hello Frank
>>>> Thanks for your mail.
>>>> They automatically included when running Spring Boot as I understand.
>> Also the ”Hello World” example is running fine, and that one returns the
>> answer in JSON.
>>>> 
>>>> /Fredrik
>>>> 
>>>> Skickat från min iPhone
>>>> 
>>>>> 8 jan. 2018 kl. 23:07 skrev Frank Herrmann <frank.herrmann@
>> modernizingmedicine.com>:
>>>>> 
>>>>> Do you have the Jackson libraries included in your project? They are
>>>>> normally needed for JSON serialization/deserialization.
>>>>> 
>>>>> On Mon, Jan 8, 2018 at 4:52 PM, Fredrik Widengren <
>>>>> fredrik.widengren@gmail.com> wrote:
>>>>> 
>>>>>> Hello,
>>>>>> 
>>>>>> I'm testing to setup Cayenne with Spring Boot. I have created a simple
>>>>>> REST service. Spring is working fine with a Hello World example from
>>>>>> Spring.io.
>>>>>> 
>>>>>> When I try to send back my cayenne objects that I have generated
from
>>>>>> the Cayenne modeller, I get an exception that it can’t find a JSON
>>>>>> serializer.
>>>>>> 
>>>>>> Error:
>>>>>> Could not write JSON: No serializer found for class
>>>>>> org.apache.cayenne.tx.TransactionFilter
>>>>>> 
>>>>>> I have read that a common reason for this is that the class that
you
>>>>>> try to serialize does not have any public getters/setters. The
>>>>>> generated classes (in the auto package) from the modeller that extends
>>>>>> CayenneDataObject do have these public getters/setters. The class
is
>>>>>> however abstract, but I'm using the class created by the modeller
that
>>>>>> extends the abstract modeller class.
>>>>>> 
>>>>>> Anyone that have any experience from Cayenne and Spring that have
some
>>>>>> input?
>>>>>> 
>>>>>> Many thanks!
>>>>>> 
>>>>>> /Fredrik
>>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> FRANK HERRMANN
>>>>> SENIOR SOFTWARE ENGINEER
>>>>> 
>>>>> T: 561-880-2998 x1563
>>>>> 
>>>>> E: frank.herrmann@modmed.com
>>>>> 
>>>>> 
>>>>> 
>>>>> [image: [ Modernizing Medicine ]] <https://www.modmed.com/>
>>>>> [image: [ Facebook ]] <https://www.facebook.com/modernizingmedicine>
>> [image:
>>>>> [ LinkedIn ]] <https://www.linkedin.com/company/modernizing-medicine/>
>> [image:
>>>>> [ YouTube ]] <https://www.youtube.com/user/modernizingmedicine>
>> [image: [
>>>>> Twitter ]] <https://twitter.com/modmed> [image: [ Blog ]]
>>>>> <https://www.modmed.com/BlogBeyondEMR> [image: [ Instagram ]]
>>>>> <https://instagram.com/modernizing_medicine>
>>>>> 
>>>>> [image: [ MOMENTUM 2017 ]] <https://www.eventproducers.
>> events/momentum2017/>
>>> 
>> 
>> 


Mime
View raw message