代码之家  ›  专栏  ›  技术社区  ›  jlpp

如何防止Hibernate修剪字符串?

  •  3
  • jlpp  · 技术社区  · 15 年前

    我使用的是Oracle10g和Hibernate2.1(旧版本,但不允许升级到Fix)。我有一个表,其中有一个不可为空的列,名为tin,varchar2(9)。此列用于暂存从平面文件加载的数据,因此可以存储长度为9的任何字符串,如果输入文件有9个空格,则包括9个空格(即:“”。

    我注意到:

    1. Oracle10g自动将空字符串转换为空。所以如果你执行:

      SELECT NVL('', 'Input string converted to NULL') FROM dual; 
      

      结果是“输入字符串转换为空”,而不是“”。我认为这与问题有关。

    2. 当Hibernate读取tin值为9个空格(或任意数量的空格)且没有其他字符的记录时,它将该值存储在内存中为“”。然后,Hibernate似乎在欺骗自己,让自己认为值已经从9个空格变为空字符串。然后,如果将记录写回数据库,Hibernate将尝试写入一个空字符串而不是9个空格,Oracle显然会将其转换为空字符串,然后抛出一个非空约束冲突。

    以下是本专栏的HBM供参考:

    <property
        name="tin"
        type="java.lang.String"
        column="TIN"
        not-null="true"
        length="9">
    

    我的问题是,如何指示Hibernate不要将只包含空格的值转换为空字符串?

    更新1:我刚回去测试类似“text”的字符串,发现hibernate也会修剪这些空格,使字符串成为“text”,并愚弄自己认为值发生了变化。我一定错过了什么。这看起来不像是默认行为。

    更新2:看起来HBM2Java Ant任务将HBM转换为Java源可能是字符串修剪的来源。还在调查中。

    谢谢, 杰夫

    编辑:修改了问题的措辞,使其更加精确。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Joshua McKinnon    15 年前

    解决这个问题的方法之一是 create a Hibernate UserType . 在hibernate.org的链接中有一些说明,其中有一些已经为字符串转义创建的类。我意识到这并不能直接回答“我如何告诉Hibernate不要将9个空格转换为空字符串”,但它将解决数据库端的存储问题。

    该页上有两个实现-一个是对所有字符串进行转义(可以按您所需的方式处理9个空格大小写),另一个是对值“”进行转义。听上去前者可能更适合你。

    作为记录-我自己也在使用这个方法。您只需在类路径中拥有类,并将hbm.xml中的“type”属性设置为完全限定的类名(即在属性元素中添加type=“my.fully.qualified.hibernateUserType”)。

    在Java方面,您的类仍然直接处理Java.Lang.Stand和您希望看到的值,但是在Hibernate方面,它们将使用USER类型类。

        2
  •  3
  •       15 年前

    结果发现问题不在Hibernate身上。我正在研究的项目是使用HBM2Java Ant任务从HBM文件生成Java POJOS的。这反过来又引用getter/setters/equals/to string/etc的源模板,该模板是为剪裁setter中的所有java.lang.string属性而编写的。为了解决这个问题,我钝化了我遇到问题的那个类,这样它就不会再在每个构建上生成,然后删除tin属性上的trim。

        3
  •  2
  •   Thomas Jones-Low    15 年前

    我不知道冬眠的事。但我知道Oracle确实将空字符串视为空值。而且没有任何解决办法。