spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
916 stars 562 forks source link

@JsonIgnore not honored when applied to a relationship [DATAREST-87] #471

Open spring-projects-issues opened 11 years ago

spring-projects-issues commented 11 years ago

Marco Fago opened DATAREST-87 and commented

Consider two entities ClientEntity and AbonnementEntity as follows:


@Entity
public class ClientEntity {
....
   @JSonIgnore
   @OneToMany(targetEntity = AbonnementEntity.class, mappedBy = "client", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   private Set<Abonnement> abonnements;
....
}

and


@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
public abstract class AbonnementEntity<> implements Serializable {
....
    @NotNull
    @ManyToOne(targetEntity = ClientEntity.class, optional = false)
    private ClientEntity client;
....
}

When issuing the request http://localhost/client the @JsonIgnore is not honored and all the related abonnement entities are returned into the response under the content section


Affects: 1.1.0.M1

11 votes, 13 watchers

spring-projects-issues commented 11 years ago

Jon Brisbin commented

Have you tried @RestResource(exported = false) rather than @JsonIgnore?

spring-projects-issues commented 11 years ago

Marco Fago commented

Using @RestResource(exported = false) does not help and produces an infinite recursive output (since, I think, ClientEntity and AbonnementEntity are double linked each other) which ends with a StackOverflowException.

spring-projects-issues commented 11 years ago

Ashish Jamthe commented

I have exactly this issue. @RestResource(exported = false) will work only if the entity is directly managed by repository. I want to customize my json to include child nodes (to avoid multiple REST requests for a given view). This is proving more difficult that I thought. As neither the export=false works nor jackson annotations hold. Please let me know if this can be fixed.

spring-projects-issues commented 10 years ago

Nick Weedon commented

I think the @JsonIgnore side of this issue is closely realted to DATAREST-117 which i have now written a fix for (https://github.com/spring-projects/spring-data-rest/pull/133)

spring-projects-issues commented 10 years ago

Oliver Drotbohm commented

This should be fixed by the fixes for DATAREST-117 and DATAREST-248

spring-projects-issues commented 10 years ago

Heiko Wolf commented

This is not fixed. Here is my test case:

@Entity
public class TestEntity {

    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;

    private String name;

    @JsonIgnore /* This works for fields */
    private String name2;

    @ManyToOne(optional = true)
    @JsonIgnore
    private TestEntity parent;

    public TestEntity getParent() {
        return parent;
    }

    public String getName() {
        return name;
    }

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

    public String getName2() {
        return name2;
    }

    public void setName2(String name2) {
        this.name2 = name2;
    }
}
@RepositoryRestResource(exported = true, path = "test")
public interface TestEntityRepository extends PagingAndSortingRepository<TestEntity, Long> {
}
{
  "name" : "Test 3",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/webui/rest/test/3"
    },
    "parent" : {
      "href" : "http://localhost:8080/webui/rest/test/3/parent"
    }
  }
}
{
  "name" : "Test 3",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/webui/rest/test/3"
    }
  }
}
public class RestApiInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    protected String getServletName() {
        return "dispatcher-rest";
    }

    protected String[] getServletMappings() {
        return new String[] { "/rest/*" };
    }

    protected Class[] getServletConfigClasses() {
        return new Class<?>[] { RestConfig.class };
    }

    protected Class[] getRootConfigClasses() {
        return new Class<?>[] {};
    }

    @Configuration
    @EnableWebMvc
    @ComponentScan({ "rest.test" })
    public static class RestConfig extends RepositoryRestMvcConfiguration {
    }
}

Tested with Spring Data Rest 2.1.0.RELEASE, Spring Data JPA 1.8.0.RELEASE, Spring 4.0.5.RELEASE.

spring-projects-issues commented 9 years ago

Willie Wheeler commented

Still true for 2.3.0 Fowler.

@JsonIgnore works on the simple properties (strings, booleans, whatever) but not on associations.

Is this the intended behavior? I guess there's a subtle difference between what's logically included in the REST representation (which we can control via @RestResource(exported)) and what's included during actual serialization (which @JsonIgnore handles). The association links remain because the links aren't the properties being suppressed. If this is the concept/logic then it would be good to explain that in the docs.

spring-projects-issues commented 9 years ago

Oliver Drotbohm commented

I just gave this a quick spin and would like to keep this as is (i.e. @JsonIgnore to be used for simple properties and @RestResource for associations).

The preparation process is currently a two step one. The first one is turning an arbitrary entity into a resource which adds links for associations. This step doesn't know anything about Jackson (as it basically just operates on the entity metadata). The second step is taken in the Jackson serializer that basically prevents the properties from being rendered in the representation. At this point however the links have already been created and we can't necessarily reliably find the link associated with the property (as ResourceProcessors might have modified them already).

WDYT?

spring-projects-issues commented 9 years ago

Willie Wheeler commented

+1 Oliver

As I noted in the comment, it would be good to explain this in the docs

spring-projects-issues commented 8 years ago

KJ commented

Looks like this is still the case in 2.4.4.RELEASE (version defined with spring boot version 1.3.3.RELEASE)

spring-projects-issues commented 3 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.