kfh
kfh

Reputation: 1

One to Many Json Reponse With Jackson is not Working

I have a problem using JPA and RelationsShips One to Many with Jackson and Spring Rest ... I try to find multiples solutions but anything is working for me , and I don't kno where is the problem.

For example I have a table Team that has One to Many/Many To One relationship

I have two repository one for Team and another for Player

Team  >>> has Many >> Player
Player >>> many to one >> Team

My entity Team has the following content

@Entity
@Table(name = "teams")
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Team {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private long teamId;

    private String abbreviation;

    private String team;

    private String simpleName;

    private String logo;

    @OneToMany(cascade = {CascadeType.ALL,CascadeType.PERSIST,CascadeType.MERGE}, mappedBy = "team")
    @Column(nullable = false)
    private List<Player> players;

    Theirs getters/setter , hashcodes and string similars.

On the other hand the entity Player

    @Entity
@Table(name = "player")
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
public class Player {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "teams_id", nullable=true)
    private Team team;

    private String name;

So , I have the typical get call in a controller in a repository.

@RestController
@RequestMapping("/api/public/team")
public class TeamController {

    @Autowired
    private TeamRepository teamRepository;

    @Autowired
    private GenericMethods genericMethods;

    @GetMapping(value = "/{id}")
    public Team getPersona(@PathVariable("id") int id) {
        return teamRepository.findOne(genericMethods.toLong(id));
    }

And repository

@Repository
public interface TeamRepository extends JpaRepository<Team, Long> {

}

Now , when I call this endpoint I receive the following answer and I think that is incorrect , I only need a List With Players

{  
   "id":2,
   "teamId":0,
   "abbreviation":null,
   "team":null,
   "simpleName":"Betis",
   "logo":null,
   "players":[  
      {  
         "id":1,
         "team":2,
         "category":{  
            "id":1,
            "nombre":"juvenil a",
            "language":null,
            "description":null,
            "league":[  

            ],
            "players":[  
               1,
               {  
                  "id":2,
                  "team":2,
                  "category":1,
                  "name":"hulio"
               }
            ]
         },
         "name":"pepe"
      },
      2
   ]
}

I need to acces at information with Player and Team so I can't use @JsonIgnoreProperties

Could anyone help to solve this problem ?

Upvotes: 0

Views: 518

Answers (1)

Michal
Michal

Reputation: 2273

Depending on what you really want to achieve you may try different options. I'm not sure if you're using (or intending to use) spring-data-rest or not.

1. Dedicated repository

Spring data rest will embed the related entities if they don't have their own repository. Try creating public interface PlayersRepository extends JpaRepository...

2. Lazy loading

Why are you using FetchType.EAGER ? Try without it.

3. Projections

Projections are only applicable to lists, not to individual entities (i.e. not explicitly what you're asking for). You can hide players from the Teams collection even if it was returned by default like so:

@Projection(name = "noPlayers", types = { Team.class })
public interface TeamWithoutPlayers {

    Long getId();
    long getTeamId();
    String getAbbreviation();
    String getTeam();
    String getSimpleName();
    String getLogo();
}

More info - Spring Data Rest Projections

4. Ignore during serialization in Team Entity using @JsonIgnore

@JsonIgnore
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "teams_id", nullable=true)
private Team team;

Final thought

With spring-data-rest you can extend a CrudRepository instead of JpaRepository and access the item directly through the repository. That way you don't need to write a controller.

Upvotes: 1

Related Questions