Parameterization of object properties

Can someone show me an efficient way of code to have an object property in spring mvc change based on parameters sent to it from a hyperlink?

I am modifying an example application with a spring image so that the owner page can show separate lists of each type of pet owned by a particular owner. Currently, the list of "pets" is the property of each "owner" and is available in jstl as owner.pets. I want my jstl code to be able to call owner.cats, owner.dogs, owner.lizards, etc. From jstl and fill out several separate lists in different parts of the web page, although all cats, dogs, and lizards are stored in the same data table.

How to do it?

Here are the relevant JpaOwnerRepositoryImpl.java methods:

@SuppressWarnings("unchecked")
public Collection<Owner> findByLastName(String lastName) {
    // using 'join fetch' because a single query should load both owners and pets
    // using 'left join fetch' because it might happen that an owner does not have pets yet
    Query query = this.em.createQuery("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName");
    query.setParameter("lastName", lastName + "%");
    return query.getResultList();
}

@Override
public Owner findById(int id) {
    // using 'join fetch' because a single query should load both owners and pets
    // using 'left join fetch' because it might happen that an owner does not have pets yet
    Query query = this.em.createQuery("SELECT owner FROM Owner owner left join fetch owner.pets WHERE owner.id =:id");
    query.setParameter("id", id);
    return (Owner) query.getSingleResult();
}

Here are the relevant aspects of Owner.java:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets;

protected Set<Pet> getPetsInternal() {
    if (this.pets == null) {this.pets = new HashSet<Pet>();}
    return this.pets;
}

public List<Pet> getPets() {
    List<Pet> sortedPets = new ArrayList<Pet>(getPetsInternal());
    PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
    return Collections.unmodifiableList(sortedPets);
}

Here is the part of OwnerController.java that controls the url // owner template, from which I want my jstl to separately list cats, dogs, lizards, etc. in separate parts of the page (not in one list group, but in several separate lists.):

@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(@RequestParam("ownerID") String ownerId, Owner owner, BindingResult result, Map<String, Object> model) {
    Collection<Owner> results = this.clinicService.findOwnerByLastName("");
    model.put("selections", results);
    int ownrId = Integer.parseInt(ownerId);
    model.put("sel_owner",this.clinicService.findOwnerById(ownrId));
    return "owners/ownersList";
}
0
source share
1 answer

Since you did not ask for a verbose solution, you can just do this semi-dirty fix.

Owner.java

@Transient
private Set<Pet> cats = new HashSet<Pet>();

[...]

// Call this from OwnerController before returning data to page.
public void parsePets() {
  for (Pet pet : getPetsInternal()) {
    if ("cat".equals(pet.getType().getName())) {
      cats.add(pet);
    }
  }
}

public getCats() {
  return cats;
}

ownerDetail.jsp

[...]
<h3>Cats</h3>
<c:forEach var="cat" items="${owner.cats}">
    <p>Name: <c:out value="${cat.name}" /></p>
</c:forEach>

<h3>All pets</h3>
[...]

OwnerController.java

/**
 * Custom handler for displaying an owner.
 *
 * @param ownerId the ID of the owner to display
 * @return a ModelMap with the model attributes for the view
 */
@RequestMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
    ModelAndView mav = new ModelAndView("owners/ownerDetails");
    Owner owner = this.clinicService.findOwnerById(ownerId);
    owner.parsePets();
    mav.addObject(owner);
    return mav;
}

Screenshots of the change

+1
source

All Articles