2

JPA (EclipseLink 2.3.x) を使用して、イメージByte[]とスケジューラを Oracle 11g データベースに保持しようとしています。TimerHandle

プロパティの値が null でない場合、JPA は 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データベースで (null) としてデータベースに永続化できるように、この問題を修正するにはどうすればよいですか?

4

1 に答える 1

0

部分的な解決策を見つけました... この問題が発生した場合は、BLOB にマップされた他のクラスではなく、プレーンな oracle.sql.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 メソッドを呼び出す)。

于 2013-09-01T11:52:39.453 に答える