The @Transactional and @PersistenceContext annotations work exclusively in blueprint or eventually pax-cdi with deltaspike.

For declarative services there is no extension model to add new annotations. So we can not easily support annotations like above.
This is not a big issue though as we have alternative solutions in place.

See
http://liquid-reality.de/display/liquid/2015/06/30/Apache+Karaf+Tutorial+part+10+-+Declarative+services

For DS there is the JPATemplate from Aries JPA. It allows the same feature set as the annotations for blueprint but works using closures instead. I used this a bit myself and while I first was very pro annotation I changed my mind in the mean time. I think the closure based approach works as nice and is less complex. Btw. I am experimenting with an alternative approach using try with resources instead of closures. That would allow a similar style but be even less complex.

There is also an alternative from the OSGi specs. It is called tx-control and also hosted at Aries.
http://aries.apache.org/modules/tx-control/
It is similar to JPATemplate but a little different in style. The code is written by Tim Ward and he also did a very good documentation for it.

Christian

On 10.03.2017 09:00, erwan wrote:
Sorry for the "timeout" before answering your comment but it took me some
time to have a look at all solutions that were proposed. What strikes me is
that, as you already stated, it is difficult to select a solution that is
simple, well documented and seen as a standard. It's a bit annoying as osgi
doesn't seem to be a young solution. By browsing the web, looking for
solutions, it seems to go in every directions.
To be more concrete, I tried to combine 2 solutions to my need : blueprint
and DS.
I'm not sure we can mix several solutions. I probably need to spend some
more time :)
First, I use blueprint solution to deploy a persistence bundle and Christian
tutorial site has been of a great help with that. Thanks to you.
Then I tried to add declarative service in the loop, using annotations as it
seemed practical to me.
For the moment, I'm not able to make this working so I hope you might take a
little bit more time to evangelize
Can I do this?
In the persistence bundle, after having installed hibernate feature:

@Component(immediate = true)
@Transactional
public class RepositoryImpl implements IRepository {

        private EntityManager manager;  

        @PersistenceContext(unitName="db")
        public void setEntityManager(EntityManager manager) {
                this.manager = manager;
        }

        private UniqueIdManagerItf uniqueIdManager;

        @Reference
        public void setUniqueIdManager(UniqueIdManagerItf uniqueIdManager) {
                this.uniqueIdManager = uniqueIdManager;
        }

        @Override
        public void removeAll() {
                ArrayList<String> uniqueIdList = new ArrayList<>();

                uniqueIdList = uniqueIdManager.getUniqueIdList();
                for (String id: uniqueIdList) {
                        uniqueIdManager.setIdAsAvailable(id);
                }
                manager.createQuery("DELETE FROM MyEntity").executeUpdate();
        }

with a pom like this:
                                <configuration>
                                        <instructions>
                                                
<Bundle-SymbolicName>${project.artifactId}</Bundle-symbolicName>
                                                
<Bundle-Version>${project.version}</Bundle-Version>
                                                <supportedProjectTypes>
                                                        
<supportedProjectType>bundle</supportedProjectType>
                                                </supportedProjectTypes>
                                                <Export-Package>
                                                
com.example.persistence.entity.*;version=${project.version}
                                                </Export-Package>
                                                <Import-Package>
                                                        *
                                                </Import-Package>
                                                
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
                                                <Dynamic-Import-Package>
                                                        *,
                                                        org.hibernate.proxy,
                                                        javassist.util.proxy
                                                </Dynamic-Import-Package>
                                                
<_dsannotations>*</_dsannotations>
                                        </instructions>
                                </configuration>

a persistence.xml :
<persistence xmlns="http://java.sun.com/xml/ns/persistence";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"; version="2.0">

   <persistence-unit name="db" transaction-type="JTA">
     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=db)</jta-data-source>
        <class>com.example.persistence.entity.MyEntity</class>
        
     <properties>
       <property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect"/>
       <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
       <property name="hibernate.archive.autodetection" value="class"/>
     </properties>

   </persistence-unit>

</persistence>

and what might be unnecessary :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
                   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0";
                   xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0";
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
                   
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd";>
        <jpa:enable/>
        <tx:enable-annotations/>
</blueprint>

In the consumer bundle (something like a REST api):

@Path("")
@Component
public class EndPoint {

        private IRepository repository;
        @Reference
        public void setRepository(IRepository repository) {
                this.repository = repository;
        }

        @DELETE
        @Path("removeAll")
        public void  clearDB() {
                repository.removeAll();

        }

With a third bundle API:
public interface IRepository {
        void removeAll();

in this example, I think i'm missing something that will instantiate the
IRepository although I thought it will be done by the declarative service. I
also think that I probably didn't understand well how it works internally.

On karaf side:
scr:details com.example.persistence.JPAResourceRepositoryImpl
Component Details
   Name                : com.example.persistence.JPAResourceRepositoryImpl
   State               : ACTIVE
References
   Reference           : UniqueIdManager
     State             : satisfied
     Multiple          : single
     Optional          : mandatory
     Policy            : static
     Service Reference : Bound Service ID 556
(com.example.persistence.UniqueIdManager)

As you can understand, I really need more reading sessions of the chapter 5
inside OSGi Core document!




--
View this message in context: 
http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756p4049823.html
Sent from the Karaf - User mailing list archive at Nabble.com.


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply via email to