从 JPA 1.0 迁移到 JPA 2.0 后存储图像 BLOB

Storing an image BLOB after migrating from JPA 1.0 to JPA 2.0

我们正处于将一些应用程序迁移到 WAS liberty 配置文件的迁移过程中,该应用程序使用的是 open jpa 版本 1 和 java 6,并且代码工作正常,我们决定迁移到 JPA 2.0,和 java 版本 8,因为它是在 apache open jpa 中实现的,以避免迁移问题,现在应用程序无法在 oracle DB 中保存图片,它作为 blob 数据类型存储在 table,我们能够正确地从数据库中检索图像,但由于在提交存储图像查询时出现以下错误,我们无法将任何图像存储在数据库中。我注意到它未能获得 blob 数据类型字段的占位符。

字段声明:

@Lob
@Column(name="FORM" ,columnDefinition="BLOB" ,  nullable=true )
private byte[] form;

存储交易

  @Action(Action.ACTION_TYPE.CREATE)
public void createTransaction(final Transaction transaction) throws Exception {
    EntityManager em = getEntityManager();
    try {
        em.getTransaction().begin();
        em.persist(transaction);
        em.getTransaction().commit();
    } catch (Exception ex) {
        try {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
        } catch (Exception e) {
            ex.printStackTrace();
            throw e;
        }
        throw ex;
    } finally {
        em.close();
        this.emf.close();
        this.emf = null;
    }
}

JPA项目设置: 平台:通用 2.0,JPA 实现:目标运行时提供的库。

异常堆栈跟踪:

       [err] <openjpa-2.2.3-SNAPSHOT-r422266:1802153 fatal store error> org.apache.openjpa.persistence.RollbackException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
[err]   at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:594)
[err]   at com.test.hace.sfp.dao.entities.controller.TransactionManager.createTransaction(TransactionManager.java:92)
[err]   at com.test.hace.sfp.services.process.impl.TransactionServiceImpl.submitNewTransactionToApproval(TransactionServiceImpl.java:115)
[err]   at pagecode.pages.branch.initiator.NewTransactionStep2.doSubmitAction(NewTransactionStep2.java:229)
[err]   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[err]   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[err]   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[err]   at java.lang.reflect.Method.invoke(Method.java:497)
[err]   at org.apache.el.parser.AstValue.invoke(AstValue.java:245)
[err]   at [internal classes]
[err]   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[err]   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[err]   at java.lang.Thread.run(Thread.java:745)
[err] Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1802153 fatal general error> org.apache.openjpa.persistence.PersistenceException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
[err]   at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2352)
[err]   at [internal classes]
[err]   ... 45 more
[err] Caused by: <openjpa-2.2.3-SNAPSHOT-r422266:1802153 fatal general error> org.apache.openjpa.persistence.PersistenceException: oracle.sql.BLOB
[err]   at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4998)
[err]   at [internal classes]
[err]   ... 52 more
[err] Caused by: java.sql.SQLException: oracle.sql.BLOB
[err]   at org.apache.openjpa.jdbc.sql.OracleDictionary.getEmptyBlob(OracleDictionary.java:1249)
[err]   at [internal classes]
[err]   ... 59 more

对于某些操作(特别是涉及 LOB),JPA 提供程序(OpenJPA、Eclipselink)将要求 JDBC 类 可由应用程序的类加载器(更具体地说,线程上下文类加载器,这是应用程序类加载器)。

问题是 JNDI 查找解析的 javax.sql.DataSource 不会自动将那些 JDBC 类 添加到应用程序类加载器(你真的不想污染一个毕竟,应用程序的 ClassLoader 带有不必要的库。)

但是,如果您将 JDBC 库作为共享库添加到您的应用程序的定义中,并将您的应用程序条目添加到 server.xml,那么它将起作用。

例如:

    <jdbcDriver id="Derby" libraryRef="JDBCLib"/>
    <library filesetRef="DerbyFileset" id="JDBCLib"/>
    <fileset dir="/derby/lib" id="DerbyFileset"/>

    <dataSource id="jdbc/JPA_DS"
                    jndiName="jdbc/JPA_DS"
                    jdbcDriverRef="Derby"
                    isolationLevel="TRANSACTION_READ_COMMITTED">
                    <properties.derby.client 
                        databaseName="TestDB"
                        serverName="localhost" 
                        portNumber="1527"/>
    </dataSource>

    <application type="ear" id="entity10"         name="Entity10"
       location="${fvt.home}/testbuckets/jpaspec-1.0/Entity/Entity10.ear">
       <classloader commonLibraryRef="JDBCLib" />
    </application>