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.
The
mappedByattributes 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.