2013-08-29 48 views
2

我試圖堅持圖像Byte[]和調度TimerHandle使用JPA(EclipseLink的2.3.x版本)無法使用JPA

當屬性值不爲空,JPA是甲骨文11g數據庫堅持零到Oracle BLOB能夠將Byte []/TimerHandle持久化到數據庫,但是當這些屬性爲null時,它會發出此異常。

Caused by: java.lang.ClassCastException: oracle.sql.BLOB incompatible with oracle.sql.BLOB 
    at oracle.jdbc.driver.OraclePreparedStatement.setBlob(OraclePreparedStatement.java:6663) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setBlob(OraclePreparedStatementWrapper.java:128) 
    at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.setBlob(DelegatingPreparedStatement.java:387) 
    at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingPreparedStatement.setBlob(LoggingConnectionDecorator.java:1499) 
    at org.apache.openjpa.lib.jdbc.DelegatingPreparedStatement.setBlob(DelegatingPreparedStatement.java:387) 
    at org.apache.openjpa.jdbc.sql.OracleDictionary.setNull(OracleDictionary.java:633) 
    at org.apache.openjpa.jdbc.sql.DBDictionary.setTyped(DBDictionary.java:1285) 
    at org.apache.openjpa.jdbc.sql.RowImpl.flush(RowImpl.java:896) 
    at org.apache.openjpa.jdbc.sql.RowImpl.flush(RowImpl.java:856) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:117) 
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.batchOrExecuteRow(BatchingPreparedStatementManagerImpl.java:99) 
    at org.apache.openjpa.jdbc.kernel.BatchingPreparedStatementManagerImpl.flushAndUpdate(BatchingPreparedStatementManagerImpl.java:83) 
    at com.ibm.ws.persistence.jdbc.kernel.PreparedStatementManagerImpl.flushAndUpdate(PreparedStatementManagerImpl.java:63) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flushInternal(PreparedStatementManagerImpl.java:100) 
    at org.apache.openjpa.jdbc.kernel.PreparedStatementManagerImpl.flush(PreparedStatementManagerImpl.java:88) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:550) 
    at org.apache.openjpa.jdbc.kernel.ConstraintUpdateManager.flush(ConstraintUpdateManager.java:106) 
    at org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager.flush(BatchingConstraintUpdateManager.java:59) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:105) 
    at org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:78) 
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:737) 
    at org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:131) 
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2178) 
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:2076) 
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1847) 
    ... 70 more 

我怎樣才能解決這個問題,使null可以在數據庫中保存到數據庫(空)?

+0

奇怪的是,它說這個問題是一個'ClassCastException'。這是說同一個班級與自己不相容! – user919860

+0

@ user919860是,[其他交](http://stackoverflow.com/questions/11411306/java-lang-classcastexception-oracle-sql-blob-cannot-be-cast-to-oracle-sql-blob)建議同班同學在課程路徑中出現了兩次,一次是由服務器類路徑提供,另一次是由您自己提供。但是這應該導致問題總是存在,不僅是空的。我沒有檢查類路徑,也沒有發現任何有用的東西。 – kftse

回答

0

我找到了部分解決方案... 使用純oracle.sql.BLOB,而不是有這個問題,當映射到BLOB任何其他類。

@Entity 
public class FileStorage implements Serializable { 
    @Id 
    private Long fileId; 
    @Lob 
    //private byte[] fileData; replaced this line with the line below. 
    private oracle.sql.BLOB fileData; 
    //Getter and setter 
} 

public class WorkingClass{ 
    private EntityManager em; 
    public foo(){ 
     FileStorage f = new FileStorage(); 
     f.setFileData(BLOB.getEmptyBLOB()); 
     //f.getFileData().setBytes(someByteArrayData); 
     em.persist(f); 
    } 
} 

public class ErrorClass{ 
    private EntityManager em; 
    public foo(){ 
     FileStorage f = new FileStorage(); 
     f.setFileData(); 
     //fail when the line below is commented 
     //f.setFileData(someByteArrayData); 
     em.persist(f); 
    } 
} 

但現在的問題困擾TimerHandle。使用ObjectOutputStream/ObjectInputStream手動序列化和反序列化之後,定時器似乎不正確串行化,導致NoSuchObjectLocalException我打電話時((TimerHandle) o).getTimer()即使我確認定時器仍在運行(調用@Timeout方法,其不斷輸出的消息)。