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!