从 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>
我们正处于将一些应用程序迁移到 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>