【问题标题】:JOIN 3 Entities in JPA在 JPA 中加入 3 个实体
【发布时间】:2013-04-24 11:33:29
【问题描述】:

这是我第一次开发 Java 应用程序并立即遇到问题。现在我有一个如下的 SQL 查询:

Select PD.* From product PD
join Stock SP on PD.id = SP.product_id
join storage SR on SR.id = SP.storage_id
join status ST on ST.storage_id = SR.id
where ST.id ='1qa7n234i'

我的实体:

public class Product extends MainEntity {
   public Product(){}
   public void setAtcKey(String pAtcKey) {
    atcKey = pAtcKey;
   }
}

public class StockPosition extends MainEntity {
   public StockPosition(){}
   @XmlIDREF
    public Product getProduct() {
        return product;
    }

    public void setProduct(Product pProduct) {
        product = pProduct;
    }

    @XmlIDREF
    public Storage getStorage() {
        return storage;
    }

    public void setStorage(Storage pStorage) {
        storage = pStorage;
    }
}

public class Storage extends MainEntity {
   public Storage(){}
   @XmlTransient
   public Station getStation() {
    return station;
   }

   public void setStation(Station pStation) {
    station = pStation;
   }
}

public class Status extends MainEntity {
   public Status(){}
}

所以我将它转换为 CriteriaQuery,例如:

CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> product = query.from(Product.class);
Join<StockPosition, Product> sp = product.join(StockPosition_.product);

但我收到了类似The method join(SingularAttribute&lt;? super Product,Y&gt;) in the type From&lt;Product,Product&gt; is not applicable for the arguments (SingularAttribute&lt;StockPosition,Product&gt;) 的错误消息?这个消息对我来说很奇怪(因为我是新手)。谢谢

【问题讨论】:

  • 你的意思是HQL查询吗?
  • 我正在使用:javax.persistence.criteria.Join
  • 您能解释一下并给我们更多细节
  • 这意味着您正在尝试构建条件查询。这不是唯一的方法,您还可以使用jpql 编写查询,这对初学者来说更容易。无论如何,如果您想要条件查询,请使用相应的标签并注意在 SO 上 theres 有价值的答案。如果您仍然需要帮助,请发布实体以及您已经完成的工作
  • 我只是更新我的问题,谢谢,伙计们。

标签: java jpa criteria-api


【解决方案1】:
CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> product = query.from(Product.class);
Join<StockPosition, Product> sp = product.join(StockPosition_.product);

我认为它应该是这样的:

CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> product = query.from(Product.class);
Join<StockPosition, Product> sp = product.join(Product_.stockposition);

也许您对 SQL 连接的方式有很多想法。

如果您不需要在运行时构建查询,您可以考虑改用 JPQL。

带有 NamedQueries 的 JPQL: http://www.objectdb.com/java/jpa/query/named

也许这可以帮助您解决有关 JPA 的其他问题 http://www.objectdb.com/java/jpa/query/criteria

您自己构建元模型类吗?还是您使用了持久性框架提供的“元模型生成器”?

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您的加入不正确。如果您的 Root 在 Product (Root&lt;Product&gt;) 中,那么您必须使用 Product 类中的属性加入。

    在这种情况下,您的Productclass 应该定义如下属性:

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
    private List<StockPosition> stackPositions;
    

    然后执行join如下:

    Join<Product, StackPosition> sp = product.join(Product_.stackPositions_);
    Predicate p = cb.equal(sp.get(StackPosition_.id, "1qa7n234i");
    ...
    

    【讨论】:

      【解决方案3】:

      如果您的数据库模型中存在 一对一 关系,那么具有如下所示的类和 注释 应该会给您结果。

      基本上,您将获取Stock,并获取stock.storage.status(根据@javax.peristence.JoinColumn 子句加入)

      class Product {
      
      @OnetoOne
      @JoinColumn(name="product_id")
      Stock stock;
      
      }
      
      class Stock {
      
      @OnetoOne
      @JoinColumn(name="storage_id")
      Storage storage;
      
      }
      
      class Storage {
      
      @OnetoOne
      @JoinColumn(name="storage_id")
      Status status;
      
      }
      

      【讨论】:

      • 谢谢你,伙计,但这种方法没有帮助:(
      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2014-01-29
      • 2020-11-30
      • 1970-01-01
      相关资源
      最近更新 更多