我一直在試圖給我們JPA堅持在一個簡單的保險絲ESB項目的實體,但我面對的是實體永遠不會被寫入到底層數據庫的問題。該項目的結構具有以下三個模塊:保險絲ESB JPA實體不堅持
簡單數據源
簡單模型
簡單服務
數據源通過藍圖配置和數據源連接到JNDI:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="simpleDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVICE_NAME=xyz))(ADDRESS=(PROTOCOL=TCP)(HOST=xx.xx.xx.xx)(PORT=1521)))" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<service ref="simpleDataSource" interface="javax.sql.DataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/simpleDataSource" />
</service-properties>
</service>
該模型定義的持久單元persistence.xml文件和參考文獻內的數據源通過JNDI:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="2.0">
<persistence-unit name="simple-service-persistence-unit" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>osgi.jndi.service.name=jdbc/simpleDataSource</jta-data-source>
<!-- list of the persistance classes -->
<class>com.model.SimpleRow</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
的SimpleRow類使用JPA註釋:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "SIMPLE")
public class SimpleRow {
@Column(name = "simple_id")
private Long simpleId;
@Column(name = "simple_text", length =100)
private String simpleText;
public Long getSimpleId() {
return simpleId;
}
public void setSimpleId(Long simpleId) {
this.simpleId = simpleId;
}
public String getSimpleText() {
return simpleText;
}
public void setSimpleText(String simpleText) {
this.simpleText = simpleText;
}
}
我然後注入的EntityManager到服務,再次使用藍圖和簡單的服務的持久性單元的參考,並指定方法級噸ransaction劃界應使用(正如我在所有的例子見過):
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.1.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://aries.apache.org/xmlns/jpa/v1.1.0 http://aries.apache.org/schemas/jpa/jpa_110.xsd">
<bean id="simpleService" class="com.service.SimpleServiceImpl">
<jpa:context property="entityManager" unitname="simple-service-persistence-unit" />
<tx:transaction method="*" value="Required" />
</bean>
<service ref="simpleService" interface="com.service.SimpleService" />
簡單服務中簡單的創建一個實體,並使用EntityManager如下依舊它:
public class SimpleServiceImpl implements SimpleService {
EntityManager entityManager;
public void invokeSimpleService() {
try {
SimpleRow row = new SimpleRow();
row.setSimpleText("Some simple text");
entityManager.persist(row);
System.out.println("Persisted row...");
} catch (Exception e) {
System.out.println("An error occurred: " + e.getMessage());
}
} ...
相關的一個最終配置是如下的特徵集合:
<feature dependency="true" version="${activemq.version}">activemq-camel</feature>
<feature dependency="true" version="${camel.version}">camel-blueprint</feature>
<feature dependency="true" version="${camel.version}">camel-core</feature>
<feature dependency="true" version="${cxf.version}">cxf</feature>
<feature dependency="true" version="${camel.version}">camel-cxf</feature>
<feature dependency="true" version="${camel.version}">camel-jpa</feature>
<feature dependency="true" version="1.0.1.fuse-71-047">transaction</feature>
<feature dependency="true" version="${jpa.version}">jpa</feature>
<feature dependency="true" version="${jndi.version}">jndi</feature>
<bundle>wrap:mvn:net.sourceforge.serp/serp/1.13.1</bundle>
<bundle>wrap:mvn:oracle/ojdbc/11.2.0.3</bundle>
<bundle>mvn:com.h2database/h2/1.3.167</bundle>
<bundle>mvn:commons-dbcp/commons-dbcp/1.4</bundle>
<bundle>mvn:org.apache.commons/commons-lang3/3.1</bundle>
<bundle>mvn:com.company/simple-datasource/${project.version}</bundle>
<bundle>mvn:com.company/simple-model/${project.version}</bundle>
<bundle>mvn:com.company/simple-service/${project.version}</bundle>
我已經驗證了數據源通過注射它作爲服務入以直JDBC連接使用它的另一個模塊正常工作。
然而,調用SimpleService.invokeSimpleService,代碼執行時,沒有異常拋出,但寫不保留在數據庫上。
如果我添加一個沖洗一直存在,即
entityManager.persist()
之後再拋出以下錯誤:
An error occurred: Can only perform operation while a transaction is active.
如果我嘗試和明確啓動事務,並刪除TX:交易註解在服務bean配置,然後它失敗並出現以下錯誤:
An error occurred: Transaction management is not available for container managed EntityManagers.
其他inf這可能是相關的。底層的EntityManager實現:
org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager
還安裝白羊座的組件列表是:
[ 7] [Active ] [Created ] [ ] [ 20] Apache Aries Blueprint Core (1.0.1.fuse-71-047)
[ 9] [Active ] [ ] [ ] [ 20] Apache Aries Util (1.0.0)
[ 10] [Active ] [Created ] [ ] [ 20] Apache Aries Blueprint CM (1.0.1.fuse-71-047)
[ 11] [Active ] [ ] [ ] [ 20] Apache Aries Proxy API (1.0.0)
[ 12] [Active ] [ ] [ ] [ 20] Apache Aries Proxy Service (1.0.0)
[ 13] [Active ] [ ] [ ] [ 20] Apache Aries Blueprint API (1.0.1.fuse-71-047)
[ 25] [Active ] [ ] [ ] [ 30] Apache Aries JMX Blueprint API (1.0.1.fuse-71-047)
[ 30] [Active ] [ ] [ ] [ 30] Apache Aries JMX Blueprint Core (1.0.1.fuse-71-047)
[ 33] [Active ] [ ] [ ] [ 30] Apache Aries JMX API (1.0.1.fuse-71-047)
[ 38] [Active ] [ ] [ ] [ 30] Apache Aries JMX Core (1.0.1.fuse-71-047)
[ 75] [Active ] [ ] [ ] [ 60] Aries JPA Container Managed Contexts (1.0.0)
[ 77] [Active ] [Created ] [ ] [ 60] Apache Aries Transaction Enlisting JDBC Datasource (1.0.1.fuse-71-047)
[ 81] [Active ] [ ] [ ] [ 60] Aries JPA Container API (1.0.0)
[ 100] [Active ] [Created ] [ ] [ 60] Apache Aries Transaction Blueprint (1.0.1.fuse-71-047)
[ 118] [Active ] [ ] [ ] [ 60] Apache Aries JNDI API (1.0.0)
[ 125] [Active ] [ ] [ ] [ 60] Aries JPA Container (1.0.0)
[ 139] [Active ] [ ] [ ] [ 60] Apache Aries JNDI Core (1.0.0)
[ 144] [Active ] [ ] [ ] [ 60] Apache Aries JNDI Support for Legacy Runtimes (1.0.0)
[ 146] [Active ] [ ] [ ] [ 60] Apache Aries JNDI RMI Handler (1.0.0)
[ 168] [Active ] [Created ] [ ] [ 60] Aries JPA Container blueprint integration for Aries blueprint (1.0.0)
[ 176] [Active ] [ ] [ ] [ 60] Apache Aries Transaction Manager (1.0.1.fuse-71-047)
[ 177] [Active ] [ ] [ ] [ 60] Apache Aries JNDI URL Handler (1.0.0)
有什麼明顯錯誤此配置,它遵循大多數在線的例子?
我懷疑的原因是正在使用的不正確的EntityManager。儘管指定了openjpa持久性提供程序,但blueprint最終將注入容器EntityManager:org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager。這可能是由於openjpa實現類在這種情況下對服務模塊不可用,所以默認爲容器實現。 – Ellis