Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot Data Rest POST returns 204 but only SELECTS

So this was working before I switched to Boot. Basically I was able to POST a text/uri-list to a @OneToMany resource just fine. I switched my project to use Boot and somewhere in the process it stopped working. I can PUT a text/uri-list at the @ManyToOne end, but that's not what I want to do.

When I submit the POST, I get a 204 response, but I can see the SQL on my console only Selecting and not inserting anything. EDIT: I use Postman, but here's a curl command that does/returns the same

curl -v -X POST -H "Content-Type: text/uri-list" -d "http://localhost:8080/games/2" http://localhost:8080/developers/1/gameList

And the logger on IDEA:

Hibernate: select developer0_.developer_id as develope1_1_0_, developer0_.name as name2_1_0_ from developer developer0_ where developer0_.developer_id=?
Hibernate: select game0_.game_id as game_id1_6_0_, game0_.developer_id as develope5_6_0_, game0_.esrb_rating as esrb_rat2_6_0_, game0_.name as name3_6_0_, game0_.release_date as release_4_6_0_, developer1_.developer_id as develope1_1_1_, developer1_.name as name2_1_1_ from game game0_ left outer join developer developer1_ on game0_.developer_id=developer1_.developer_id where game0_.game_id=?

Here are my relevant classes:

@Entity
public class Developer {
    @Id
    @GeneratedValue
    @Column(name = "developerId")
    private Long id;

    private String name;

    @OneToMany(mappedBy = "developer", cascade = CascadeType.ALL)
    private List<Game> gameList;

Other one:

@Entity
public class Game {
    @Id
    @GeneratedValue
    @Column(name = "gameId")
    private Long id;

    private String name;

    private Date releaseDate;

    private ESRBRating esrbRating;

    @ManyToMany(mappedBy = "gameList", cascade = CascadeType.ALL)
    private List<User> userList;

    @ManyToOne
    @JoinColumn(name = "developerId")
    private Developer developer;

If I'm missing any other relevant info let me know and I'll provide it.

like image 300
jam01 Avatar asked Mar 10 '16 08:03

jam01


People also ask

What does the @RepositoryRestResource annotation do?

The @RepositoryRestResource annotation is optional and is used to customize the REST endpoint. If we decided to omit it, Spring would automatically create an endpoint at “/websiteUsers” instead of “/users“. That's it! We now have a fully-functional REST API.

Why is Spring Data rest not recommended in real world applications?

Real-world applications should avoid using Spring Data REST because the entities are exposed as RESTful Services. The two most critical considerations in designing a RESTful service are the domain model and the consumers.

What is @RepositoryRestController?

Annotation Type RepositoryRestControllerAnnotation to demarcate Spring MVC controllers provided by Spring Data REST. Allows to easily detect them and exclude them from standard Spring MVC handling.

What is collectionResourceRel?

and collectionResourceRel is described: The rel value to use when generating links to the collection resource.


2 Answers

If you want to keep it bi-directional you seem to have 2 options :

  • Remove the mappedBy = "developer" and let JPA use a jointable to manage the one-to-many relationship.

Developer:

@OneToMany(cascade = CascadeType.ALL)
@JoinTable(
        name="DeveloperGame",
        joinColumns = @JoinColumn( name="dev_id"),
        inverseJoinColumns = @JoinColumn( name="game_id")
)
private List<Game> gameList;

Game:

@ManyToOne
@JoinTable(
        name="DeveloperGame",
        joinColumns = @JoinColumn( name="game_id"),
        inverseJoinColumns = @JoinColumn( name="dev_id")
)
private Developer developer;
  • Remove the mappedBy = "developer" and add a @JoinColumn if you don't want to use a jointable (make you have a joincolumn on both sides of the relationship with the same column name

Developer:

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "devId")
private List<Game> gameList;

Game:

@ManyToOne
@JoinColumn(name = "devId")
private Developer developer;

I do wonder if this is by design or if this is a bug in Spring Data REST.

like image 131
ddewaele Avatar answered Oct 15 '22 20:10

ddewaele


Hibernate collects insert, updates and deletes until the entitymanager is flushed. This is normally done at the end of a transaction. So it could be that your transaction management does not work correctly.

Set the logging for org.springframework.transaction to debug, than you should see when transactions are opened and closed.

like image 36
Stefan Isele - prefabware.com Avatar answered Oct 15 '22 22:10

Stefan Isele - prefabware.com