Java Oracle 上的 Hibernate:将 String 属性映射到 CLOB 列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1644559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate on Oracle: mapping String property to CLOB column
提问by Max A.
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.
警告:请参阅下面我自己的答案。该问题是由除 10.2.0.4 之外的类路径中存在的旧 Oracle 驱动程序引起的。问题解决了。把这个问题的其余部分留给后代。
I've been banging my head against the following. Here's a simple POJO distilled from my application code:
我一直在反对以下内容。这是从我的应用程序代码中提取的一个简单的 POJO:
@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:
有一个 String 属性和一个 CLOB 列。当内容很短时(例如“hello world”),它会一直存在。对于更长的字符串,我得到以下异常:
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.
我将 Hibernate 3.2.3 与 Oracle JDBC 驱动程序 10.2.0.4 一起使用。异常消息表明批处理可能有问题。虽然我可以在这种简单的情况下禁用批处理,但我需要为“真正的”POJO 启用它。事实上,就目前的情况而言,查询批处理是我们使用 Hibernate 的唯一原因。
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!
编辑:有趣的观察:只要长度正好是 1333 个字符,我的“描述”属性的值就会一直存在。这么奇葩的数字!
EDIT 2: In an attempt to find a solution, I modified the getProperty()
annotations as follows, which has made no difference:
编辑 2:为了找到解决方案,我修改了getProperty()
注释如下,这没有什么区别:
@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":
编辑 3:这是“PIGGIES”的 DDL:
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
采纳答案by Max A.
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:
白痴警报:事实证明,我的类路径上有一个陈旧的 JAR,其中包含 9 个 Oracle JDBC 类。清理干净后,一切都只是神奇地工作,只需以下注释:
@Lob
@Column(name = "PIGGY_DESCRIPTION")
public String getDescription() { return description; }
Blame the fat fingers.
怪胖手指。
回答by Jherico
Have you tried dropping the @Lob
annotation, and just annotating it with @Column
? In my experience, you don't need to tell hibernate the column type for a CLOB, it will determine it on its own.
你有没有试过删除@Lob
注释,只是用 注释它@Column
?根据我的经验,您不需要告诉休眠 CLOB 的列类型,它会自行确定。
Can you include a snippet of the client code which is performing the batching operation?
您能否包含一段正在执行批处理操作的客户端代码?