Hibernate Annotation查询混乱

时间:2014-03-26 08:44:42

标签: java hibernate annotations hql hibernate-mapping

我有4张表,其中purchaseOrder与sullpier,item和ordertype有关系。 purchaseOrder所有表的引用键是supplierIdfk,itemIdfk,orderTypeIdfk。

所以我的问题如何获得suplliername =“XXX”的purchaseOrder记录,suplliername是供应商表的列之一。

我正在使用hibernate注释,反手使用mysql。

我已经用注释映射了所有实体。 谢谢你的时间。

我的表格看起来像这样

CREATE TABLE `purchaseorder` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`discount` double NOT NULL,
`finalAmount` double NOT NULL,
`remark` varchar(255) DEFAULT NULL,
`shipDate` datetime DEFAULT NULL,
`unitPrice` double NOT NULL,
`itemIdfk` int(11) DEFAULT NULL,
`orderIdfk` int(11) DEFAULT NULL,
`supplierIdfk` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `indexPurchaseOrderShipDate` (`shipDate`),
KEY `FKDFD4BAAD36B52348` (`itemIdfk`),
KEY `FKDFD4BAADFD3C54D4` (`orderIdfk`),
KEY `FKDFD4BAAD79028B3A` (`supplierIdfk`),
CONSTRAINT `FKDFD4BAAD36B52348` FOREIGN KEY (`itemIdfk`) REFERENCES `item` (`id`),
CONSTRAINT `FKDFD4BAAD79028B3A` FOREIGN KEY (`supplierIdfk`) REFERENCES `supplier`    (`id`),
CONSTRAINT `FKDFD4BAADFD3C54D4` FOREIGN KEY (`orderIdfk`) REFERENCES `ordertype` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

我的purchaseOrder的实体代码是这样的。

 package org.chillies.database;
 import java.util.Date;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import org.hibernate.annotations.Index;
 @Entity
 public class PurchaseOrder {
private int id;
private Date shipDate;
private double unitPrice;
private double discount;
private double finalAmount;
private String remark;
private OrderType orderType;
private Supplier supplier;
private Item item;

private static final String KeyOrderId = "orderIdfk";
private static final String KeySupplierId = "supplierIdfk";
private static final String KeyItemId = "itemIdfk";


@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}
@Index(name = "indexPurchaseOrderShipDate")
public Date getShipDate() {
    return shipDate;
}

public void setShipDate(Date shipDate) {
    this.shipDate = shipDate;
}

public double getUnitPrice() {
    return unitPrice;
}

public void setUnitPrice(double unitPrice) {
    this.unitPrice = unitPrice;
}

public double getDiscount() {
    return discount;
}

public void setDiscount(double discount) {
    this.discount = discount;
}

public double getFinalAmount() {
    return finalAmount;
}

public void setFinalAmount(double finalAmount) {
    this.finalAmount = finalAmount;
}

public String getRemark() {
    return remark;
}

public void setRemark(String remark) {
    this.remark = remark;
}


@ManyToOne
@JoinColumn(name = KeyOrderId)
public OrderType getOrderType() {
    return orderType;
}

public void setOrderType(OrderType orderType) {
    this.orderType = orderType;
}

@ManyToOne
@JoinColumn(name = KeySupplierId)
public Supplier getSupplier() {
    return supplier;
}

public void setSupplier(Supplier supplier) {
    this.supplier = supplier;
}

@ManyToOne
@JoinColumn(name = KeyItemId)
public Item getItem() {
    return item;
}

public void setItem(Item item) {
    this.item = item;
}
 }

实际上我正在使用这样的查询代码,但它给了我错误...

public PurchaseOrder getPurchaseOrder(String supplierName) {
    Session session = null;
    PurchaseOrder purchaseOrder = new PurchaseOrder();

    try {
        session = HibernateUtil.getSessionFactory().openSession();
        session.beginTransaction();
        Query query=session.createQuery("FROM PurchaseOrder WHERE PurchaseOrder.supplierIdfk=Supplier.id AND Supplier.name=?");
        purchaseOrder = (PurchaseOrder)query.uniqueResult();
        query.setString("Supplier.name",supplierName);
        session.getTransaction().commit();
    } catch (HibernateException e) {
        if (session != null) {
            session.getTransaction().rollback();
            e.printStackTrace();
        }
    } finally {
        if (session != null) {
            session.close();
        }
    }
    return purchaseOrder;
}

我的错误代码是这样的

 org.hibernate.QueryException: Unable to resolve path [PurchaseOrder.supplierIdfk], unexpected token [PurchaseOrder] [FROM org.chillies.database.PurchaseOrder WHERE PurchaseOrder.supplierIdfk=Supplier.id AND Supplier.name=?]
at org.hibernate.hql.ast.tree.IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:219)
at org.hibernate.hql.ast.tree.IdentNode.resolve(IdentNode.java:108)
at org.hibernate.hql.ast.tree.DotNode.resolveFirstChild(DotNode.java:175)
at org.hibernate.hql.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:550)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.addrExpr(HqlSqlBaseWalker.java:4543)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1289)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4243)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3722)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1864)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1789)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:818)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:604)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:288)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:231)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:254)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
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:94)
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:1651)
at org.chillies.dataaccesslayer.DataAccessLayer.getPurchaseOrder(DataAccessLayer.java:748)
at TestDataAccess.purchaseOrderDalTest(TestDataAccess.java:368)
at TestDataAccess.main(TestDataAccess.java:404)
Exception in thread "main" java.lang.NullPointerException
at TestDataAccess.purchaseOrderDalTest(TestDataAccess.java:370)
at TestDataAccess.main(TestDataAccess.java:404)

3 个答案:

答案 0 :(得分:0)

假设您已正确完成所有映射,则查询将如下所示

    List<PurchaseOrder> purchaseOrders;
    Session session = HibernateUtil.getSession();
    Query query = session.createQuery("from PurchaseOrder  po where po.supplierName = ?1");
    query.setString(1, pass_your_supplier_name);
    purchaseOrders = query.list();

答案 1 :(得分:0)

尝试

Query query=session.createQuery("select new fu.bar.PurchaseOrderDto(po.id, po.x, po.y, po.z) FROM PurchaseOrder po, Supplier sup WHERE po.supplier.id=sup.id AND sup.name=?");

Query query=session.createQuery("FROM PurchaseOrder po WHERE po.supplier.id=sup.id AND sup.name=?");

正如我在评论中所说: 如果您正在使用HQL,则必须使用java-objects变量,而不是数据库字段。

我不知道第二个是否有效,因为&#34;来自&#34;后未提及供应商。如果它不起作用,请在您的实体中创建2个构造函数:空和一个包含您需要的字段的构造函数,或者使用您需要的字段创建DTO。然后使用第一个查询。

编辑: 第二个问题是&#34; query.setString&#34;。它没有做你想要的。请改用setParameter:

    [...]
    Query query=session.createQuery("select new fu.bar.PurchaseOrderDto(po.id, po.x, po.y, po.z) FROM PurchaseOrder po, Supplier sup WHERE po.supplier.id=sup.id AND sup.name= :supName ");
    query.setParameter("supName",supplierName);
    purchaseOrder = (PurchaseOrder)query.uniqueResult();
    session.getTransaction().commit();
    [...]

答案 2 :(得分:0)

感谢您的回复和宝贵的时间。

我找到了答案。

我已经建立了这样的查询。

 createQuery("FROM PurchaseOrder po LEFT JOIN FETCH po.supplier sup WHERE sup.name=:supName").setString("supName",suplierName);