📜 ⬆️ ⬇️

Spring Boot solving a problem with ManyToMany



The article is addressed to you, wandering in the darkness of the night. You, whose path is illuminated only lonely fireflies. In general, a programmer who studies Spring Boot and ManyToMany's relationship to Hibernate.

He did a test task on an abstract musical theme: write a service for storing data about musicians, songs, albums using Java, Spring, Hibernate. Part of the task was the creation of the classes “Compositions” and “Artists”. The composition can be performed by many performers, and the performer can perform many compositions. Typical bidirectional relationship ManyToMany.
')
The Khasang courses told you how to avoid looping rest requests to Spring using the DTO class, but Spring Boot is another story. On Russian-language websites I saw answers like “Yes, this is all elementary,” but without specific explanations. I will give an example of solving this problem. The full code is posted on the githab, link below.

First create the Entity: People and SongPlayers. Getters and setters omitted for short.

@Entity public class People { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String human; //      @ManyToOne(cascade = CascadeType.ALL) private RockGroups rockGroups; //     @ManyToMany(mappedBy = "songInstrumentalist",fetch = FetchType.EAGER) private List<SongPlayers> songItems; public People(){} public People(long id, String human){ this.id = id; this.human = human; } //. . . . . . . . . } 

 @Entity public class SongPlayers { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String song; //    private String composer; //     private String poet; //    private String album; //   //     @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private List<People> songInstrumentalist; //. . . . . . . . . } 

Then we create Repository interfaces for the People class.

 @Repository public interface PeopleRepository extends JpaRepository<People, Long> { @Query("select h from People h where h.human=?1") List<People> searchByHuman(String human); List<People> findPeopleByHuman(String human); } 

And for the SongPlayers class

 @Repository public interface SongPlayersRepository extends JpaRepository<SongPlayers, Long> { List<SongPlayers> findSongPlayersBySong(String song); List<SongPlayers> findSongPlayersByComposer(String composer); List<SongPlayers> findSongPlayersByPoet(String poet); } 

The Repository annotation extends the Component annotation, which allows the implemented class to make bean and autowiring, respectively.

Extending the JpaRepository interface allows you to perform the necessary CRUD operations without additional description and other useful things.

Now you need to create DTO classes for Entity People and SongPlayers. Here I will give only PeopleDTO so as not to clutter the article. Getters and setters dropped again.

 public class PeopleDTO { private long id; private String human; private RockGroups rockGroups; private List<SongPlayersDTO> songPlayersList; public List<PeopleDTO> getPeopleDTOList(List<People> peopleList){ List<PeopleDTO> peopleDTOList = new ArrayList<>(); for (People people : peopleList){ songPlayersList = new ArrayList<>(); PeopleDTO peopleDTO = new PeopleDTO(); peopleDTO.setId(people.getId()); peopleDTO.setHuman(people.getHuman()); peopleDTO.setRockGroups(people.getRockGroups()); for (SongPlayers songPlayers : people.getSongItems()){ SongPlayersDTO songPlayersDTO = new SongPlayersDTO(); songPlayersDTO.setId(songPlayers.getId()); songPlayersDTO.setSong(songPlayers.getSong()); songPlayersDTO.setPoet(songPlayers.getPoet()); songPlayersDTO.setComposer(songPlayers.getComposer()); songPlayersDTO.setAlbum(songPlayers.getAlbum()); songPlayersList.add(songPlayersDTO); } peopleDTO.setSongPlayersList(songPlayersList); peopleDTOList.add(peopleDTO); } return peopleDTOList; } //. . . . . . . . . } 

By analogy, the SongPlayersDTO class is also created. Select the required fields for display in the rest - answer.

Create a controller for the people. Attention, watch your hands!

 @RestController @RequestMapping("/people") public class PeopleController { @Autowired private PeopleRepository repository; @GetMapping("/all") public List<PeopleDTO> getAllPeople(){ PeopleDTO peopleDTO = new PeopleDTO(); return peopleDTO.getPeopleDTOList(repository.findAll()); } //. . . . . . . } 

Yeah, you say. This will not work. And where is the implementation of the PeopleRepository interface?
Will work, the PeopleRepository class is created on the fly! Just fantastic.

Now compare the number of generated classes and interfaces for an identical project on Spring and Spring Boot
classes in the Spring projectclasses in Spring Boot

I wish you all successful programming. Waiting for your comments.


Used Books:

Source: https://habr.com/ru/post/432318/


All Articles