POST Spring Data REST does not work with relationships

Asked

Viewed 435 times

4

I’m with a project using Spring Boot and Spring Data Rest to serve a Rest API.

When I’m serving an entity without relationships, it works smoothly.

The problem is when I use an entity with relationships. I cannot add new entities via POST. I tested with my Angularjs application and with Google Chrome extensions like Yet Another REST Client but the POST does not add the entity correctly. It edits an existing record causing confusion.

Follows the code:

@Entity
public class City {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private boolean capital;

    @ManyToOne(targetEntity=State.class, fetch = FetchType.EAGER)
    @JoinColumn(name = "state_id")
    private State state;
    // getters e setters omitidos
}

@RepositoryRestResource(excerptProjection = CityProjection.class)
public interface Cities extends PagingAndSortingRepository<City, Long>{

}

If necessary put more parts of the code. Still I don’t know what I did wrong or didn’t do to make it work properly.

All queries work correctly.


I did the following test, I sent a Request as POST with the following content:

{
    "name": "Aparecida de Goiânia",
    "capital": false,
    "state": {
        "id": "1",
        "name": "Goiás",
        "initials": "GO"
    }
}

And I received as return and what appears in the database:

{
  "id": 1,
  "name": "Goiás",
  "capital": false,
  "_links": {
    "self": {
       "href": "http://localhost:8080/rest/cities/1"
     },
    "city": {
      "href": "http://localhost:8080/rest/cities/1{?projection}",
      "templated": true
    },
    "state": {
      "href": "http://localhost:8080/rest/cities/1/state"
    }
  }
}

The same happens if I add "id": null in the city.

  • What is the error and how the message is being sent to the service?

  • No error is shown. But data is not entered.

  • 1

    Um, weird. Usually in these cases it is written log - according to the configured log level - that there is no mapped resource, that the received message is out of pattern, etc. Anyway, it puts at least the message you are testing, as said that you are editing an existing record, may be the message that is wrong (with id filled, for example).

  • I changed the question with the requested return. In the log, nothing else appears. Only the Tomcat startup log (which is normal).

  • 1

    Dear, when you send in POST state_id instead of state and value 1, what happens? If you send the post without state records? What happens if you switch to Lazy? Have you run these tests? In the State class, the attributes are actually id, name and initials? In addition has access methods?

  • If I pass the field state_id or not pass, records, but the field state_idtable is null. json also searches "state": null. I did not test with Lazy because it is only the queries. And yes, entities have all public access methods (getters and setters).

  • I also tested without Eager, the lack of it did not disturb the consultations and that is good, but still does not work the POST. also tested with unique field names with the @Column without success. I appreciate the help.

  • I had a similar problem and used @Manytoone(Scade = Cascadetype.REFRESH) to avoid these "Updates". Put it there and see where it goes.

  • I ran the tests with CascadeType.REFRESH, but without success. Thanks for the help.

Show 4 more comments

1 answer

1


First you should do the post in State and then in City sending in state the corresponding address. (I couldn’t find any way to send the state as a child object)

Example:

POST http://localhost:8080/states
{ 
  "id": "1",
  "name": "Goiás",
  "initials": "GO"
}

POST http://localhost:8080/cities
{
  "name": "Aparecida de Goiânia",
  "capital": false,
  "state": "http://localhost:8080/states/1"
}

POST http://localhost:8080/cities
{
  "name": "Aparecida de Goiânia 2",
  "capital": false,
  "state": "http://localhost:8080/states/1"
}

Answer when calling GET http://localhost:8080/Cities

{
  "_embedded" : {
    "cities" : [ {
      "name" : "Aparecida de Goiânia",
      "id" : 1,
      "state" : {
        "name" : "Goiás",
        "initials" : "GO"
      },
      "capital" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/cities/1"
        },
        "city" : {
          "href" : "http://localhost:8080/cities/1{?projection}",
          "templated" : true
        },
        "state" : {
          "href" : "http://localhost:8080/cities/1/state"
        }
      }
    }, {
      "name" : "Aparecida de Goiânia 2",
      "id" : 2,
      "state" : {
        "name" : "Goiás",
        "initials" : "GO"
      },
      "capital" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/cities/2"
        },
        "city" : {
          "href" : "http://localhost:8080/cities/2{?projection}",
          "templated" : true
        },
        "state" : {
          "href" : "http://localhost:8080/cities/2/state"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/cities"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile/cities"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 2,
    "totalPages" : 1,
    "number" : 0
  }
}
  • Sorry it took me so long to reply. Do you tell me to send the link in the post instead of the object itself? I will run the tests here on this.

  • 1

    that’s right, my tests worked and it was the only way I could

  • 1

    I did the tests here and it worked perfectly! Thank you very much! Just do not need the POST in States before because I already have the registration of States (States) ready.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.