草庐IT

java - JPA 查询返回空值 - 具有空列的复合键

coder 2024-03-03 原文

我有一个旧数据库(实际上是 Cobol 文件),我正在使用带有 Hibernate/JPA 的专有 JDBC 驱动程序访问它。

实体有一个包含 2 列的复合主键:CODESITE .

在遗留数据中有相同的记录 CODE可以具有 SITE 的特定值, 或者在 SITE 中可能有一条为 NULL 的记录代表“所有站点”的列。这个文件的理论是,如果你找不到CODE为您的特定 SITE然后你在 SITE 中查找带有 NULL 的记录(“包罗万象”)。

我不能改变这个“表”的结构,因为它会涉及重写我们不想做的大部分遗留 Cobol 系统。我也无法创建数据 View 。

现在当我做 em.find主复合键类包含特定的 code site 为空,然后 Hibernate 会正确地找到列中具有 NULL 值的匹配记录 - 一切顺利!

但是如果我尝试使用 em.createQuery 进行查询类似于以下内容:

SELECT x FROM TareWeight x WHERE x.pk.code = 'LC2'

对于有 2 条记录,它在结果列表中为 SITE 中为 NULL 的记录返回一个空对象。柱子。

如果我采用 Hibernate 用于此查询的 SQL,则“数据库”返回两条记录,一条记录为 NULL 站点,另一条记录为特定站点。似乎当 Hibernate 从这些结果中加载实体时,它将它映射到一个空实体对象。

因此,Hibernate 要么支持,要么不支持。为什么会出现em.find工作但不是 em.createQuery ?

我知道this question是相似的,但答案似乎表明这是不可能的。但显然 Hibernate 可以正确地进行查找,那么为什么查询不起作用呢?

编辑:好的,所以我找到了一个 NullableStringType this Hibernate JIRA Issue 上的类定义并将其添加到我的项目中。

如果我添加一个 @Type site上的定义使用此类型类的 PK 列,然后我可以使用 site 从 SELECT 查询中成功获取非空实体。包含我定义为 null 表示的任何字符串文本的字段.

但是,它的行为仍然不同。 find返回一个带有 site 的实体包含 null 的字段,但查询返回一个实体,其中 site包含“NaN”的字段( null 的默认表示)。

仍然感觉这些应该表现相同。

更新 2:你们中的一些人想知道有关“数据库”的细节。

它是 Genesis RDBMS 引擎,作者 Trifox Inc. .数据存储在 AcuCobol(现为 Micro Focus)Vision 索引文件中。

我们将配置设置为将空白 (SPACES) 字母数字字段转换为 NULL,因此我们的包含 PK 字段空格的文件记录正在转换为 NULL。我可以通过使用WHERE site_id IS NULL来具体选择合适的记录,所以 RDBMS 将这些空白字段视为 SQL NULL。

说了这么多,我不相信这个问题与“数据库”有任何关系,除了 PK 字段为空是不寻常的事实。

更重要的是,如果我记录 Hibernate 用于 find 的 SQL和查询,它们几乎相同。

这是查找的 SQL:
select tareweight0_.CODE as CODE274_0_, tareweight0_.SITE as SITE274_0_, 
       tareweight0_.WEIGHT as WEIGHT274_0_ from TARE_WEIGHT tareweight0_ 
       where tareweight0_.CODE=? and tareweight0_.SITE=?

这是查询的 SQL:
select tareweight0_.CODE as CODE274_, tareweight0_.SITE as SITE274_, 
       tareweight0_.WEIGHT as WEIGHT274_ from TARE_WEIGHT tareweight0_ 
       where tareweight0_.CODE=? and tareweight0_.SITE=?

如您所见,唯一的区别是列别名。

更新 3:以下是一些示例数据:
select code, site, weight from tare_weight where code like 'LC%';

 CODE   SITE    WEIGHT
 ------ ------ -------
 LC1               .81
 LC2               .83
 LC2    BEENLH     .81
 LC3              1.07
 LC3    BEENLH    1.05
 LC4              1.05
 LCH1              .91
 LCH2              .93
 LCH2   BEENLH     .91
 LCH6             1.13
 LCH6   BEENLH    1.11

并专门搜索 NULL:
select code, site, weight from tare_weight where code like 'LC%' and site IS NULL;

 CODE   SITE    WEIGHT
 ------ ------ -------
 LC1               .81
 LC2               .83
 LC3              1.07
 LC4              1.05
 LCH1              .91
 LCH2              .93
 LCH6             1.13

最佳答案

"So either they support it or they don't"



TL;博士 这种期望/感觉是不合理的。您的链接中不受支持的功能(和我的下面)正是您的。 “不支持”意味着如果你这样做,那么 Hibernate 可以做任何他们想做的事情。你很幸运他们(似乎)返回了合理的值。 (虽然这只是猜测他们的表现。你没有规范。)没有理由期待任何事情,更不用说一致性了。当行为只是一些不受支持的情况出现的结果时,任何“为什么”很可能只是在考虑其他情况下编写代码的方式的产物。

这是 Hibernate Team 回答的(旧)支持线程:

帖子主题:一列空值复合键
发布时间:2006 年 7 月 3 日星期一上午 2:21

I have table with composite primary key and I created following mapping for the table.As it is possible to insert a null value for any column in composite key as long as the combination of all columns is Unique, I have record in teh table which has null value for V_CHAR2 column ( which is part of composite key ) . when I execute a query on this entity I get null values for the records which are having null value of V_CHAR2 column. What's wrong in my mapping and implementation..



发布时间:2006 年 7 月 11 日星期二上午 9:09
hibernate 团队

a primary key cannot be null (neither fully or partial)



发布时间:2007 年 1 月 6 日星期六上午 5:35
hibernate 团队

sorry to disapoint you but null in primary key is not supported - primarily because doing join's and comparisons will require alot of painfullly stupid code that is just not needed anywhere else.....think about it and you will see (e.g. how do you do a correct join with such a table)



这并不奇怪,因为在 SQL 的 PK 列中不允许 NULL。 PRIMARY KEY 声明是 UNIQUE NOT NULL 的同义词。 NULL 不等于任何具有(误导)意图的东西,即某些未记录的值不知道是相等的。 (至少在某些情况下,您对 PK 中 NULL 等于条件中的 NULL 的某种异常的期望与 SQL 相悖。)鉴于 PK 值中不允许使用 NULL,我们可以期待与 1:1 相关的 PK 优化映射和到集合而不是行包,以在方便时假设没有 NULL。可以预料,Hibernate 决定不担心他们的实现对不应出现在 SQL 中的情况做了什么。太糟糕了,他们在编译或执行时没有告诉你。希望它在文档中。)

find不同于 createQuery re NULL 并不奇怪。前者涉及一个值,而后者涉及没有 NULL 值(但不是)的行集合(不是包)。

解决方法可能是不将主键的任何列视为 NULL,而是将其视为存储中的实际空格字符串。 (无论这意味着什么,考虑到您的存储/DBMS/hibernate/JPA/Java 堆栈。您没有向我们提供足够的信息来了解您的数据库的 Cobol View 是否会因未将空间映射到 JPA 的 NULL 而受到阻碍)。使用您的数据,您仍然可以在列上声明 UNIQUE 索引。

关于java - JPA 查询返回空值 - 具有空列的复合键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34079524/

有关java - JPA 查询返回空值 - 具有空列的复合键的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  5. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  6. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

随机推荐