3

Talking about MVC with servlets and JSP's, in a context about products and manufacturers , when querying the application for a list of products:

  • the servlet loads a list of products from the database in a List object (or similar);
  • the servlet sets that list as attribute of the request and forwards the request to a JSP;
  • the JSP retrieves the list from the request and displays its contents on the webpage.

If the above is correct, my question is: how do I load products manufacturers (let's suppose that each product contains the id of its manufacturers)?

A common approach I saw around is that when the JSP loops inside the list object, upon showing each product is calls some other class method which finally runs a query on the database.

There are two things that I dislike about this approach:

  1. it breaks the MVC pattern;
  2. several, usually separate, queries are run on the database, potentially loading the same data (i.e. when two products come from the same manufacturer).

Is the above true? Are there better approaches that solve the problem?

So far I'm thinking about making a servlet load the manufacturers data in a separate object (e.g. a Map) along with the products List: both objects are set to the request, and then the JSP can access both when rendering the page.

A (potentially dangerous) drawback of this idea is that it requires more memory to hold all the informations; anything else?

3
  • 2
    If you're going to use JSP, you should probably use it on its own terms. You are already describing a level of detail that you have to attend to that is much higher than, say, ASP.NET MVC and C#. In other MVC systems (including ASP.NET MVC), you would be describing a ViewModel. Sep 15, 2014 at 18:42
  • What you are proposing is just a plain old cache of manufacturers. More than the memory, a consideration would be if it is worth the effort (and if it is, maybe the cache should lay inside the application logic, not in top of it). Generally I would say that it does not, because for getting the details of a product you typically will spend a very little time (and quite constant), so the user will not have an issue with the extra database access (if the server has capacity issues, get a better HW or provide a better design).
    – SJuan76
    Sep 15, 2014 at 18:50
  • Why don't you make a model-view domain, aka ViewObjects or TO. That will decouple your view from your data model. What it takes is to calc all the data needed in view and dump into ViewObjects. M of MVC is not forced to be tied to your domain model (persisted entities). Then your jsp will have whatever it needs to be rendered.
    – Laiv
    May 8, 2016 at 19:48

2 Answers 2

1

you can use ORM (object relational mapping) like JPA or Hibernate. when you are using ORM in your model, you dont need to re-query the related object because ORM will handle it for you automatically. for example:

define your model class and it's relationship:

class Product
{
    Manufacturer manufacturer;

    //setter and getter
}

class Manufacturer
{
    Long id;
    String name;

    //setter and getter
}

calling the model in the controller's method:

public Result showProductList()
{
   List<Product> products = ProductModel.get();
   return Result.ok().render("products", products);
}

and you can call the manufacture name in product in from your product model.

<c:forEach var="product" items="${products}">
    <option value ="10"><c:out value="${product.manufacturer.name}"/></option>
</c:forEach>

disclaimer: the example code above is not the real code. I just want to show the big picture about using the ORM in your code. using this approach you won't break the MVC design pattern (because you don't need to re-query the object from your view)

1
  • Then you have to fetch all the data In order to don't get LazyInitializationException's (data that might not be used). Or even worse, you can end up bringing jpa session to the view (open-session-in-view) what I don't suggest to do. Plus your view will be hard coupled to your domain (entity model).
    – Laiv
    May 8, 2016 at 19:41
0

It seems that you want map the joined tables to composite objects.

For this task is best use already mentioned ORM framework (best with JPA specification). Mapping relations to composite objects can be done in one-round-trip in ORM. ORM using more ways to optimize data access. But you must learn quite a complex framework.

Mentioned common approach with querying to DB in rendering JSP may be caused by using ORM lazy loading for associated objects. Unloaded associated objects are initialized as proxy objects (proxies have the same interface like target objects, but without values). Proxies are replaced with real objects by the querying database or cache at the time of the first access.

If you want to create code for one-round-trip query yourself, then you can use the same approach like using ORM frameworks:

public List<Product> getProducts(Connection con) {
    List<Product> result = new ArrayList<>;
    Statement stmt = null;
    try {
       stmt = con.createStatement();
       //only one query
       ResultSet rs = stmt.executeQuery("SELECT * FROM product p INNER JOIN manufacture m ON p.manufacture_id=m.id");
       while (rs.next()) {

           Product product = new Product();
           product.set...(rs.getType('column_of_product'))
           ...
           Manufacturer manufacturer = new Manufacturer();
           manufacturer.set...(rs.getType('column_of_manufacturer'))
           ...
           product.setManufacturer(manufacturer);

           result.add(product);
       }
   } catch (SQLException e) {
       JDBCTutorialUtilities.printSQLException(e);
   } finally {
       if (stmt != null) { stmt.close(); }
   }
   return result;
}
  • add 1. No, it's not break MVC pattern - This has nothing to do with the MVC approach
  • add 2. On the basis of this example it's seen that's no need of multiple queries into the database. Duplicating data or consuming more memory is for save processing time :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.