【问题标题】:How do I prevent Hibernate from trimming strings?如何防止 Hibernate 修剪字符串?
【发布时间】:2010-10-11 19:50:17
【问题描述】:

我正在使用 Oracle 10g 和 Hibernate 2.1(旧版本,但不允许升级修复)。我有一个表,其中包含一个不可为空的列,名为 TIN,varchar2(9)。此列用于暂存从平面文件加载的数据,因此可以存储长度为 9 的任何字符串,如果输入文件有 9 个空格,则包括 9 个空格(即:'')。

我注意到的是:

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

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

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

  2. 当 Hibernate 读取 TIN 值为 9 个空格(或任意数量的空格)且没有其他字符的记录时,它将值作为 '' 存储在内存中。然后,Hibernate 似乎自欺欺人地认为,可以说,该值已从 9 个空格变为空字符串。然后,如果将记录写回数据库,Hibernate 会尝试写入一个空字符串而不是 9 个空格,Oracle 显然会将其转换为 null,然后引发非空约束违规。

作为参考,以下是本专栏的 HBM:

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

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

更新1:我刚回去测试了像'text'这样的字符串,发现Hibernate也修剪了这些空格,使字符串'text'并自欺欺人地认为值改变了。我肯定错过了什么。这似乎不是默认行为。

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

谢谢, 杰夫

编辑:将问题措辞更改为更准确。

【问题讨论】:

    标签: java oracle hibernate


    【解决方案1】:

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

    该页面上有 2 种实现 - 一种转义所有字符串(可能以您想要的方式处理 9 个空格的情况),另一种只转义值 ''。听起来前者可能更适合你。

    为了记录 - 我自己正在使用这种方法。您需要做的就是在您的类路径中拥有该类,并将 HBM​​.xml 中的“类型”属性设置为完全限定的类名(即,将 type="my.fully.qualified.HibernateUserType" 添加到您的属性元素)。

    在 Java 方面,您的类仍将直接处理 java.lang.String 和您希望看到的值,但在休眠方面,它们将使用 UserType 类。

    【讨论】:

    • 谢谢约书亚。这似乎是一个很好的方法。我看到的最大问题是,在 Hibernate 之外访问该数据的所有内容都必须意识到这些值已被转义。我想我想知道 Hibernate 修剪值的这种行为是否正常/记录在案。
    • True - 如果代码的其他部分在 hibernate 之外访问数据库,这是一个问题。
    • 不幸的是,情况就是这样。编写了一些存储过程来批量处理读取/写入同一列的平面文件。不过谢谢。你的答案很可靠。
    【解决方案2】:

    原来问题不在于 Hibernate。我正在处理的项目设置为使用 hbm2java Ant 任务从 HBM 文件生成 Java POJO。这反过来又引用了 getters/setters/equals/toString/etc 的源模板,该模板用于修剪 setter 中的所有 java.lang.String 属性。为了解决这个问题,我钝化了我遇到问题的一个类,这样它就不会再在每个构建中生成,然后删除了 TIN 属性上的修剪。

    【讨论】:

      【解决方案3】:

      我不知道休眠。但我确实知道 Oracle 确实将空字符串视为 Null 值。并且没有任何解决方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-22
        • 1970-01-01
        • 2022-01-01
        • 2017-04-25
        • 2012-12-21
        • 2020-01-25
        • 2015-08-12
        • 2010-09-08
        相关资源
        最近更新 更多