Nital
Nital

Reputation: 6114

In Vaadin how to display data from a joined table?

I am display all the products data on a page using JavaEE and Vaadin which is working except that the Category column which displays the entire object instead of just the Category name.

I am joining two tables product and category based on category_id column and fetching and displaying the category name from category table. Query is mentioned in ProductDaoImpl class below.

Products In Vaadin

Vaadin Version in POM

<vaadin.version>7.6.5</vaadin.version>

ProductsUI.java

@Title("Home")
@Theme("mytheme")
@Widgetset("com.study.crud.MyAppWidgetset")
public class ProductsUI extends UI {

    private static final Logger LOG = Logger.getLogger(ProductsUI.class);
    private final Grid productsGrid = new Grid();
    private DataSource dataSource;

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        getDataSource(vaadinRequest);
        configureComponents();
        buildLayout();
    }

    private void getDataSource(VaadinRequest vaadinRequest) {
        VaadinServletRequest req = (VaadinServletRequest) vaadinRequest;
        this.dataSource = (DataSource) req.getServletContext().getAttribute("dataSource");
    }

    private void configureComponents() {
        // get all products
        ProductDao productDao = new ProductDaoImpl(dataSource);
        List<Product> products = productDao.getProducts();

        //set all the products in grid
        productsGrid.setContainerDataSource(new BeanItemContainer<>(Product.class, products));
        productsGrid.setColumnOrder("productId", "name", "image", "listPrice", "category", "active");
        productsGrid.removeColumn("description");
        productsGrid.removeColumn("createdBy");
        productsGrid.removeColumn("expiryDate");
        productsGrid.removeColumn("modifiedOn");
    }

    private void buildLayout() {
        VerticalLayout layout = new VerticalLayout();

        //add products grid to the main layout
        layout.addComponent(productsGrid);
        productsGrid.setSizeFull();
        layout.setSizeFull();
        layout.setMargin(true);
        layout.setSpacing(true);

        setContent(layout);
    }

    @WebServlet(urlPatterns = "/*", name = "ProductsUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = ProductsUI.class, productionMode = false)
    public static class ProductsUIServlet extends VaadinServlet {
    }

}

Product.java

public class Product implements Serializable {

    private int productId;
    private String name;
    private String description;
    private String image;
    private BigDecimal listPrice;
    private Category category;
    private Date expiryDate;
    private String createdBy;
    private Date modifiedOn;
    private String active;

    public Product() {
    }

    public Product(int productId) {
        this.productId = productId;
    }

    public Product(int productId, String name, String description, String image, BigDecimal listPrice, Category category, Date expiryDate, String createdBy, Date modifiedOn, String active) {
        this.productId = productId;
        this.name = name;
        this.description = description;
        this.image = image;
        this.listPrice = listPrice;
        this.category = category;
        this.expiryDate = expiryDate;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.active = active;
    }

    public int getProductId() {
        return productId;
    }

    public void setProductId(int productId) {
        this.productId = productId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public BigDecimal getListPrice() {
        return listPrice;
    }

    public void setListPrice(BigDecimal listPrice) {
        this.listPrice = listPrice;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getModifiedOn() {
        return modifiedOn;
    }

    public void setModifiedOn(Date modifiedOn) {
        this.modifiedOn = modifiedOn;
    }

    public String getActive() {
        return active;
    }

    public void setActive(String active) {
        this.active = active;
    }

    @Override
    public String toString() {
        return "Product{" + "productId=" + productId + ", name=" + name + ", description=" + description + ", image=" + image + ", listPrice=" + listPrice + ", category=" + category + ", expiryDate=" + expiryDate + ", createdBy=" + createdBy + ", modifiedOn=" + modifiedOn + ", active=" + active + '}';
    }

}

Category.java

public class Category implements Serializable {

    private int categoryId;
    private String name;
    private String description;
    private Date expiryDate;
    private String createdBy;
    private Date modifiedOn;
    private String active;

    public Category() {
    }

    public Category(int categoryId) {
        this.categoryId = categoryId;
    }

    public Category(String name) {
        this.name = name;
    }

    public Category(int categoryId, String name) {
        this.categoryId = categoryId;
        this.name = name;
    }

    public Category(int categoryId, String name, String description, Date expiryDate, String createdBy, Date modifiedOn, String active) {
        this.categoryId = categoryId;
        this.name = name;
        this.description = description;
        this.expiryDate = expiryDate;
        this.createdBy = createdBy;
        this.modifiedOn = modifiedOn;
        this.active = active;
    }

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getModifiedOn() {
        return modifiedOn;
    }

    public void setModifiedOn(Date modifiedOn) {
        this.modifiedOn = modifiedOn;
    }

    public String getActive() {
        return active;
    }

    public void setActive(String active) {
        this.active = active;
    }

    @Override
    public String toString() {
        return "Category{" + "categoryId=" + categoryId + ", name=" + name + ", description=" + description + ", expiryDate=" + expiryDate + ", createdBy=" + createdBy + ", modifiedOn=" + modifiedOn + ", active=" + active + '}';
    }

}

ProductDaoImpl.java

public class ProductDaoImpl implements ProductDao {

    private final DataSource dataSource;

    public ProductDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }


    @Override
    public List<Product> getProducts() {
        String sql = "select a.*, b.name as category_name from product a, category b where a.category_id = b.category_id";
        LOG.debug(sql);

        Statement stmt = null;
        ResultSet rs = null;
        Connection cn = null;
        List<Product> products = new ArrayList<>();
        try {
            cn = dataSource.getConnection();
            stmt = cn.createStatement();
            rs = stmt.executeQuery(sql);
            while (rs != null && rs.next()) {
                int productId = new Integer(StringUtils.defaultString(rs.getString("PRODUCT_ID")));
                String name = StringUtils.defaultString(rs.getString("NAME"));
                String description = StringUtils.defaultString(rs.getString("DESCRIPTION"));
                String image = StringUtils.defaultString(rs.getString("IMAGE"));
                BigDecimal listPrice = new BigDecimal(StringUtils.defaultString(rs.getString("LIST_PRICE")));
                int categoryId = new Integer(StringUtils.defaultString(rs.getString("CATEGORY_ID")));
                String categoryName = StringUtils.defaultString(rs.getString("CATEGORY_NAME"));
                Category category = new Category(categoryId, categoryName);
                Date expiryDate = rs.getDate("EXPIRY_DATE");
                String createdBy = StringUtils.defaultString(rs.getString("CREATED_BY"));
                Date modifiedOn = rs.getDate("MODIFIED_ON");
                String active = StringUtils.defaultString(rs.getString("ACTIVE"));
                Product product = new Product(productId, name, description, image, listPrice, category, expiryDate, createdBy, modifiedOn, active);
                products.add(product);
            }
            LOG.debug("products = " + products);
            LOG.debug("products.size() = " + products.size());
            return products;
        } catch (SQLException | NumberFormatException ex) {
            LOG.error("Exception while getting products....", ex);
            return null;
        } //close resources
        finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
                if (cn != null) {
                    cn.close();
                }
            } catch (SQLException ex) {
                LOG.error("Exception while closing DB resources rs, stmt or cn.......", ex);
            } finally {
                try {
                    if (cn != null) {
                        cn.close();
                    }
                } catch (SQLException ex) {
                    LOG.error("Exception while closing cn.......", ex);
                }
            }
        }
    }
}

Upvotes: 0

Views: 426

Answers (1)

kukis
kukis

Reputation: 4644

The reason for this is that (since you use BeanItemContainer) Vaadin calls every getter in your Product class and tries to cast every returned value to String*. When it reaches the Category getter then it calls toString() on the returned value. Since you has overridden the toString() method in a Category, Vaadin calls it and displays returned value in the Grid. Should you left toString() method untouched in Category class it would display the value returned by Object.toString().

The simple way to fix this particular problem would be to add this getter in your Product class:

public String getCategoryName() {
    return category.getName();
}

and to remove the 'Category' column.

*this is not always true when we take into consideration Converters for the Columns but it is good enough in this scenario

Upvotes: 1

Related Questions