JPA查询问题

时间:2010-04-24 15:07:24

标签: java hibernate orm jpa

我正在尝试执行以下JPA查询:

    public static final String UPDATE_INVENTORY_CUSTOMER_FOR_AMS_MAPPING = "UPDATE Inventory inventory SET" 
    + " inventory.customer.id = :" + DataAccessConstants.PARAM_CUSTOMER_ID
    + " ,inventory.lastUpdateUserId = :" + DataAccessConstants.PARAM_USER_ID
    + " where inventory.amsConsignorName = :" + DataAccessConstants.PARAM_AMS_CONSIGNOR_NAME
    + " and inventory.amsConsignorOrgCd = :" + DataAccessConstants.PARAM_AMS_CONSIGNOR_ORG_CD
    + " and inventory.amsConsignorTypeName = :" + DataAccessConstants.PARAM_AMS_CONSIGNOR_TYPE
    + " and inventory.status.code in (:" + DataAccessConstants.PARAM_STATUS + ")";  

但它看到以下内容:

update ATL_INVENTORY,  set CONSIGNOR_ID=?, LAST_UPDATE_USER_ID=? where AMS_CONSIGNOR_NAME=? and AMS_CONSIGNOR_ORG_CD=? and AMS_CONSIGNOR_TYPE_NAME=? and (CODE in (? , ? , ? , ?))

为什么表名后面有逗号的理由?


解决方案

我必须将原始查询更改为以下内容:

update Inventory inv set " 
    + "inv.customer.id = :" + DataAccessConstants.PARAM_CUSTOMER_ID + " "
    + "where inv.amsConsignorName =:" + DataAccessConstants.PARAM_AMS_CONSIGNOR_NAME + " "
    + "and inv.amsConsignorOrgCd =:" + DataAccessConstants.PARAM_AMS_CONSIGNOR_ORG_CD + " "
    + "and inv.amsConsignorTypeName =:" + DataAccessConstants.PARAM_AMS_CONSIGNOR_TYPE + " "
    + "and exists(select 1 from Code code where inv.status = code and code.code in (:" + DataAccessConstants.PARAM_STATUS + "))

然后产生了这个:

update ATL_INVENTORY set CONSIGNOR_ID=? where AMS_CONSIGNOR_NAME=? and AMS_CONSIGNOR_ORG_CD=? and AMS_CONSIGNOR_TYPE_NAME=? and (exists (select 1 from ATL_CODE code1_ where ATL_INVENTORY.STATUS=CODE_ID and (code1_.CODE in (? , ? , ? , ?))))

根据此处的澄清说明:Incorrect SQL generated for JPA QL Update statement involving multiple entities

2 个答案:

答案 0 :(得分:1)

您的查询代码为UPDATE Inventory inventory SET,但生成的SQL显示为update ATL_INVENTORY, set。为什么文字SQL字符串不是您编码的?当我遇到这样的谜团时,他们通常是因为假设有一件事正在进行,而事实上另一件事正在发挥作用。

这表明您编写的SQL不会像您假设的那样用于生成SQL。查看此查询可能来自哪里。我敢打赌,真正的消息来源中有一个错误的逗号。

您使用的是哪种JPA实施?如果我对一个不好的假设不正确,那就说实施中存在一个错误。你以前用过吗?你有UPDATE的成功吗?如果是的话,它肯定会隐藏在你的代码库中。

你有一个包含大量常量的接口。就个人而言,我并不关心这样的设计。这是一个anti-pattern with a name

答案 1 :(得分:1)

我认为JPA提供程序中的错误是不太可能的,因为@duffymo说,你确定你使用了正确的常量,代码或者依赖关系是最新的吗?我会朝那个方向挖掘。

话虽如此,我真的很想知道你为什么不使用命名查询(大部分时间都是在部署时由持久性实现预先编译的),无论是在Java代码中还是在元数据映射文件(有趣的是,人们没有发现在XML 2.x中使用XML外化的EJB-QL查询非常易于管理,因此JPA的@NamedQuery注释)。