这怎么可能?
我们正在执行EJBQL在Toplink(DB是Oracle)和query.getResultList
是空的。
但是!当我将日志级别切换到FINE
并收到Sql查询时,TopLink生成,我试图在数据库上执行此查询,并且(奇迹!)我得到了一个非空结果!
可能的原因是什么?如何治疗?提前感谢!
注:没有例外。
更新:
查询日志:
SELECT DISTINCT t0.ID, t0.REG_NUM, t0.REG_DATE, t0.OBJ_NAME, t1.CAD_NUM, t1.CAD_NUM_EGRO, t2.ID, t2.DICT_TYPE, t2.ARCHIVE_DATE, t2.IS_DEFAULT, t2.IS_ACTUAL, t2.NAME, t0.INVENTORY_NUM FROM CODE_NAME_TREE_DICTIONARY t3, DEFAULTABLE_DICTIONARY t2, IMMOVABLE_PROP t1, ABSTRACT_PROPERTY t0 WHERE ((t3.ID IN (SELECT DISTINCT t4.ID FROM CODE_NAME_TREE_DICTIONARY t5, CODE_NAME_TREE_DICTIONARY t4, type_property_parents t6 WHERE (((t5.ID = ?) AND (t4.DICT_TYPE = ?)) AND ((t6.type_property_id = t4.ID) AND (t5.ID = t6.parent_id)))) AND ((t1.ID = t0.ID) AND (t0.PROP_TYPE_DISCR = ?))) AND ((t3.ID = t0.PROP_TYPE) AND ((t2.ID (+) = t1.STATUS_ID) AND (t2.DICT_TYPE = ?)))) ORDER BY t0.REG_NUM ASC
bind => [4537, R, R, realty_status]|#]
这个查询返回100k行,但是toplink认为它不是…
如果日志级别为FINE,您是否可以验证您正在连接到相同的数据库?你的测试用例有多简单?你能确认被翻译成那个SQL的就是这个JPQL吗?
VPD (http://download.oracle.com/docs/cd/B28359_01/network.111/b28531/vpd.htm)?政策?这种风格的东西在模式上定义了吗?这些特性透明地将动态where子句添加到在数据库会话中执行的语句中,因此在这种情况下查询结果取决于会话的状态。
当重新格式化查询时,以下条件看起来很奇怪:
AND t2.ID (+) = t1.STATUS_ID
AND t2.DICT_TYPE = ?
(+)
表示t2 (DEFAULTABLE_DICTIONARY)的外部连接,但这个表似乎是不可选的,因为它必须为第二个条件具有非空的DICT_TYPE。
仔细看,绑定参数似乎也关闭了,字段是有序的
- CODE_NAME_TREE_DICTIONARY。ID
- CODE_NAME_TREE_DICTIONARY。DICT_TYPE
- ABSTRACT_PROPERTY。PROP_TYPE_DISCR
- DEFAULTABLE_DICTIONARY。DICT_TYPE
对于给定的参数(4537,R, R, realty_status),第一个DICT_TYPE将是'R',而第二个是字符串"realty_status",这似乎不一致。
事务处理?Oracle从来不会给你一个"脏读",即数据库对未提交数据的访问。如果您在一个连接上发送数据,则在提交之前无法在任何其他连接上访问该数据。如果稍后手工尝试查询,则数据已经提交,并且得到了预期的结果。
如果您在多个连接中更新数据,并且数据操作未设置为"自动提交",则会出现这种情况。JPA默认为自动提交,但是在事务边界刷新可以给您一个更干净的设计。
我不能确切地说,但我有点惊讶,字符串参数没有引号。是否有可能交互地有一些自动转换,但在这个连接上,而不是字符串'R',它被转换为R的INT ascii ?
我找到原因了!原因是甲骨文!我在Postgres上尝试了相同的代码,它工作了!
我不知道为什么,但是在一些神奇的情况下,oracle忽略查询参数,查询返回空结果。