Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何为多个级别创建休眠条件_Java_Hibernate_Hibernate Criteria - Fatal编程技术网

Java 如何为多个级别创建休眠条件

Java 如何为多个级别创建休眠条件,java,hibernate,hibernate-criteria,Java,Hibernate,Hibernate Criteria,我正在尝试使用hibernate criteria API设计一个查询。目标是获得一个过滤后的项目列表,该列表以java.util.Set的形式存储在第三级,与特定值匹配。此外,该列表应在最外层过滤另一个特定值。以下是形成多级关系的模型类: Seller.java @Entity @Table(name="seller") public class Seller { private Integer id; private Set<Store> stores;

我正在尝试使用hibernate criteria API设计一个查询。目标是获得一个过滤后的项目列表,该列表以java.util.Set的形式存储在第三级,与特定值匹配。此外,该列表应在最外层过滤另一个特定值。以下是形成多级关系的模型类:

Seller.java

@Entity
@Table(name="seller")
public class Seller {
    private Integer id;
    private Set<Store> stores;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable=false)
    public Integer getId(){
        return id;
    }
    public void setId(Integer id){
        this.id = id;
    }

    @ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinTable(name="seller_store",
        joinColumns={@JoinColumn(name="sellertid")},
        inverseJoinColumns={@JoinColumn(name="storeid", referencedColumnName="id")})
    @ForeignKey(name="fk_sellerid_seller_store", inverseName="fk_storeid_seller_store")
    public Set<Store> getStores() {
        return stores;
    }
    public void setStores(Set<Store> stores) {
        this.stores = stores;
    }
}
Stock.java

@Entity
@Table(name="stock")
public class Stock {
    private Integer id;
    private Set<Item> stockItems;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id", unique=true, nullable=false)
    public Integer getId(){
        return id;
    }
    public void setId(Integer id){
        this.id = id;
    }

    @ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinTable(name="stock_stockitem",
            joinColumns={@JoinColumn(name="stockid")},
            inverseJoinColumns={@JoinColumn(name="stockitemid")})
    @ForeignKey(name="fk_stockid_stock", inverseName="fk_stockitemid_stock")
    public Set<Item> getStockItems() {
        return stockItems;
    }
    public void setStockItems(Set<Item> stockItems) {
        this.stockItems = stockItems;
    }
现在,我需要获取一个特定的Stock对象,该对象包含具有特定id的项目,对于具有特定id的卖家也需要这样做。我可以通过按id获取顶级卖家对象来轻松实现这一点,但这将给我的代码带来一个负担,即手动筛选生成的项目列表股票带有多个for循环,这绝对不是一个好主意。对于映射和/或标准逻辑的任何建议和指南,我们将不胜感激。
提前谢谢

第一步应该是将Store实体更改为支持许多卖家,然后我将开始编写jpql查询

SELECT * FROM stock s 
JOIN stock.items si 
JOIN stock.store.sellers sss
WHERE si.id IN(:itemIds) 
AND sss.id IN(:sellerIds)
第二步是以条件查询方式重写此查询

CriteriaQuery<Stock> cq = cb.createQuery(Stock.class);
Metamodel m = em.getMetamodel();
EntityType<Stock> Stock_ = m.entity(Stock.class);
Root<Stock> stock = cq.from(Stock.class);
Join<Stock, Item> items = stock.join(Stock_.items);
Join<Stock, Store> store = stock.join(Stock_.store);
Join<Store, Seller> sellers = store.join(Store_.sellers);
cq.where(cb.in(items.get(Item_.id), Arrays.asList(1, 2, 3, 4))
    .and(cb.in(sellers.get(Seller_.id), Arrays.asList(1, 2, 3, 4));
或使用别名:

List stocks = sess.createCriteria(Cat.class)
  .createAlias("items", "si")
  .createAlias("store.sellers", "sss")
    .add( Restrictions.in("si.id", {1, 2, 3, 4, 5}) )
    .add( Restrictions.in("sss.id", {1, 2, 3, 4, 5}) )
  .list();
同样,我也不确定这些查询中是否有任何一个能起作用


作为最后的建议,您应该避免使用特定于供应商的工具。JPA标准查询是标准的。这意味着其他供应商也使用它。例如,如果您使用JPA标准而不是Hibernate标准,您可以在Hibernate和EclipseLink之间切换,而不会出现很多问题,因为这两个供应商都应该遵循标准(不是100%,而是高度标准)。

有人能帮上忙吗?谢谢您的回复和回答@bigluis;我理解通过加入我将能够获得累积的股票集合;但我不理解商店可能与卖家有多(一个或多个?)关系的想法。正如您所看到的,我已经将卖家配置为拥有多个单独的表,这是基于一个卖家可能拥有超过1个“存储”的事实。此外,我在问题标题中所写的“条件查询”这一措辞可能造成了混乱。我想用Hibernate标准API而不是JPA Crtieria API来实现这一点。在那里你可以看到这两个实体都有很多。我的意思是,您还应该用@manytomy注释Store.sellers。您应该用@manytomy(mappedBy=“sellers”)标记Store.sellers。这告诉hibernate Store.sellers将从sellers表中获取。您不应该用@JoinTable注释Store.sellers,因为您已经注释了Seller.stores.Ok。我会听从你的建议,试着用JPA的方式来做这件事。:)非常感谢您重写了criteria的Hibernate风格。
CriteriaQuery<Stock> cq = cb.createQuery(Stock.class);
Metamodel m = em.getMetamodel();
EntityType<Stock> Stock_ = m.entity(Stock.class);
Root<Stock> stock = cq.from(Stock.class);
Join<Stock, Item> items = stock.join(Stock_.items);
Join<Stock, Store> store = stock.join(Stock_.store);
Join<Store, Seller> sellers = store.join(Store_.sellers);
cq.where(cb.in(items.get(Item_.id), Arrays.asList(1, 2, 3, 4))
    .and(cb.in(sellers.get(Seller_.id), Arrays.asList(1, 2, 3, 4));
List stocks = sess.createCriteria(Stock.class)
  .createCriteria("items")
    .add( Restrictions.in("id", {1, 2, 3, 4, 5}) )
  .createCriteria("store")
    .createCriteria("sellers")
      .add( Restrictions.like("id", {1, 2, 3, 4, 5}) )
  .list();
List stocks = sess.createCriteria(Cat.class)
  .createAlias("items", "si")
  .createAlias("store.sellers", "sss")
    .add( Restrictions.in("si.id", {1, 2, 3, 4, 5}) )
    .add( Restrictions.in("sss.id", {1, 2, 3, 4, 5}) )
  .list();