0

I am working on my senior project and my group's client has required that we use Spring Boot, which none of us are familiar with. Right now I'm working on making a paginated, sortable list that will show a logged in user the visits that are associated with their user id. Our models are as follows:

@Entity
@Table(name="users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonView(View.User.class)
    private long id;

    @Column(name = "full_name")
    @NotNull
    @JsonView(View.User.class)
    private String fullName;

    @Column(name = "is_manager")
    @NotNull
    private boolean isManager;

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "users")
    private Set<Visit> visits;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="user")
    private Set<VisitEntry> visitEntries;

-

@Entity
@Table(name="visits")
public class Visit implements Iterable<VisitEntry> {
    static final public String INSPECTION_TYPE_FULL = "Full Inspection";

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonView(View.Visit.class)
    private long id;

    @Column(name = "visit_number")
    @NotNull
    @JsonView(View.Visit.class)
    private int visitNumber;

    @ManyToOne(cascade=CascadeType.ALL)
    @NotNull
    @JsonView(View.Visit.class)
    private Provider provider;

    @ManyToOne(cascade=CascadeType.ALL)
    private User leader;

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name="users_visits",
            joinColumns={@JoinColumn(name="VISIT_ID")},
            inverseJoinColumns = @JoinColumn(name = "USER_ID")
    )
    private Set<User> users;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="visit")
    @JsonView(View.Visit.class)
    @JsonManagedReference
    private List<VisitEntry> visitEntries = new ArrayList<>();

    @Column(name = "open")
    @NotNull
    private boolean open;

-

@Entity
@Table(name="visit_entries")
public class VisitEntry {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonView(View.Visit.class)
    private long id;

    @Column(name = "pre_inspection")
    @JsonView(View.Visit.class)
    private int preInspectionPrepHours;

    @ManyToOne(cascade = CascadeType.ALL)
    @NotNull
    @JsonBackReference
    private Visit visit;

    @ManyToOne(cascade=CascadeType.ALL)
    @NotNull
    @JsonView(View.Visit.class)
    private User user;

So we have visits which have many visit entries and each visit entry has a user. What I need is to get all visits associated with a user.

Unfortunately after each reading various tutorials my teammates and I are incredibly confused and have entirely different ideas on how to do this, none of which have actually worked. Based on this question (Joining two table entities in Spring Data JPA) I created the relationship between visits and users thinking that I would then be able to use Page<Visit> findByUsers(User user, Pageable pageable); in my repository, but I always get an empty set. So now we've ended up with this ugly piece of code that works as far as paginating but does not do any sorting:

@RequestMapping(value="/visits/{pageNum}/{sort}/{direction}", method= RequestMethod.GET)
public String visits(@PathVariable int pageNum,
                     @PathVariable String sort,
                     @PathVariable String direction,
                     Model model,
                     HttpServletRequest request) {
    User currentUser = getUser(request);

    final int pageSize = 10;
    Pageable pageable;

    //get direction info from parameters and convert to Sort.Direction enum
    if (direction.compareTo("asc") == 0)
        pageable = new PageRequest(pageNum - 1, pageSize, Sort.Direction.ASC, sort);
    else
        pageable = new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, sort);

    //get pageable list of visits dependant on current user
    Page<Visit> visits;

    if(currentUser.isManager()) {
        visits = visitRepo.findAll(pageable);
    }
    else {
        //visits = visitRepo.findByUser_Id(currentUser, pageable);
        List<VisitEntry> entries = visitEntryDao.findByUser(currentUser);
        List<Visit> visitList = new ArrayList<>();
        for (int x = 0; x < entries.size(); x++) {
            visitList.add(entries.get(x).getVisit());
        }

        int offset = (pageNum - 1) * pageSize;
        int offsetEnd = offset + 10;
        if (offsetEnd > visitList.size())
            offsetEnd = visitList.size();

        List<Visit> content = visitList.subList(offset, offsetEnd);
        visits = new PageImpl<Visit>(content, pageable, visitList.size());
    }

    edu.ewu.timetrackers.util.Page[] pages = new edu.ewu.timetrackers.util.Page[visits.getTotalPages()];

    for (int i = 0; i < visits.getTotalPages(); i++) {
        pages[i] = new edu.ewu.timetrackers.util.Page(i + 1, pageNum == i + 1);
    }

    //add visit and number of pages to model
    model.addAttribute("visits", visits);
    model.addAttribute("pageCount", visits.getTotalPages());
    //add sorting and paging info to model
    model.addAttribute("pageNum", pageNum);
    model.addAttribute("sort", sort);
    model.addAttribute("direction", direction);
    model.addAttribute("pages", pages);

    //below attributes determine previous and next buttons for pagination
    if (pageNum > 1)
        model.addAttribute("notFirst", pageNum - 1);
    if (pageNum < visits.getTotalPages())
        model.addAttribute("notLast", pageNum + 1);

    return "visits";
}

Can anyone clear up the correct way to do this? We've tried asking around and not found anyone in our community that uses Spring that can help us understand what we're missing here.

Thanks!

Community
  • 1
  • 1
  • What about showing the code that does not work and what you expect the outcome to be. – Alan Hay May 13 '16 at 08:00
  • The code I posted in the question is the code that doesn't work. What I am expecting is a Page object with just visits that fit the criteria (associated with current user). On the manager page, which shows all visits, I use `visits = visitRepo.findAll(pageable);` and that works fine. It sorts by whatever sort I have in the pageable object. When I create the page here using new PageImpl it is not sorted despite passing in the pageable object. But I'm sure there must be a better way to get my visits than what I'm doing here so that's why I'm asking. – Sierra Huckins May 13 '16 at 17:18
  • That code does not show where `pageable` is coming from nor does it show where any sort is set on the `pageable` object. For your original code which returns an empty set you also do not provide any information about the `pageable` passed to `findByUsers()`. – Alan Hay May 13 '16 at 17:31
  • I expanded the code in my original question to show the entire controller. – Sierra Huckins May 13 '16 at 18:49

0 Answers0