Search code examples
javahibernatehibernate-mapping

java.lang.Object; cannot be cast to shoppingbasket.Product


I am trying to retrieve a list of products with they're associated offers. After iterating through the result of the query I want to be able to use the getters/setters from the products class but I know it's not working because the query is not returning an instance of Product.

function to grab the products:

public List<Product> getProducts() {
    factory = (new Configuration()).configure().buildSessionFactory();
    Session session = factory.getCurrentSession();

    session.beginTransaction();

    List<Product> products = new ArrayList<Product>();

    Query query = session.createQuery("from Product p INNER JOIN p.offers"); 
    //The castList is declared and explained at the bottom of listing
    List<Product> list =  query.list();

    Iterator<Product> iter = list.iterator();

    while (iter.hasNext()) {
        Product product = iter.next();
        System.out.println(product);
    }
}

Hibernate mapping for Offer:

<hibernate-mapping>
<class name="shoppingbasket.Offer" table="offers">
    <id name="offerID" type="integer" access="field">
        <column name="OfferID" />
        <generator class="assigned" />
    </id>
    <property name="offerDescription" type="java.lang.String" access="field">
        <column name="OfferDescription" length="60" not-null="true"/>
    </property>
    <property name="shortDescription" type="java.lang.String" access="field">
        <column name="ShortDescription" length="10" not-null="false"/>
    </property>
    <property name="TFTPOTGroup" type="java.lang.Integer" access="field">
        <column name="TFTPOTGroup" length="4" not-null="false" default="null"/>
    </property>
    <property name="discountPercentage" type="java.lang.Double" access="field">
        <column name="DiscountPercentage"  not-null="false" default="null"/>
    </property>
</class>

Hibernate mapping for Product:

<hibernate-mapping>
<class name="shoppingbasket.Product" table="products">
    <id name="productID" type="integer" access="field">
        <column name="ProductID" />
        <generator class="assigned" />
    </id>
    <property name="offerID" type="java.lang.Integer" access="field">
        <column name="OfferID" />
    </property>
    <property name="productName" type="java.lang.String" access="field">
        <column name="ProductName" length="40" not-null="true"/>
    </property>
    <property name="unitPrice" type="java.math.BigDecimal" access="field">
        <column name="UnitPrice"/>
    </property>
    <one-to-one name="offers" class="shoppingbasket.Offer" />
</class>

Product class:

public class Product implements java.io.Serializable {
private Integer productID;
private Integer offerID;
private String productName;
private BigDecimal unitPrice;
private Offer offer;
public Integer getProductID() {
    return productID;
}
public void setProductID(Integer productID) {
    this.productID = productID;
}
public Integer getOfferID() {
    return this.offerID;
}
public void setOfferID(Integer offerID) {
    this.offerID = offerID;
}
public Offer getOffers() {
    return offer;
}
public void setOffers(Offer offer) {
    this.offer = offer;
}
//more getters/setters
}

Offer class:

public class Offer
{
private Integer offerID;
private String offerDescription;
private String shortDescription;
private Integer TFTPOTGroup;
private Double discountPercentage;
public Integer getOfferID() {
    return offerID;
}
public void setOfferID(Integer offerID) {
    this.offerID = offerID;
}
//more getters/setters

}

Any help would be hugely appreciated


Solution

  • #Potential Unnecessary Projections Data:

    Since you're not specifying SELECT clause in the query and putting explicit joins, hibernate will return 2 objects per row (Product, Offers), wherein Product object might already be populated with the Offer data due to underlying mapping associations.

    Try adding select clause to the query and see if it casts correctly

    Add SELECT p FROM ... to the query