0

I have been still learning Hibernate and I need to develope application which can map database with "ManyToMany" reflection. There are 3 tables for it: PRODUCT, SHOP, SHOP_PRODUCT.

Product.class

@Entity
@Table(name="PRODUCT")
public class Product {

    @Id @GeneratedValue @Column(name="PRODUCT_ID")
    private Integer productId;

    @Column(name="PRODUCT_NAME", length=50, nullable=false)
    private String productName;

    @Column(name="RECOMMENDED_PRICE", length=10, precision=2)
    private BigDecimal recommendedPrice;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="shopProducts")
    private Collection<ShopProduct> shopProducts;

    public void setShopProducts(Collection<ShopProduct> shopProducts) {
        this.shopProducts=shopProducts;
    }

    public Collection<ShopProduct> getShopProducts() {
        return shopProducts;
    }

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

    public Integer getProductId() {
        return productId;
    }

    public void setProductName(String productName) {
        this.productName=productName;
    }

    public String getProductName() {
        return productName;
    }

    public void setRecommendedPrice(BigDecimal recommendedPrice) {
        this.recommendedPrice=recommendedPrice;
    }

    public BigDecimal getRecommendedPrice() {
        return recommendedPrice;
    }
}

Shop.class:

@Entity
@Table(name="SHOP")
public class Shop implements Serializable{

    @Id @GeneratedValue @Column(name="SHOP_ID")
    private Integer shopId;

    @Column(name="SHOP_NAME", length=50, nullable=false)
    private String shopName;

    @OneToMany(fetch=FetchType.LAZY, mappedBy="shopProducts")
    private Collection<ShopProduct> shopProducts;

    public Collection<ShopProduct> getShopProducts() {
        return shopProducts;
    }

    public void setShopProducts(Collection<ShopProduct> shopProducts) {
        this.shopProducts=shopProducts;
    }

    public Integer getShopId() {
        return shopId;
    }

    public void setShopId(Integer shopId) {
        this.shopId=shopId;
    }

    public String getShopName() {
        return shopName;
    }

    public void setShopName(String shopName) {
        this.shopName=shopName;
    }
}

ShopProduct.class:

@Entity
@Table(name="SHOP_PRODUCT")
@AssociationOverrides({
    @AssociationOverride(name="shopProducts", joinColumns=@JoinColumn(name="SHOP_ID")),
    @AssociationOverride(name="shopProducts", joinColumns=@JoinColumn(name="PRODUCT_ID"))
})
public class ShopProduct implements Serializable{

    @EmbeddedId
    private ShopProductId id;

    @Column(name="PRODUCT_PRICE", length=10, precision=2)
    private BigDecimal productPrice;

    @Column(name="PRODUCT_COUNT", length=10)
    private Integer productCount;

    public void setShopProductId(ShopProductId id) {
        this.id=id;
    }

    public ShopProductId getShopProductId() {
        return id;
    }

    public void setShop(Shop shop) {
        id.setShop(shop);
    }

    public void setProduct(Product product) {
        id.setProduct(product);
    }

    public Shop getShop() {
        return id.getShop();
    }

    public Product getProduct() {
        return id.getProduct();
    }

    public void setProductPrice(BigDecimal productPrice) {
        this.productPrice=productPrice;
    }

    public BigDecimal getProductPrice() {
        return productPrice;
    }

    public void setProductCount(Integer productCount) {
        this.productCount=productCount;
    }

    public Integer getProductCount() {
        return productCount;
    }

    @Override
    public boolean equals(Object o) {

        if (this==o) {
            return true;
        }

        if (o==null || this.getClass()!=o.getClass()) {
            return false;
        }

        ShopProduct sp=(ShopProduct)o;

        if (id!=null ? !id.equals(sp.getShopProductId()) : sp.getShopProductId()!=null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {

        return (id!=null ? id.hashCode() : 0);
    }
}

ShoProductId.class:

@Entity
@Table(name="SHOP_PRODUCT")
@AssociationOverrides({
    @AssociationOverride(name="shopProducts", joinColumns=@JoinColumn(name="SHOP_ID")),
    @AssociationOverride(name="shopProducts", joinColumns=@JoinColumn(name="PRODUCT_ID"))
})
public class ShopProduct implements Serializable{

    @EmbeddedId
    private ShopProductId id;

    @Column(name="PRODUCT_PRICE", length=10, precision=2)
    private BigDecimal productPrice;

    @Column(name="PRODUCT_COUNT", length=10)
    private Integer productCount;

    public void setShopProductId(ShopProductId id) {
        this.id=id;
    }

    public ShopProductId getShopProductId() {
        return id;
    }

    public void setShop(Shop shop) {
        id.setShop(shop);
    }

    public void setProduct(Product product) {
        id.setProduct(product);
    }

    public Shop getShop() {
        return id.getShop();
    }

    public Product getProduct() {
        return id.getProduct();
    }

    public void setProductPrice(BigDecimal productPrice) {
        this.productPrice=productPrice;
    }

    public BigDecimal getProductPrice() {
        return productPrice;
    }

    public void setProductCount(Integer productCount) {
        this.productCount=productCount;
    }

    public Integer getProductCount() {
        return productCount;
    }

    @Override
    public boolean equals(Object o) {

        if (this==o) {
            return true;
        }

        if (o==null || this.getClass()!=o.getClass()) {
            return false;
        }

        ShopProduct sp=(ShopProduct)o;

        if (id!=null ? !id.equals(sp.getShopProductId()) : sp.getShopProductId()!=null) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {

        return (id!=null ? id.hashCode() : 0);
    }
}

Main.class:

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Session session=new AnnotationConfiguration().configure().buildSessionFactory().openSession();
        //System.out.println(product.getShops().size());
    }

}

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.url">jdbc:mysql://localhost/shop_db</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

    <mapping class="com.nda.hibernate.Product"/>
    <mapping class="com.nda.hibernate.Shop"/>
    <mapping class="com.nda.hibernate.ShopProduct"/>
    <mapping class="com.nda.hibernate.ShopProductId"/>
</session-factory>
</hibernate-configuration>

When I try to execute it I will have got this exception:

Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.nda.hibernate.ShopProduct.shopProducts in com.nda.hibernate.Product.shopProducts
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:666)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:626)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1587)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1362)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1727)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1778)
    at com.nda.hibernate.Sessions.<clinit>(Sessions.java:14)
    ... 1 more

How can I fix it? Thank you.

1 Answer 1

2

The mappedBy attributes means:

This association is bidirectional. I'm not the owner of the association. Find the mapping of the association on the other side. The other side is in the target class of the association, under the following property/field: <the value of the mappedBy attribute>.

So, in your Product entity, the collection of ShopProducts is mapped by the field "product" in the ShopProduct. And in the Shop entity, the collection of ShopProducts is mapped by the field "shop" of the ShopProduct entity.

You haven't shown us the ShopProductId class, but you have additional errors in your mapping. The AssociationOverrides doesn't make sense: you're not extending any other class, so there's nothing to override.

Since ShopProduct is an entity, you should make your life easier, and use a single-column, auto-generated ID, as you're doing for the other entities.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I have just found the error. I should change "mappedby" value as 'id.shop' and 'id.product'for Shop and Product classes. Also I need to change values of 'AssociationOverride' attribute from ShopProduct.class.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.