Hibernate sur Oracle: cartographie de la Chaîne de propriété à la colonne CLOB
AVERTISSEMENT: voir ma propre réponse ci-dessous. Le problème est causé par de vieux pilotes Oracle, qui étaient présents sur le chemin de classe en plus de 10.2.0.4. Le problème est résolu. En laissant le reste de cette question pour la postérité.
J'ai été frapper ma tête contre le suivant. Voici un simple POJO distillée à partir de mon code d'application:
@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; }
}
Il y a une Chaîne de propriété et une colonne de CLOB. Lorsque le contenu est court (par exemple "hello world"), il persiste à l'amende juste. Avec des chaînes plus longues, j'obtiens l'exception suivante:
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)
Je suis en utilisant Hibernate 3.2.3 avec Oracle JDBC driver 10.2.0.4. Le message de l'exception indique que le traitement par lots peut être en faute. Alors que je peux désactiver le dosage, dans ce cas simple, j'ai besoin de l'avoir activé le "vrai" Pojo. En fait, l'état actuel des choses, à la requête de dosage est la seule raison pour laquelle nous sommes à l'utilisation d'Hibernate.
Donc, ma question est, comment puis-je faire le travail ci-dessus?
MODIFIER: observation Intéressante: la valeur de ma propriété "description" persiste juste très bien tant que c'est exactement 1333 caractères de long ou plus court. Un tel nombre impair!
EDIT 2: Dans une tentative de trouver une solution, j'ai modifié le getProperty()
annotations comme suit, qui n'a fait aucune différence:
@Lob
@Type(type="text")
@Column(name = "PIGGY_DESCRIPTION", length = Integer.MAX_VALUE)
public String getDescription() { return description; }
MODIFIER 3: Voici le DDL pour les "COCHONS":
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)) ;
Et voici l'ensemble de la pile:
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
OriginalL'auteur Max A. | 2009-10-29
Vous devez vous connecter pour publier un commentaire.
Crétin d'alerte: il s'avère que j'ai eu un rassis POT avec 9-quelque chose Oracle JDBC classes sur mon classpath. Après les avoir nettoyés, tout simplement fonctionné comme par magie avec juste les annotations suivantes:
Blâmer les gros doigts.
OriginalL'auteur Max A.
Avez-vous essayé de tomber la @Lob annotation, et juste en annotant avec @Colonne? Dans mon expérience, vous n'avez pas besoin de dire hibernate le type de colonne pour un CLOB, il permettra de déterminer sur son propre.
Pouvez-vous insérer un extrait de code client qui effectue le dosage de l'opération?
Nope, enlever le @Lob, en laissant Colonne @et @Type n'a pas aidé. J'ai annoté de la classe elle-même avec @BatchSize(taille=0) à des fins d'isolation, même si ce n'est pas un plan d'action acceptable dans l'ensemble.
@BatchSize(taille=0) truc qui n'a pas aidé non plus.
Donc l'erreur est d'être jeté sur la livraison, qu'est-ce que le minimum de l'ensemble des opérations à l'intérieur de l'transactions nécessaires pour déclencher d'erreur?
Je suis juste essayer de persister une instance de
Piggy
. Un tableau, une ligne, les deux colonnes. Il n'y a pas beaucoup à elle. C'est en fait exactement le même comportement que je vois dans la vraie application où il est, si vous voulez, une collection de beaucoup plusPiggy
-s.OriginalL'auteur Jherico