用的是oracle9
有一个字段设置为vchar(4000)
hibernate 映射为: <property name="complainPosition" column="complain_position" type="string" length="4000" />
obj.set....
使用template.update(obj)
当数据str.getBytes().length >2000的时候就报错:数据大小超出此类型的最大值客户要求允许 2000个汉字,求指导。我不想用clob类型!另外附上一个问题:由于这样要求的字段有两个,都必须要2000个汉字,一个字段是问题,一个字段是解决办法。
配置文件为<property name="dealSituation" column="deal_situation" type="text" />
当我用两个同时用clob的时候,当其中一个数据str.getBytes().length =2500的时候,可以正常保存。
当两个字段同时插入str.getBytes().length =2500的汉字的时候,就报错:
ORA-01483: DATE 或 NUMBER 绑定变量的长度无效我已经疯掉了,以前用sql2000,直接在数据库里设置为text或者长度为4000的字段,都不会出现问题,
神马2000个汉字都能像我们所知道的那样正常保存。PreparedStatement对字符串的要求是不能超过2000,
可以通过stmt.setCharacterStream(1, new InputStreamReader(String内容, String内容.length());
来调整。
不过我现在是用的hibernate来保存的,虽然show_sql打印发现hibernate也是用的预处理,但我没办法调整它的长度限制
求大侠来指点迷津。。经过询,我大致知道的原因是,
有一个字段设置为vchar(4000)
hibernate 映射为: <property name="complainPosition" column="complain_position" type="string" length="4000" />
obj.set....
使用template.update(obj)
当数据str.getBytes().length >2000的时候就报错:数据大小超出此类型的最大值客户要求允许 2000个汉字,求指导。我不想用clob类型!另外附上一个问题:由于这样要求的字段有两个,都必须要2000个汉字,一个字段是问题,一个字段是解决办法。
配置文件为<property name="dealSituation" column="deal_situation" type="text" />
当我用两个同时用clob的时候,当其中一个数据str.getBytes().length =2500的时候,可以正常保存。
当两个字段同时插入str.getBytes().length =2500的汉字的时候,就报错:
ORA-01483: DATE 或 NUMBER 绑定变量的长度无效我已经疯掉了,以前用sql2000,直接在数据库里设置为text或者长度为4000的字段,都不会出现问题,
神马2000个汉字都能像我们所知道的那样正常保存。PreparedStatement对字符串的要求是不能超过2000,
可以通过stmt.setCharacterStream(1, new InputStreamReader(String内容, String内容.length());
来调整。
不过我现在是用的hibernate来保存的,虽然show_sql打印发现hibernate也是用的预处理,但我没办法调整它的长度限制
求大侠来指点迷津。。经过询,我大致知道的原因是,
可以插4000个汉字
++如果你觉得不行。。建议你改用text类型
现在不是我数据库容不下这些字。
我现在插的一段话汉字才700多,加上一次字符等,只有2500个长度。
数据长度是够的,
但问题是hibernate保存的时候出错。
是hibernate对oracle支持貌似有问题,插入超过1000个汉字都成问题
建议我用clob的,看看我下面的,
我已经做过测试了,但遇到了新问题
查看用户漫游VLR地址为00821600900017,可以正常主叫、收发短信说明用户的位置更新、国际漫游、国际长途等用户数据正常。在软交换做跟踪,发现用户做被叫时可正常取用户漫游号码,但在软交换汇接局收到IAM消息6秒后,主叫端局REL拆线,原因为“recovery on timer expiry(106)”。 经过多次测试,同时发现IAM后,有时韩国VLR会回送ACM,有时并未回送ACM,但始终表现为主叫端局REL(主叫为PSTN和手机均无法正常呼通漫游用户)。在主叫MSC指令CTRAI进行跟踪,发现起呼后要等待很长时间(约20秒以上)才能正常返回MSRN。回送MSRN后,可正常占用到软交换汇接路由设备。说明此时主叫端局已发送了IAM消息。 跟踪主叫号码返回的EOS代码为2552,含义为“手机发起的断开连接,非正常挂机”。因MSRN回送较慢,在HLR上确认用户是否有签约消息。最终确认漫游用户为VPMN用户,SK=3。所以尝试取消漫游用户的签约消息,取消OCSI、TCSI后,用户可立即正常被叫,接通率100%。同时接续速度明显提高。判断问题与VPMN流程相关。恢复用户的签约消息后,在SCP侧进行CAMEL消息跟踪,对比正常的VPMN流程,发现IDP消息有差异。7、 通过以上对比,发现异常流程中的IDP被叫用户位置信息和状态信息均未正a常提供。根据MAP PAHSE 2+的流程图,可以判断漫游地VLR未正常回送PSI_ACK消息。因为漫游地的VLR支持MAP2+版本,但又无法正常回送PSI_ACK,因此主叫端局等待20秒后超时(端局参数设置),只返回HLR中的VLR地址,被叫状态、LAI等信息均未提供。同时根据3GPP规范“5.2.1.3 Receipt of a CALL PROCEEDING message”规定:手机上发setup后启动T303;收到call proceeding后,复位T303并启动T310;收到progress或者alerting后复位T310。因此当主叫手机发起setup,并收到call proceeding,但在30秒内未收到progress或者alerting,导致T310(T310通常设置为30秒)超时。手机会自动释放呼叫。T310时长30秒,PSI消息超时用去20秒,因此用户被叫用户接续的正常时间只有10秒,用于国际长途的接续时间非常有限,因此造成了被叫接续困难的情况。最后在爱立信端局上修改PSI_ACK消息的超时门限,避免因PSI_ACK超时而花费过多接续时长。
但通过页面提交到后台,hibernate保存出错。
所以,应该不是数据库长度不足,而是hibernate有错误。原因,我在上面分析过了:
PreparedStatement对字符串的要求是不能超过2000,
可以通过stmt.setCharacterStream(1, new InputStreamReader(String内容, String内容.length());
来调整。现在用show_sql打印发现hibernate也是用的预处理,但我没办法调整它的长度限制
求大侠来指点迷津。。
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
<property name="dataSource">
<ref bean="dataSource" />
</property>
理论上是一个汉字点两个字节。
我做了一个vchar2(6)做测试,
可以保存3个汉字。
但我还是不想用jdbc来解决。
以后还有好多事情要用hibernate。
特别是遇到要存2000个汉字的问题,难道以后都不能用hibernate做保存2000汉字的问题?
所以我非常想把这个问题解决掉。
hibernate3
oracle9
两个vchar2(4000)
然后把我那段话保存试下?你们如果是正常的,请告诉 我实现方式,
如果不正常,请帮忙来一起想办法解决
1、使用setCharacterStream()方法;
2、使用OCI驱动连接Oracle数据库。另外可以试下用最新的oracle jdbc驱动
建议用CLOB,也可以试下用最新的ORACLE JDBC驱动包,有网友说可以解决问题。
至于包,我用的是ojdbc14.jar了
你考虑使用CLOB吧,不过说话Oracle中操作CLOB是最最最最恶心!没有之一
没有解决办法吗?
如果你混分就算了。
再请问各位大侠:
用hibernate,不用clob,就最多只能插666个汉字吗?
没有解决办法吗?
现在nvarchar2(4000)
我现在数据库的安装字符集是gbk,所以肯定可以存2000个汉字,
但我现在用hibernate保存报错了,这个错误hibernate的问题,具体我前面都说了。
建议你看看我前面描述的问题原因,
看你说的这么简单,希望你自已在你本机做个小例子测试,有没有问题?如果没有,请告诉我怎么做的。如果有问题,我们一起找解决。
我这个问题不在这儿问应该去哪儿问,我都百度google了几天了
nvarchar(4000)不能把 最多就2000汉字
如果不是字符串本身存在乱码导致长度不对的话,你试试在hibernate配置数据源的时候指定一下字符集,characterEncoding,呵呵,瞎猜的,没根据哦
换成10G的驱动,或者换数据库字段的类型,或者换数据库为10g,
Oracle9i的BUG,你懂得。
这些我都不可能改变的,真的是它的bug吗?没有别的办法了?
应该是这样,
以下引用网上的说明:Oracle 9i 的 varchar2 最大可存 32,767 bytes.
直接存进 varchar2 只能存 4,000 bytes,
间接存就可存到 32,767 bytes.你的 666 汉字所用的编码里 (可能是 UTF8) 每个字占了 3 bytes,
当你存的时候, 没有作好 charset-encoding 的转换,
造成你的每个 byte 被当成是 java 的一个 char (2 bytes) 来存,
总言之, 你的每个汉字要用 3x2=6 bytes 存进 oracle 中,
所以最多只能存到 4000/6=666 字.如果你的汉字每个字只用 2 bytes,
而且存的过程正确,
那摸最多就可以存到 16,000 多个字了.
其实是JDBC驱动的BUG,听说换最新版版的Oracle驱动可以解决,不过我们那项目最后是直接换的数据库,你可以试试~
我在页面写3个汉字,
在后台取的时候,用str.getByte().length的结果是 9
也就是一个汉字占3个字节。
然后,hibernate中对象的赋值obj.set...
对于字符串型 ,最大只能只能长度为2000
(注意,这个地方不能用str.length()来计算长度,而要用str.getByte().length来计算长度。)
这样的结果就是:hibernate最多能接收的汉字是666左右。这是hibernate的问题的,可能是由于连接了oracle的驱动,才会这样。因为我在sql2000数据库中没有这种问题。
另外,我这是没办法换驱动和库。
现在网运行的环境是9i和jdk4
求指导
附:我暂时按下面的方法应付了。
hibernate在增加和修改的时候,对这两个大字段set成空字符串,
后面用jdbcTemplate做更新操作
stmt.setCharacterStream(1, new InputStreamReader(String内容, String内容.length());
接收大文本应该是正解.改用Hibernate后加载大文本,那要看具体是什么数据库,在它的方言中是如何将Hibernate的类型与数据库字段类型相匹配的.
我用过Access数据库(小玩具),我看了一下Hibernate操作它的方言,它就是用:
// Access: MEMO is 65,535 characters; 2.14 GB if not binary data
registerColumnType( Types.BLOB, "memo" ); // so that's 65,535 characters in Access
registerColumnType( Types.CLOB, "memo" ); // so that's 2.14 GB in Access
这就是它的映射. 而我的实体类用的也是String.
---------------------------------
Hibernate插进来之后,应该有三家数据类型:
一家是实体类的实例字段用什么数据类型,
一家是数据库的字段用什么数据类型,
还有一家是Hibernate用的是什么数据类型.
此时,我们好像看不见sql的数据类型.
而数据库的字段类型与Hibernate的类型如何匹配,是放在方言文件中定义的!换句话说,你要想让数据库接收大文本,是不是应该找到数据库的什么类型的字段与Hibernate的CLOB匹配.找到后,通过调整数据库字段的数据类型来达到设计目的.
------------------------------
以上供参考.
<property name="hibernate.connection.SetBigStringTryClob">true</property>
String str=要插入的值;
if (str != null) {
byte[] bs = str.getBytes("UTF-8");
//用新的字符编码生成字符串
str= new String(bs, "GBK");
}else{
str="";
}
System.out.print(str);
60楼,我去试试。
61楼,我觉得可行,而且看上去可以解决我的问题,如果改成GBK的,那么一个汉字就只点两个字节了,我得试试才知道当然也期待更多的回复,能给出一个最终解决办法
以前做的,今天下午专门调出来试了一下. 大文本字段一条可存260k(没再加码试了).部分配置如下:表结构:
CREATE TABLE OA_DOCUMENT(
GID AUTOINCREMENT(1,1) PRIMARY KEY,
GHEADING VARCHAR(255),
GKEYWORD VARCHAR(255),
GCOUNTER INT,
GBUILDTIME TIMESTAMP,
GUPDATETIME TIMESTAMP,
GMATTER NOTE, //这个是大文本字段
GUSERID INT,
GLOCKUP BIT,
GCONTENT_TYPE VARCHAR(255),
GSHOWSCOPE VARCHAR(255)
);
==========================================
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/DefaultDS</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="show_sql">true</property>
<property name="hibernate.cache.user_query_cache">true</property>
<property name="hibernate.cache.use_structured_entries">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="net.sf.ehcache.configurationResourceName">ehcache.xml</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.transaction.auto_close_session">false</property>
<mapping class="gsy.document.entity.Document"/>
</session-factory>
</hibernate-configuration>中间层DAO用泛型做的,很平常.
Document 实体类中大文本字段用的是String型.
select * from nls_database_parameters; 结果中:
NLS_CHARACTERSET=ZHS16GBK
NLS_LENGTH_SEMANTICS=BYTE
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.ttc7.TTCItem.setArrayData(TTCItem.java:147)
at oracle.jdbc.dbaccess.DBDataSetImpl.setBytesBindItem(DBDataSetImpl.java:2492)
at oracle.jdbc.driver.OraclePreparedStatement.setItem(OraclePreparedStatement.java:1194)
at oracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:1614)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.setString(DelegatingPreparedStatement.java:132)
at org.hibernate.type.StringType.set(StringType.java:26)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:136)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:107)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2002)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2376)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
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.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:367)
at org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:636)
at org.springframework.orm.hibernate3.HibernateTemplate.update(HibernateTemplate.java:632)
at com.wri.hy.framework.application.framework.dao.hibernate.CommonDaoImpl.updateObj(CommonDaoImpl.java:237)
at com.wri.hy.jcssv3.app.web.knowledge.CaseController.save(CaseController.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:433)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:371)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:797)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:360)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.wri.hy.framework.util.EncodingFilter.doFilter(EncodingFilter.java:70)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
解决方法就是在Hibernate实体 该字段前加上说明@Type(type = " org.springframework.orm.hibernate3.support.ClobStringType " )
private String prdDescHtml; 当然这个是基于Spring提供的Hibernate模板来操作的
OracleDatabase db = (OracleDatabase)DataRegester.CreateDatabase();
OracleCommand commandWrapper = (OracleCommand)db.GetStoredProcCommand("NRGLB_Insert"); db.AddParameter(commandWrapper, "PNR", OracleType.Clob, entity.NR.Length, ParameterDirection.Input, true, 0, 0, "NR", DataRowVersion.Current, entity.NR);
你查看一下你的oracle9i的小版本号,是不是oracle 9i.2.3,然后换乘oracle 9i.2.4的驱动试试,也就是3版本以上的驱动包,注意是小版本号。
91和92普遍用的是92版本而92版本又分为:
9201
9204
9206
9208你换乘9204的驱动包,应该就好了。
在实体类中
在映射文件中不要写 length="4000" />public class Test{private String complainPosition;public void setComplainPosition(String s){
if(s.length()>2000)
return;
else
this.complainPosition = s;
}