Reputation: 7106
I have a data access module that provides implementations of repositories using Spring and JDBC.
Therefore, I define a Spring context as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager" />
<bean id="annotationTransactionAspect" factory-method="aspectOf" class="org.springframework.transaction.aspectj.AnnotationTransactionAspect">
<property name="transactionManager" ref="transactionManager" />
</bean>
</beans>
I also expose the repositories implementations as services using Declarative Services as follows:
<?xml version="1.0" encoding="UTF-8"?>
<component name="cdr-repository" enabled="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/scr/v1.1.0 http://www.osgi.org/xmlns/scr/v1.1.0">
<!-- Property and Properties -->
<properties entry="OSGI-INF/myrepository-component.properties" />
<!-- Service (optional) -->
<service>
<provide interface="com.example.osgi.dataaccess.api.MyRepository" />
</service>
<!-- Zero or more references to services -->
<!-- Exactly one implementation -->
<implementation class="com.example.osgi.dataaccess.jdbc.impl.MyRepositoryImpl" />
</component>
So, my services are created outside the Spring environment and therefore they are not fully configured (e.g. datasource is not injected).
I'm looking for the right way to integrate Spring with Declarative Services.
Thanks, Mickael
Upvotes: 3
Views: 1556
Reputation: 19606
Spring and Declarative services are not meant to be used together. So the approach you use will not work.Declarative services is a very simple framework that can only wire services into components and publish components as services. It has no capabilities regarding jpa. So I think DS will not be a good match if you want to use something like jpa with container managed persistence.
Like Holly mentioned blueprint supports that with the help of some other aries modules. I have created a tutorial that shows how to use this in a complete example. See: http://liquid-reality.de/pages/viewinfo.action?pageId=6586413
The blueprint approach is very different from how spring does jpa and container managed transactions. In spring you normally create the datasource in your context and inject it. In blueprint you work more like in standard jpa. There the datasource is referenced in persistence.xml and looked up using jndi. Aries jndi then bridges from jndi to OSGi services so another bundle can offer the datasource as an OSGi service.
The other option you have is to use spring dm to create jpa services the "spring way". But spring dm is not maintained and has a lot of problems in OSGi. So blueprint is currently the best way to go.
Upvotes: 3