2013-07-04 2 views
0

Я пытаюсь использовать JPA для сохранения объекта в простом проекте Fuse ESB, но перед этим я сталкиваюсь с проблемой, что объект никогда не записывается в базовую базу данных. Проект построен с использованием следующих трех модулей:Предохранитель ESB JPA Объект не сохраняется

простой DATASOURCE

простой модели

простой сервис

DataSource конфигурируется через копирку и источник данных, прикрепленных к 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; 
} 

}

I затем вставьте 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. 

Если я пытаюсь начать транзакцию явно, и удалить ТЙ: аннотация сделки в конфигурации служебного бина, то он не работает со следующей ошибкой:

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

Другие i которые могут иметь значение.Лежащая в основе реализация 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) 

Есть ли что-то явно не так с этой конфигурацией, которая следует большинство примеров в Интернете?

ответ

0

Я точно не знаю, когда используется resource_local, поскольку тип транзакции является подходящим в уровне сохранения. Однако изменение persistence.xml использовать JTA и JTA,-источника данных следующим образом сосредоточил свой вопрос:

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

+0

Я подозреваю, что причина в том, что неправильное EntityManager используется. Несмотря на то, что провайдер постоянства openjpa указывается, проект в конечном итоге вводит контейнер EntityManager: org.apache.aries.jpa.container.context.transaction.impl.JTAEntityManager. Это может быть связано с тем, что класс реализации openjpa недоступен для сервисного модуля в этом случае и поэтому по умолчанию используется реализация контейнера. – Ellis