用hibernate加入外键

时间:2010-10-06 09:16:18

标签: java hibernate

我是一个hibernate-beginner,在尝试使用hibernate加入2个表时遇到问题。我想要做的是获取某个商店的产品列表,具体取决于商店ID,但我得到的是每个商店下列出的数据库中所有可用产品的列表。

以下是Product.java的代码:

@Entity
@Table (name = "products")
public class Product implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = -1001086120280322279L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column (name = "product_id")
private int product_id;

@Column(name = "product_name", unique=true)
private String product_name;

@JoinColumn(name = "store", referencedColumnName="store_id")
@ManyToOne(cascade=CascadeType.ALL)
private Store store;

等。

这是Store.java的代码:

@Entity
@Table(name = "stores")
public class Store implements Serializable{
/**
 * 
 */
private static final long serialVersionUID = 4497252090404342019L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column (name = "store_id")
private int store_id;

@Column(name = "store_name", unique=true)
private String store_name;

@JoinColumn(name="store", referencedColumnName= "store_id")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private List<Product> productList;

等。

以下是产出:(产品A应在Butik A下,产品B在Butik B下)

Butik: Butik A
Produkt: Banana A
Produkt: Morot A
Produkt: Banana B
Produkt: Apple B

Butik: Butik B
Produkt: Banana A
Produkt: Morot A
Produkt: Banana B
Produkt: Spple B

我有另外两个类,ProductDAO和StoreDAO负责查询,除了table-name / class-name之外,两个类中的代码类似。

public class ProductDAO { 
   public static List<Product> getStoreProductsList() { 
     Session hibernateSession = HibernateUtil.getSession(); 
     hibernateSession.beginTransaction();    
     Query query = hibernateSession.createQuery("from Product");
     hibernateSession.getTransaction().commit();     
     List<Product> storeProducts = query.list(); 
     return storeProducts;   
   }
}

有没有办法只用hibernate来解决这个问题?

由于

2 个答案:

答案 0 :(得分:7)

完成评论后。看起来你从来没有在那里设定条件,当然,无论他们属于哪个商店,你最终都会获得所有产品。没有惊喜。您在哪里指定标准?

你可以做点什么,

// One liner
List<Product> list = session.createQuery("from Product p where p.store.store_id = "
          +" :storeId").setInteger("storeId", storeId).list();

或者您可以获取Store然后获取Product的列表,如下所示

// Another one liner
List<Product> list = session.createCriteria(Store.class)
             .add(Restrictions.eq("store_id", storeId)).list().getProductList();

另一种更简单的方法,因为我们知道store_id是主键,(感谢Pakore提醒我)

// And another. Changed to use load() instead of get() here. 
// Assuming non-existance is an error.
List<Product> list = (Store) session.load(Store.class,storeId).getProductList();

[已编辑]

...添加一些有用的指针(感谢Pascal

  

14.3 Associations and joins

     

14.4 Forms of join syntax

答案 1 :(得分:4)

问题在于您的查询,它只是选择系统中的所有产品,而不管商店。

尝试使用休眠标准。为数据库创建查询更容易,您可以始终使用Java“side”而不是DB“side”。

int storeid = 1 //whatever you want here.
Criteria criteria = session.createCriteria(Product.class);
criteria.add(Restrictions.eq("store_id",storeid));
List<Product> list = criteria.list();

list将包含属于Storestoreid等于您提供的storeid的产品列表。

但是对于这个简单的查询,如果您使用session.get()session.load(),它甚至可以更容易(它们之间的区别在于answer或更多关于它们的信息在documentation

int storeid = 1; //Whatever you want
Store store = (Store) session.get(Store.class,storeid);
List<Product> list = store.getProductList();

如您所见,Hibernate负责为您进行连接:)。