如何防止Hibernate修剪字符串?

时间:2009-03-06 19:07:53

标签: java oracle hibernate

我正在使用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,然后抛出非空约束违规。

  3. 作为参考,这是此专栏的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任务可能是String trims的来源。还在调查。

    谢谢, 杰夫

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

3 个答案:

答案 0 :(得分:4)

解决这个问题的一种方法是create a Hibernate UserType。在hibernate.org的链接中有一些指令,其中包含一些已经为String转义的类。我意识到这并没有直接回答'如何告诉hibernate不要将9个空格转换为空字符串',但它会解决数据库端的存储问题。

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

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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