【问题标题】:How to execute join query in hibernate?如何在休眠中执行连接查询?
【发布时间】:2013-12-13 18:12:26
【问题描述】:

如何在 Hibernate 中运行 join HQL 查询?我已将值插入到一对一关系表中。但在我插入表之前,我需要检查值是否存在。如果退出,我需要该记录的 id。之后我已插入 orderdetails 表。

所以,我需要运行 SQL 从表中获取 ID。

表格:产品

Product_id
product_name

表:版本

version_id
product_id
date

所以如果记录存在,我需要找到 version_id。我想运行 SQL:select version_id from product p,version v where p.product_id=v.product_id and product_name='stackoverflow'

我试过这种方式..

Query q=session.createQuery("from Product p,Version v where p.product_id=v.product_id and productname='"+item+"'");
if(query.list().size()>0){
for(Iterator it=query.iterate();it.hasNext();)
{
Version std = ( Version) it.next();
System.out.println("partid: " + std.getversion_id());
V.setversion_id(std.getversion_id());
 }

但上面的代码给出了错误。

org.hibernate.QueryException: could not resolve property: product_id of: Version [from Product p,Version v where p.product_id=v.product_id and productname='stack']
    at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)
    at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:75)
    at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1465)
    at org.hibernate.hql.ast.tree.FromElementType.getPropertyType(FromElementType.java:315)
    at org.hibernate.hql.ast.tree.FromElement.getPropertyType(FromElement.java:487)
    at org.hibernate.hql.ast.tree.DotNode.getDataType(DotNode.java:611)
    at org.hibernate.hql.ast.tree.DotNode.prepareLhs(DotNode.java:263)
    at org.hibernate.hql.ast.tree.DotNode.resolve(DotNode.java:210)
    at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:117)
    at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:113)
    at org.hibernate.hql.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:880)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1330)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4471)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3947)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2047)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1972)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:831)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:617)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:244)
    at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:256)
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187)
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
    at com.import(CompleteNotice.java:764)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)

产品类别:

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

    private String product_id;
    private String product_name

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="PRODUT_ID")
    public String getProduct_id() {
        return product_id;
    }

    public void setProduct_id(String product_id) {
        this.product_id = product_id;
    }

    @Column(name="PRODUCT_NAME")
    public String getProduct_name() {
        return product_name;
    }

    public void setProduct_name(String product_name) {
        this.product_name = product_name;
    }


}

版本:

@Entity
@Table(name="DBO.VERSION")
public class Version {

    private int version_id;
    private int product_id;
    private Product product;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="VERSION_ID")
    public int getVersion_id() {
        return version_id;
    }

    public void setVersion_id(int Version_id) {
        this.version_id = version_id;
    }


    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="product_id")
    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

请告知如何在休眠中执行上述查询?

【问题讨论】:

  • 在您的表格中,一个产品可以有one-to-many 个版本
  • 第一件事是product和p之间缺少qhitespace。
  • 我们的商务版产品不同。我们那里有几个表有一对多的版本关系表。这里只应用一对一
  • 抛出什么样的错误?
  • 无法解析属性:product_id of: Version [from Product p,Version v where p.product_id=v.product_id and productname='stack']

标签: java hibernate jpa


【解决方案1】:

在这种情况下,首先您的类名是 Part 而不是 Product。 因此,您还必须在查询中使用 Part。

其次,我不确定是否有能够生成的休眠 ID 生成器 字符串序列,因此您必须分配一个自定义的 id 生成器。

此外,您发布的代码没有显示 Version 类,而是 与产品或部件的关联。

在我看来,尽管存在 id 问题,但您的查询应该如下所示

select v.version_id 
from FeatureVersion v, Part p
where v.product.product_id = p.product_id
and p.product_name='"+item+"

当您执行该查询时。 Hibernate 创建一个 FeaturedVersion 类型的实例并根据关联的表列初始化它的属性。

尽量避免使用这种语句。改用 PreparedStatements 来传递 查询的参数并使用命名参数左右将它们分配给查询。

尽量使用符合 Java 和 JavaBeans 约定的属性和类名,并且 表示避免下划线等。因此,它更易于阅读查询,并且您可以避免令人沮丧的错误搜索。

【讨论】:

  • SQL 生成器为两个表生成 id。因为插入记录完美。现在我想检查特定项目是否已经存在。
  • 假设产品和版本为表格。所以查询将是 Select v.version_id from Product p,Version v where v.product_id = p.product_id and name='item'。
  • 如果我错了,请纠正我。因为我又遇到了同样的错误。
  • HQL 查询与 SQL 的不同之处在于它直接与实体类的对象相关联。 Hibernate 自己解析到数据库中表和列的映射因此在您的查询中,您必须使用类名和适当的属性名称。您在本例中使用引用名称解析的引用或关系 product 后跟一个点和此类的适当属性
【解决方案2】:

你的映射很糟糕。 FeatureVersion中不需要product_id

@Entity
@Table(name="DBO.PRODUCT")
public class Part { // why not call Product..

    private String product_id;
    private String product_name;
    private FeatureVersion version;    

    @OneToOne(mappedBy="product")
    public FeatureVersion getFeatureVersion(){
        return featureVersion;
    }    
      //put others getters and setter 
 }

在另一个班级。

@Entity
@Table(name="DBO.VERSION")
public class FeatureVersion {

    private int version_id;
    private Product product;

    //add setter and getter that i leave

   @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="product_id", referencedColumnName= "product_id")
    public Product getProduct() {
        return product;
    }

}

在客户端代码中,查询字符串如下所示:

String hql = "FROM Part p fetch join p.version Where p.product_name = :myParam" // this is cause you put it lazy if you don't put anything it will be eager 
session.createQuery(hql).setParameter("myParam", productName).uniqueResult() // or list

一些建议:

1) 遵循 java 代码约定,例如将 product_name 更改为 productName 或只是 name。 2) 按照约定调用数据库中同名的类。

3) 对于字符串,如果您不想完全匹配,我会使用 like 子句而不是 =。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2015-04-17
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    相关资源
    最近更新 更多