0

I am using Spring boot 1.0.1.RELEASE and am trying to get it to pick up some Jackson annotations. More specifically, I am trying to use @JsonManagedReference and @JsonBackReference annotations. Any idea why this might get ignored? I also tried @JsonIgnore but that also did not seem to get picked up.

I already tried the 2 things mentioned in this SO question (Moving the Jackson annotionations to be first and using a List instead of a Set). I also looked at this question on the Spring forums, but that does not help me either.

UPDATE:

This is my ComponentType class:

@Entity
public class ComponentType
{
// ------------------------------ FIELDS ------------------------------

    @Id
    @GeneratedValue()
    private long m_id;

    private String m_name;

    @JsonManagedReference
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id")
    private List<ComponentSubtype> m_subtypes;

// --------------------------- CONSTRUCTORS ---------------------------

    public ComponentType()
    {
    }

    public ComponentType( String name, Iterable<ComponentSubtype> subtypes )
    {
        m_name = name;
        m_subtypes = Lists.newArrayList(subtypes);
    }

    // -------------------------- PUBLIC METHODS --------------------------

    public long getId()
    {
        return m_id;
    }

    public void setId( long id )
    {
        m_id = id;
    }

    public String getName()
    {
        return m_name;
    }

    public void setName( String name )
    {
        m_name = name;
    }

    public List<ComponentSubtype> getSubtypes()
    {
        return m_subtypes;
    }

    public void setSubtypes( List<ComponentSubtype> subtypes )
    {
        m_subtypes = subtypes;
    }

    public ComponentSubtype getSubtype( final long subtypeId )
    {
        return Iterables.find( getSubtypes(), new Predicate<ComponentSubtype>()
        {
            @Override
            public boolean apply( ComponentSubtype input )
            {
                return input.getId() == subtypeId;
            }
        } );
    }

And this is ComponentSubtype:

@Entity
public class ComponentSubtype
{
    @Id
    @GeneratedValue()
    private long m_id;

    private String m_name;

    @JsonBackReference
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id",insertable=false,updatable=false)
    private ComponentType m_componentType;

    public ComponentSubtype()
    {
    }

    public ComponentSubtype( String name )
    {
        m_name = name;
    }

    public long getId()
    {
        return m_id;
    }

    public void setId( long id )
    {
        m_id = id;
    }

    public String getName()
    {
        return m_name;
    }

    public void setName( String name )
    {
        m_name = name;
    }

    public ComponentType getComponentType()
    {
        return m_componentType;
    }

    public void setComponentType( ComponentType componentType )
    {
        m_componentType = componentType;
    }
}

The controller:

@RestController
@RequestMapping("/api/components")
public class ComponentTypeController
{
    @Autowired
    private ComponentTypeRepository m_repository;

    @RequestMapping("/list")
    public Iterable<ComponentType> listComponents()
    {
        return m_repository.findAll();
    }
}

And the repository:

public interface ComponentTypeRepository extends CrudRepository<ComponentType, Long>
{
}

In my main I create some entities for testing:

    ConfigurableApplicationContext context = SpringApplication.run( Main.class, args );
ComponentTypeRepository componentTypeRepository = context.getBean( ComponentTypeRepository.class );
componentTypeRepository.save( new ComponentType( "Component A", Sets.newHashSet( new ComponentSubtype( "Sub A - 1" ), new ComponentSubtype( "Sub A - 2" ) ) ) );
componentTypeRepository.save( new ComponentType( "Component B", Sets.newHashSet( new ComponentSubtype( "Sub B - 1" ), new ComponentSubtype( "Sub B - 2" ) ) ) );
componentTypeRepository.save( new ComponentType( "Component C", Sets.newHashSet( new ComponentSubtype( "Sub C - 1" ), new ComponentSubtype( "Sub C - 2" ) ) ) );
componentTypeRepository.save( new ComponentType( "Component D", Sets.newHashSet( new ComponentSubtype( "Sub D - 1" ),
                                                                                 new ComponentSubtype( "Sub D - 2" ),
                                                                                 new ComponentSubtype( "Sub D - 3" )
) ) );

If I point my browser to http://localhost:8080/api/components/list, then I get a stackoverflow exception.

This is part of the stacktrace I get:

java.lang.StackOverflowError: null
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:660)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)
    at com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:541)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:644)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:117)
    at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23)

EXAMPLE PROJECT that demonstrates the problem:

Download from https://dl.dropboxusercontent.com/u/6373261/jackson-problem.zip

Community
  • 1
  • 1
Wim Deblauwe
  • 25,113
  • 20
  • 133
  • 211
  • What version of Jackson are you using? Make sure it is the one supported by Spring Boot (e.g. by using the starter poms as dependencies - Jackson is included in the web starter). – Dave Syer Apr 14 '14 at 23:41
  • I am using `spring-boot-starter-web` dependency and this seems to give me Jackson 2.3.2 – Wim Deblauwe Apr 15 '14 at 06:23
  • OK, then it should work. What is it you are trying to do more precisely? Maybe put some code in the question? – Dave Syer Apr 15 '14 at 11:10
  • I have added my code. Thank you for having a look. Is there any way that I can enable more debugging from Jackson? – Wim Deblauwe Apr 15 '14 at 12:17
  • Thanks, that helps. So what comes out of your endpoints? If it's JSON I guess Jackson is working, but your field-level annotations are not? Mayeb you could put a short section of the cycle from the exception in the question as well? – Dave Syer Apr 15 '14 at 12:42
  • Added the stacktrace. I can confirm that none of the field-level annotations work. If I add a `@JsonProperty("foo")` on a field, then the JSON will still print the field name instead of the `foo` in the JSON. I am using Java 7 if that would matter. – Wim Deblauwe Apr 15 '14 at 12:48
  • Any chance they are the wrong annotations (maybe you have Jackson 1.9 on your classpath by mistake as well)? – Dave Syer Apr 15 '14 at 12:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/50697/discussion-between-dave-syer-and-wim-deblauwe) – Dave Syer Apr 15 '14 at 12:51

1 Answers1

1

It's your (old-fashioned IMO) naming convention for fields ("m_*"). Jackson doesn't correlate them with the getters and setters. So you have to either @JsonIgnore the getters and setters, or change your naming, or annotate the getters. Or maybe there is a feature in @JsonBackReference(...)? @JsonBackReference("componentType") for instance, might work.

Dave Syer
  • 56,583
  • 10
  • 155
  • 143