0

シンプルなFuse ESBプロジェクトでエンティティを永続化するためにJPAを使用しようとしましたが、エンティティが基礎となるデータベースに書き込まれないという問題に直面しています。プロジェクトは、次の 3 つのモジュールで構成されています。

シンプルなデータソース

シンプルモデル

シンプルサービス

データソースはブループリントを介して構成され、データソースは 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;
}

}

次に、再びブループリントと simple-service-persistence-unit への参照を使用して EntityManager をサービスに挿入し、メソッド レベルのトランザクション境界を使用する必要があることを指定します (すべての例で見たように)。

<?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.

トランザクションを明示的に開始しようとして、サービス Bean 構成の tx:transaction アノテーションを削除すると、次のエラーで失敗します。

An error occurred: Transaction management is not available for container managed EntityManagers.

関連する可能性があるその他の情報。基になる EntityManager 実装は次のとおりです。

org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager

また、インストールされている aries コンポーネントのリストは次のとおりです。

[   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)

オンラインのほとんどの例に従っているこの構成に明らかに問題がありますか?

4

1 に答える 1

0

永続化レイヤーでトランザクション タイプが適切であるため、resource_local をいつ使用するか正確にはわかりません。ただし、JTA と jta-data-source を使用するように persistence.xml を次のように変更すると、問題が修正されました。

<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>
    <!--non-jta-data-source>osgi:service/jdbc/simpleDataSource</non-jta-data-source-->      
    <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/simpleDataSource)</jta-data-source>
    <class>com.company.model.SimpleRow</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="openjpa.Log" value="DefaultLevel=INFO, Tool=INFO, SQL=TRACE"/>
    </properties>
</persistence-unit>

于 2013-07-04T11:21:41.647 に答える