Hibernate+Oracle+Clob:属性内容被切换

发布于 2024-09-08 08:29:48 字数 497 浏览 7 评论 0原文

有人听说过这个错误吗:

我有一个Java 5应用程序,它使用Hibernate 3.3.2访问Oracle数据库10g,JDBC驱动程序是Oracle light驱动程序版本10.2.0.4.0(我认为是最新版本) )。 数据库访问发生在通过 Spring 的 AOP 工具管理的事务期间。 有一张数据库表映射到一个Java实体,该映射是通过注释完成的。该实体中有两个属性在数据库中是 CLOB。它们根据 JPA 用“Lob”进行注释,并且是 Java 字符串。除非两个属性的值超过 4000 个字符,否则一切正常:提交后,值会在数据库上切换,即属性 A 包含属性 B 的值,反之亦然。

这不是玩笑!

Eclipse 调试器告诉我 Java 实体具有正确的值,直到事务关闭(我没有调试到 spring 事务处理)。 如果两个 Clob 都使用 Hibernate 注释“Type(type = "clob")”进行注释(在这种情况下,它们必须是 java.sql.Clob 类型,当然不是 String 类型),则不会发生此错误。

Has anyone heard of this error before:

I have a Java 5 application, that uses Hibernate 3.3.2 to access an Oracle Database 10g, the JDBC driver is the Oracle light driver version 10.2.0.4.0 (the most recent version, I think).
The database access happens during a transaction that is managed via the AOP-tools of spring.
There is one database table mapped to one Java entity, the mapping is done via annotations. There are two attributes in this entity that are CLOB in the database. They are annotated according to JPA with "Lob" and are Java Strings. Everthing works fine unless both attributes have values with more than 4000 characters: After the commit the values are switched on the database, that is attribute A contains the value of attribute B and vice versa.

This is not a joke!

The Eclipse debugger tells me that the Java entity has the correct values until the transaktion closes (I did not debug into the spring transaction handling).
This error does not occur if both Clobs are annotated with the Hibernate annotation 'Type(type = "clob")' (in which case they have to be of the type java.sql.Clob and not String, of course).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滿滿的愛 2024-09-15 08:29:48

我不是 100% 确定,但您可以尝试将连接属性 SetBigStringTryClob 设置为 true (请参阅 如何在 JDBC 中轻松处理 CLOB?)。

如果你使用Spring,像这样:

<property name="hibernateProperties">
  <props>
    <prop key="hibernate.connection.SetBigStringTryClob">true</prop>
  </props>
</property>

I'm not 100% sure but could you try to set the connection property SetBigStringTryClob to true (see How To Handle CLOBs Easily in JDBC?).

If you are using Spring, something like this:

<property name="hibernateProperties">
  <props>
    <prop key="hibernate.connection.SetBigStringTryClob">true</prop>
  </props>
</property>
女皇必胜 2024-09-15 08:29:48

同时我找到了问题的解决方案:SQL方言错误,有人将其设置为Oracle9而不是正确的版本,即:

name =“hibernate.dialect”value =“org.hibernate.dialect.Oracle10gDialect”

设置正确的 SQL 方言可以解决问题:-)

Meanwhile I found a solution to the problem: The SQL-dialect was wrong, someone set it to Oracle9 instead of the correct version, which is this:

name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"

Setting the correct SQL-dialect solves the problem :-)

没企图 2024-09-15 08:29:48

我有完全相同的问题。一张桌子上有两个 CLOB。在插入件上只设置了一个,一切都很好。在更新时,我设置了第二个,提交后表上的值被交换。两者均包含 4000 多个字符。已调试,bean 上的值是正确的。
可悲的是,我的属性中已经有 org.hibernate.dialect.Oracle10gDialect 了。
(Hibernate 版本 4.2.2.Final)

//更新
目前作为一种解决方法,我在 JPA 注释中将第一列设置为 updatable=false ,以便在 hibernate 生成更新查询期间现在只有一个 CLOB 列。我可以这样做,因为在这种特殊情况下,我不需要在插入后更改值,但这不是通用的解决方案。

I have exactly the same problem. Two CLOB on a table. On the insert only one is set and everything is fine. On the update I set the second one and after commit the values on table are swapped. Both contains more than 4000 characters. Debugged and the values on the bean are correct.
The sad thing is that i have already org.hibernate.dialect.Oracle10gDialect in my properties.
(Hibernate version 4.2.2.Final)

//UPDATE
for the moment as a workaround I have set the first column as updatable=false in the JPA annotation so that during the generation of the update query by hibernate there is only one CLOB column now. I can do this as that in this particular case I don't need to change the value after the insert, but it's not a general solution.

匿名的好友 2024-09-15 08:29:48

唯一对我们有用的是使用 hql 查询进行更新。每个查询更新一个 CLOB(因此我们需要两个单独的查询):

Query query = em.createQuery("update SomeTable as someTable set value = :value where id = :id");
query.setParameter("value", value);
query.setParameter("id", id);
if (query.executeUpdate() != 1) {
    throw new Exception("Value update had no effect");
}

The only thing that worked for us was to use hql queries for the update. Each query updated a single CLOB (so we needed two separate queries):

Query query = em.createQuery("update SomeTable as someTable set value = :value where id = :id");
query.setParameter("value", value);
query.setParameter("id", id);
if (query.executeUpdate() != 1) {
    throw new Exception("Value update had no effect");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文