Спящий режим > CLOB > Oracle :(
Вопрос
Я пытаюсь записать в поле Clob Oracle значение длиной более 4000 символов.Кажется, это распространенная проблема, но ни одно из решений не работает.Поэтому я молюсь о помощи отсюда.
Вниз и грязная информация:
Использование Oracle 9.2.0.8.0
Hibernate3 реализует pojo с аннотациями
Томкэт 6.0.16
Драйверы Oracle 10.2.x
Поставщик пула соединений C3P0
В моем файле persistence.xml у меня есть:
<persistence-unit name="DWEB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.connection.password" value="###" />
<property name="hibernate.connection.username" value="###" />
<property name="hibernate.default_schema" value="schema" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="300" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test_period" value="3000" />
<property name="show_sql" value="true" />
<property name="format_sql" value="true" />
<property name="use_sql_comments" value="true" />
<property name="SetBigStringTryClob" value="true"/>
<property name="hibernate.jdbc.batch_size" value="0"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@server.ss.com:1521:DDD"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
</properties>
</persistence-unit>
Геттер и сеттер выглядят так:
@Lob
@Column(name="COMMENT_DOC")
public String getDocument(){
return get("Document");
}
public void setDocument(String s){
put("Document",s);
}
Исключение, которое я получаю:
SEVERE: Servlet.service() for servlet SW threw exception
java.sql.SQLException: Io exception: Software caused connection abort: socket write error
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:334)
at oracle.jdbc.ttc7.TTC7Protocol.handleIOException(TTC7Protocol.java:3678)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1999)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1144)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2152)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:2035)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2876)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:609)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2275)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
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:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
at org.sw.website.actions.content.AddComment.performAction(AddComment.java:60)
...
Если мне нужно предоставить дополнительную информацию, пожалуйста, спрашивайте.Все работает до тех пор, пока не будет превышен страшный предел.
Решение
Спасибо Non sequitor за помощь.У меня это работает, и я помещу все детали сюда для дальнейшего использования.Несмотря на все заявления об обновлении драйверов и том, что все будет работать, у меня ничего не получилось.В конце концов мне пришлось реализовать «org.hibernate.usertype.UserType», я назвал его так же, как и все примеры в Интернете StringClobType.За исключением некоторого импорта, я использовал пример из Использование Clobs/Blobs с Oracle и Hibernate.Насколько я понимаю, игнорируйте утверждение «остерегайтесь».
Чтобы заставить слияния работать, мне пришлось внести одно изменение.Некоторые методы не были реализованы в предоставленном примере кода.Eclipse исправил это для меня, заглушив их.Круто, но метод replace должен быть действительно реализован, иначе все слияния перезапишут данные нулевым значением.Вот моя реализация:
public Object replace(Object newValue, Object existingValue, Object arg2)throws HibernateException {
return newValue;
}
Я не буду дублировать здесь реализацию класса. Чтобы увидеть ее, перейдите по ссылке выше.Я использовал код в третьем сером поле.Затем в верхней части класса pojo, который я хотел использовать, я добавил следующее после импорта
...
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDefs;
import org.hibernate.annotations.TypeDef;
@TypeDefs({
@TypeDef(
name="clob",
typeClass = foo.StringClobType.class
)
})
@Entity
@Table(name="EA_COMMENTS")
public class Comment extends SWDataObject implements JSONString, Serializable {
...
}
Затем, чтобы использовать новый UserType, я добавил аннотацию к своему геттеру:
@Type(type="clob")
@Column(name="COMMENT_DOC")
public String getDocument(){
return get("Document");
}
Мне не нужна была аннотация @Lob.
В моем файле persistence.xml объявление единицы персистентности выглядело так:
<persistence-unit name="###" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.connection.password" value="###" />
<property name="hibernate.connection.username" value="###" />
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@server.something.com:1521:###"/>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver"/>
<property name="hibernate.default_schema" value="###" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect" />
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="100" />
<property name="hibernate.c3p0.timeout" value="300" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test period" value="3000" />
<property name="hibernate.c3p0.idle_connection_test_period" value="300" />
<property name="show_sql" value="false" />
<property name="format_sql" value="false" />
<property name="use_sql_comments" value="false" />
<property name="hibernate.jdbc.batch_size" value="0"/>
</properties>
</persistence-unit>
SetBigStringTryClob у меня никогда не работал и не требовался для этой окончательной реализации.
Мой урок заключается в том, что, в конце концов, лучше присоединиться, чем сражаться.Это сэкономило бы мне три дня.
Другие советы
Я думаю, ваша проблема может заключаться в том, что вы используете Оракул 9i но диалект Hibernate 10 г.Убедитесь, что ваш драйвер, версия базы данных и диалект синхронизированы, поскольку существует также диалект 9i. org.hibernate.dialect.Oracle9iDialect
Должен быть:
<property name="hibernate.connection.SetBigStringTryClob">true</property>
<property name="hibernate.jdbc.batch_size">0</property>
И не:
<property name="SetBigStringTryClob">true</property>
И используйте правильный диалект для вашей базы данных (org.hibernate.dialect.Oracle9iDialect
).
Также убедитесь, что вы используете последнюю версию Тонкий драйвер Oracle 10g Release 2 (10.2.0.4) или новее.