Oracle上的Hibernate:将String属性映射到CLOB列 [英] Hibernate on Oracle: mapping String property to CLOB column

查看:88
本文介绍了Oracle上的Hibernate:将String属性映射到CLOB列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

警告:请在下方查看我自己的回答。除10.2.0.4之外,该问题是由类路径中存在的旧Oracle驱动程序引起的。问题解决了。留下这个问题的其余部分留给后人。



我一直在抨击以下几点。这是一个简单的POJO,它是从我的应用程序代码中提取的: b $ b public class Piggy {
private long id;
私有字符串描述;
$ b public Piggy(){}

@Id
@GeneratedValue
@Column(name =PIGGY_ID)
public Long getId (){return id; }
public void setId(Long id){this.id = id; }

@Lob
@Column(name =PIGGY_DESCRIPTION)
public String getDescription(){return description; }
public void setDescription(String d){description = d; }
}

有一个String属性和一个CLOB列。当内容很短时(例如hello world),它仍然很好。对于较长的字符串,我得到以下异常:

  java.sql.SQLException:操作不允许:streams类型不能用于通过oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
在oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
处的oracle批处理
。 jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:4236)
at org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
at org.apache.commons.dbcp。 DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
在org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:31)
在org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister。 java:2403)

我使用Hibernate 3.2.3和Oracle JDBC驱动程序10.2.0.4。例外消息表明配料可能存在问题。虽然我可以在这种简单的情况下禁用批处理,但我需要启用真正POJO。事实上,就目前而言,查询批处理是我们使用Hibernate的唯一原因。



所以,我的问题是,我怎么才能使上述work?



编辑:有趣的观察:只要字符长度不超过1333个字符,我的description 。这样一个奇数!

编辑2 :为了找到解决方案,我修改了 getProperty()


$ b

  @Lob 
@Type(类型=text)
@Column(name =PIGGY_DESCRIPTION,length = Integer.MAX_VALUE)
public String getDescription(){return description; }

编辑3 :这里是PIGGIES的DDL: p>

  CREATE TABLEPIGGIES
(PIGGY_IDNUMBER NOT NULL ENABLE,
PIGGY_DESCRIPTIONCLOB,
的约束 PIGGIES_PK 主键( PIGGY_ID)
使用INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
储存(INITIAL 1048576 NEXT 1048576个MINEXTENTS 1个MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACEBBDATAENABLE
)PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
存储(初始1048576下一个1048576矿井1大小2147483645
PCTINCREASE 0自由空间1 FREELIST GROUPS 1个BUFFER_POOL DEFAULT)
TABLESPACE BBDATA
LOB( PIGGY_DESCRIPTION)存储为 SYS_LOB0000177753C00002 $$(
TABLESPACE BBDATA ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
NOCACHE
储存(初始1048576下一个1048576矿业1大写2147483645
PCTINC REASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT));

以下是整个堆栈:

 org.hibernate.exception.GenericJDBCException:无法更新:[com.bamnetworks.cms.types.Piggy#934] 
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter .java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
。在在org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)
。在组织。 hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
处org.hibernate.engine.ActionQueue org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
。在org下执行(ActionQueue.java:248)
。 hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
在org.hibernate.event.def.AbstractFlushingEventListener。 (org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java: 1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
导致:java.sql.SQLException:操作不允许:streams类型不能用于批处理
处oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess。 DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:4236)
at org.apache.commons。 dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
在org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
在org.hibernate.jdbc.BatchingBatcher.addToBatch( BatchingBatcher.java:31)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
... 45 more


解决方案

Moron警报:事实证明,我的classpath上有9个Oracle JDBC类的过时JAR。清理完成后,所有内容都可以通过以下注解神奇地发挥作用:

  @Lob 
@Column(name = PIGGY_DESCRIPTION)
public String getDescription(){return description; }

指责胖手指。


WARNING: see my own answer below. The problem is caused by old Oracle drivers that were present on the classpath in addition to 10.2.0.4. Problem solved. Leaving the rest of this question for posterity.

I've been banging my head against the following. Here's a simple POJO distilled from my application code:

@Entity
@Table(name = "PIGGIES")
public class Piggy {    
    private Long id;
    private String description;

    public Piggy() {}

    @Id
    @GeneratedValue
    @Column(name = "PIGGY_ID")
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    @Lob
    @Column(name = "PIGGY_DESCRIPTION")
    public String getDescription() { return description; }
    public void setDescription(String d) { description = d; }
}

There's a String property and a CLOB column. When the contents are short (e.g. "hello world"), it persists just fine. With longer strings, I get the following exception:

java.sql.SQLException: operation not allowed: streams type cannot be used in batching
        at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
        at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
        at oracle.jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:4236)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
        at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:31)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)

I'm using Hibernate 3.2.3 with Oracle JDBC driver 10.2.0.4. The exception's message indicates that batching may be at fault. While I can disable batching in this simple case, I need to have it enabled for the "real" POJOs. In fact, as things stand right now, query batching is the only reason we're using Hibernate at all.

So, my question is, how can I make the above work?

EDIT: Interesting observation: the value of my "description" property persists just fine as long as it's exactly 1333 characters long or shorter. Such an odd number!

EDIT 2: In an attempt to find a solution, I modified the getProperty() annotations as follows, which has made no difference:

@Lob
@Type(type="text")
@Column(name = "PIGGY_DESCRIPTION", length = Integer.MAX_VALUE)
public String getDescription() { return description; }

EDIT 3: Here's the DDL for "PIGGIES":

CREATE TABLE "PIGGIES" 
 (  "PIGGY_ID" NUMBER NOT NULL ENABLE, 
"PIGGY_DESCRIPTION" CLOB, 
 CONSTRAINT "PIGGIES_PK" PRIMARY KEY ("PIGGY_ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "BBDATA"  ENABLE
 ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "BBDATA" 
LOB ("PIGGY_DESCRIPTION") STORE AS "SYS_LOB0000177753C00002$$"(
TABLESPACE "BBDATA" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
NOCACHE 
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) ;

And here's the entire stack:

org.hibernate.exception.GenericJDBCException: could not update: [com.bamnetworks.cms.types.Piggy#934]
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
Caused by: java.sql.SQLException: operation not allowed: streams type cannot be used in batching
    at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
    at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
    at oracle.jdbc.driver.OraclePreparedStatement.addBatch(OraclePreparedStatement.java:4236)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:172)
    at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:31)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
    ... 45 more

解决方案

Moron alert: it turns out that I had a stale JAR with 9-something Oracle JDBC classes on my classpath. Having cleaned that up, everything simply worked magically with just the following annotations:

@Lob
@Column(name = "PIGGY_DESCRIPTION")
public String getDescription() { return description; }

Blame the fat fingers.

这篇关于Oracle上的Hibernate:将String属性映射到CLOB列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆