Java API code with Spring Model:

public class UserBean {     
    @JsonProperty
    private String userId;          
    @JsonProperty
    private int limit;      
    @JsonProperty
    private int page;

    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public int getLimit() {
        return limit;
    }
    public void setLimit(int limit) {
        this.limit = limit;
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
}

public class ResponseJSON {
    private Map&lt;String, Object&gt; response = new LinkedHashMap&lt;String, Object&gt;(); 
    public void setStatus(String status) {
        response.put("status", status);
    }
    public void setMessage(String message) {
        response.put("message", message);
    }       
    public void add(String key, Object value) {
        response.put(key, value);
    }       
    public Map&lt;String, Object&gt; get() {
        return this.response;
    }
}


Controller:

@ResponseBody
@RequestMapping(value = "/user/products", method = RequestMethod.POST)
public Object getProductListByUser(@RequestBody UserBean userBean) {
    ResponseJSON responseJSON = new ResponseJSON();
    try {
        List&lt;Object&gt; result = userRepository.getProductListByUser(userBean);
        int resultCount = result.size();

        List&lt;Object&gt; productList = new ArrayList&lt;Object&gt;();
        for (int i = 0; i &lt; resultCount; i++) {
            ProductInfo product = (ProductInfo) result.get(i);

            Map&lt;String, Object&gt; productInfo = new LinkedHashMap&lt;String, Object&gt;();                  
            productInfo.put("id", product.getId());
            productInfo.put("title", product.getTitle());
            productInfo.put("description", product.getDescription());
            productInfo.put("iconImage", product.getIconImage());               
            productInfo.put("updateDatetime", product.getUpdateDatetime());
            productInfo.put("createDatetime", product.getCreateDatetime());
            productList.add(productInfo);
        }

        responseJSON.setStatus(Constants.SUCCESS);
        responseJSON.add("items", productList); 
    } catch (Exception e) {
        responseJSON.setStatus(Constants.FAIL);
        responseJSON.setMessage(e.getMessage());
        logger.error(e.getMessage());
    }

    return responseJSON.get();
}


Repository:

@SuppressWarnings("unchecked")
@Transactional
public List&lt;Object&gt; getProductListByUser(UserBean userBean) {
    Session session = sessionFactory.getCurrentSession();

    Criteria criteria = session.createCriteria(ProductInfo.class, "product")
        .createAlias("product.productOptions", "options", CriteriaSpecification.LEFT_JOIN)
        .add(Restrictions.eq("product.userId", userBean.getUserId()))
        .addOrder(Order.asc("productOptions.size"))
        .setFirstResult((userBean.getPage() - 1) * userBean.getLimit());
        .setMaxResults(userBean.getLimit());

    return criteria.list(); 
}


I'm developing some back-end APIs.
This API returns product lists of some user.
Purpose of this API is returning result of JSON data. 
So, I get datas from repository and assign to ResponseJSON object in the controller.
Is this approach efficient or not? Which way is better?
It would be easier to follow the getProductListByUser method if you use two ResponseJSON instance. One for normal execution and one for the exceptional cases:

try {
    ...

    final ResponseJSON responseJSON = new ResponseJSON();
    ...

    responseJSON.setStatus(Constants.SUCCESS);
    responseJSON.add("items", productList); 
    return responseJSON.get();
} catch (final Exception e) {
    final ResponseJSON responseJSON = new ResponseJSON();
    responseJSON.setStatus(Constants.FAIL);
    responseJSON.setMessage(e.getMessage());
    logger.error(e.getMessage());
    return responseJSON.get();
}


It also ensures that nobody modifies accidentally the exception case result in the try block and there isn't any incomplete ProductInfo data in the error response.