Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAVA 8 - Stream features giving error while retriving data from 3 POJO class

I am having 3 POJO class for products, attribute & value. All three POJOs are have relationship with other POJO class. Now, I want to retrive value for the each and every products.

It was working perfectly with the older approach but now i want to modify my code with new JAVA 8 features.

Please find my code below.

listProducts.stream().forEachOrdered(listproducts -> 
listproducts.getProductAttr()
                .stream().forEachOrdered(attr -> 
(((Collection<ProductAttrValue>) attr.getProductAttrValue()
                .stream().filter(attrlabel -> 
attrlabel.getLabel().equalsIgnoreCase("source"))))
                .stream().forEachOrdered(attrval ->
                                {
                                    System.out.println(attrval.getValue());
                                }
                            )       
                        )

            );

Please find the error message that I am getting.

Exception in thread "main" java.lang.ClassCastException: 
java.util.stream.ReferencePipeline$2 cannot be cast to java.util.Collection
at Hibernate.Testing.App.lambda$1(App.java:81)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown 
Source)
at java.util.stream.ReferencePipeline$Head.forEachOrdered(Unknown Source)
at Hibernate.Testing.App.lambda$0(App.java:81)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.ReferencePipeline$Head.forEachOrdered(Unknown Source)
at Hibernate.Testing.App.main(App.java:80)

If am not doing type casting .stream().forEachOrdered(attr -> ((Collection<ProductAttrValue>) attr.getProductAttrValue() am getting the below errors.

enter image description here Please find my Product POJO class

public class Product {

    private String name;
    private long std_delivery_Time;
    private int min_order_Quantity;

    private String status;
    private long catalog_Id;
    private Date expiration_Date;
    private int rank;
    private String product_Type;
    private int is_Visible;
    private String product_Group;
       private String code;


    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

    public String getName() {
        return name;
    }

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


    public void setId(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }

    public void setId(int id) {
          this.id = id;
         }


    public String getCode() {
      return code;
     }


    public void setCode(String code) {
      this.code = code;
     }

    @OneToMany( mappedBy = "product", cascade = CascadeType.ALL)
    private List<ProductAttr> productAttr;
    public List<ProductAttr> getProductAttr() {
        return productAttr;
    }

    public void setProductAttr(List<ProductAttr> productAttr) {
        this.productAttr = productAttr;
    }
 }

ProductAttr class

public class ProductAttr {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", updatable=false, nullable=false)
    private long id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "PRODUCT_ID")
    private long product_id;


    public ProductAttr() {
        super();
        // TODO Auto-generated constructor stub
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public long getProduct_id() {
        return product_id;
    }

    public void setProduct_id(long product_id) {
        this.product_id = product_id;
    }

    public long getId() {
        return id;
    }

    @ManyToOne
    @JoinColumn(name = "PRODUCT_ID",  referencedColumnName = "ID", 
insertable = false, updatable = false)
    private Product product;

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    @OneToMany( mappedBy = "productAttr", cascade = CascadeType.ALL)
    private Set<ProductAttrValue> productAttrValue;

        public Set<ProductAttrValue> getProductAttrValue() {
            return productAttrValue;
        }

        public void setProductAttrValue(Set<ProductAttrValue> 
productAttrValue) {
            this.productAttrValue = productAttrValue;
        }

}

ProductValue class

public class ProductAttrValue {

    @Id
    @Column(name = "ATTR_ID", updatable=false, nullable=false)
    private long attr_id;

    @Column(name = "LABEL")
    private String label;

    @Column(name = "VALUE")
    private String value; 

        public long getAttr_id() {
            return attr_id;
        }

        public void setAttr_id(long attr_id) {
            this.attr_id = attr_id;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }


      @ManyToOne
      @JoinColumn(name = "ATTR_ID",  referencedColumnName = "ID", insertable 
      = false, updatable = false)

      private ProductAttr productAttr;

      public ProductAttr getProductAttr() {
            return productAttr;
      }

      public void setProductAttr(ProductAttr productAttr) {
            this.productAttr = productAttr;
        }

      public ProductAttrValue() {
        super();
        // TODO Auto-generated constructor stub
    }


}
like image 250
Karthikeyan Avatar asked May 21 '26 10:05

Karthikeyan


1 Answers

Your indentation suggests a wrong mindset. These stream() operation are not on the same level. You have a nested operation:

listProducts.stream().forEachOrdered(listproducts -> 
    listproducts.getProductAttr().stream().forEachOrdered(attr -> 
        attr.getProductAttrValue().stream()
                                  .filter(av -> av.getLabel().equalsIgnoreCase("source"))
                     /*.stream()*/.forEachOrdered(av -> System.out.println(av.getValue()))
    )
);

(I changed the misleading name attrlabel and attrval to av, as these aren’t labels or values; you’re invoking .getLabel() and .getValue() subsequently on these variables, so I used av for “ProductAttrValue”)

The filter operation is the only operation that is not nesting, as it is an intermediate operation chained to the stream and the terminal operation just has to be chained to the resulting stream. There is no stream() invocation necessary at that place (the one marked with /*.stream()*/).

That said, you should avoid such nested operation.

You can use

listProducts.stream()
            .flatMap(listproducts -> listproducts.getProductAttr().stream())
            .flatMap(attr -> attr.getProductAttrValue().stream())
            .filter(av -> av.getLabel().equalsIgnoreCase("source"))
            .forEachOrdered(av -> System.out.println(av.getValue()));

instead.

like image 86
Holger Avatar answered May 23 '26 00:05

Holger