我正在尝试执行以下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
答案 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
注释)。