Home > Software engineering >  SpringBoot JPA ManyToMany leftOuter join query and mapping
SpringBoot JPA ManyToMany leftOuter join query and mapping

Time:08-03

I have manyToMany relationship between Newsfeed and User in order to store favorite Newsfeeds of Uesrs.

Newsfeed

id title description
1 Test Title Here is description
2 Title 2 Here is another description

Favorite_Newsfeed (ManyToMany Relationship)

newsfeed_id user_id
1 1
2 2
1 2

Now I need to retrieve all the newsfeeds along with favorites filtered by user.

NewsfeedWithFavorite (Goal)

id title description isFavorite
1 Test Title Here is description 1
2 Title 2 Here is another description

I can do this by using case when in raw query but What is the best approach to retrieve data in this format using JPA? (I am new in JPA)

CodePudding user response:

You have to use join in JPQL and then map favorites.

Repository :

public interface NewsFeedJpaRepository extends JpaRepository<NewsFeed, Long> {
    @Query("SELECT nf , fnf.user.id FROM NewsFeed nf LEFT JOIN FavoriteNewsFeed fnf ON fnf.newsfeed = nf and fnf.user.id = :userId ")
    Page<Object[]> findAllWithFavorite(Long userId, Pageable pageable);
}

create a dto like following:

public class NewsFeedWithFavorite extends NewsFeed {

    private Boolean isFavorite;

    public NewsFeedWithFavorite(){};
    public NewsFeedWithFavorite(NewsFeed newsFeed, Long userID){
        setId(newsFeed.getId());
        setTitle(newsFeed.getTitle());
        setDescription(newsFeed.getDescription());
        if(userID !=null)
            setFavorite( Boolean.TRUE);
        else
            setFavorite(Boolean.FALSE);
    };

    public Boolean getFavorite() {
        return isFavorite;
    }

    public void setFavorite(Boolean favorite) {
        isFavorite = favorite;
    }
}

And finally in the Service :

public Page<NewsFeedWithFavorite> findAllWithFavorite(Long userId, Pageable pageable) {
    Page<Object[]> result = newsFeedJpaRepository.findAllWithFavorite(userId,pageable);
    return result.map(objArr -> new NewsFeedWithFavorite((NewsFeed) objArr[0], (Long) objArr[1]));
}

CodePudding user response:

Do not use @ManyToMany annotation.

It will be extremely hard for you to add multiple columns and in general work with the auto generated Favorite_Newsfeed table.

The best way to handle this scenarior is to use a different table for User's news feed.

Check out the following structure.

public class User {
    @OneToMany
    private List<UserNewsFeed> newsFeeds;

}
public class NewsFeed {
    public String description;
    public String title;
}
public class UserNewsFeed {
    @ManyToOne
    private User user;
    @ManyToOne
    private NewsFeed newsFeed;
    private boolean isFavorite;
}
  • Related