2009-10-29 59 views
9

CẢNH BÁO: xem câu trả lời của riêng tôi bên dưới. Vấn đề là do trình điều khiển cũ của Oracle đã có mặt trên classpath ngoài 10.2.0.4. Đã giải quyết được sự cố. Để phần còn lại của câu hỏi này cho hậu thế.Hibernate trên Oracle: ánh xạ thuộc tính String vào cột CLOB

Tôi đã đập đầu vào những điều sau đây. Dưới đây là một POJO đơn giản được chưng cất từ ​​mã ứng dụng của tôi:

@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; } 
} 

Có một thuộc tính String và cột CLOB. Khi nội dung ngắn (ví dụ: "hello world"), nội dung vẫn ổn định. Với các chuỗi dài hơn, tôi nhận được ngoại lệ sau:

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) 

Tôi đang sử dụng Hibernate 3.2.3 với trình điều khiển JDBC Oracle 10.2.0.4. Thông báo của ngoại lệ cho biết rằng việc tạo nhóm có thể bị lỗi. Mặc dù tôi có thể vô hiệu hóa việc tạo nhóm trong trường hợp đơn giản này, nhưng tôi cần phải bật tính năng này cho các POJO "thực". Trong thực tế, như mọi thứ đứng ngay bây giờ, truy vấn batching là lý do duy nhất chúng tôi đang sử dụng Hibernate ở tất cả.

Vì vậy, câu hỏi của tôi là, làm cách nào tôi có thể thực hiện công việc trên?

EDIT: Quan sát thú vị: giá trị của thuộc tính "mô tả" của tôi vẫn tiếp tục tốt miễn là dài 1333 ký tự hoặc ngắn hơn. Một số lẻ như vậy!

EDIT 2: Trong một nỗ lực để tìm một giải pháp, tôi sửa đổi getProperty() chú thích như sau, trong đó đã có sự khác biệt:

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

EDIT 3: Đây là DDL cho "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)) ; 

Và đây là toàn bộ 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 

Trả lời

23

Cảnh báo Moron: nó chỉ ra rằng tôi đã có một JAR cũ với 9-một cái gì đó Oracle JDBC lớp học trên classpath của tôi. Sau khi làm sạch mà lên, tất cả mọi thứ chỉ đơn giản là làm việc một cách kỳ diệu chỉ với các chú thích như sau:

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

Đổ lỗi cho các ngón tay của chất béo.

4

Bạn đã thử thả chú thích @Lob và chỉ chú thích nó bằng @Column? Theo kinh nghiệm của tôi, bạn không cần phải nói hibernate kiểu cột cho một CLOB, nó sẽ tự xác định nó.

Bạn có thể bao gồm một đoạn mã khách hàng đang thực hiện thao tác theo đợt không?

+0

Tôi đang thử đề xuất của bạn, chúng tôi sẽ tìm hiểu sau vài phút nữa. Liên quan đến đợt, không có gì trong mã của riêng tôi mà thực hiện theo đợt. Đó là một tính năng Hibernate tích hợp. Có chú thích @BatchSize mà chúng tôi sử dụng trên các liên kết trong ứng dụng. Nếu bạn nhìn vào dấu vết stack trong câu hỏi của tôi, bạn có thể thấy tất cả các cuộc gọi batching mà Hibernate đi qua. –

+0

Không, xóa @Lob và chỉ rời khỏi @Column và @Type không giúp được gì. Tôi đã chú thích chính lớp đó bằng @BatchSize (size = 0) cho các mục đích cách ly mặc dù nó không phải là một hành động chấp nhận được tổng thể. –

+0

Mẹo @BatchSize (size = 0) cũng không giúp ích gì. –

Các vấn đề liên quan