Search code examples
javahibernatejpaosgikaraf

An equivalent to StickySession in Karaf/OSGI?


The issue is the following: in ma Karaf container, I have two modules, the first one is used to fetch data in the DB via a JPA interface implemented by Hibernate. Collections are fetched in a lazy way. The second module gets the object containing the collections. When trying to access elements of a collection, an error is thrown:

failed to lazily initialize a collection of role:
 mapp3.model.ProductDefinition, could not initialize proxy - no Session

It has no session to access the DB and fetch the missing elements. I know in J2EE there is a concept of Sticky Session that makes a Thread create and share the same session across all beans.

It there something similar in Karaf/OSGi or is there another way of properly acheiving lazy loading between different modules ?


Solution

  • I have just implemented a similar feature in Aries JPA 2.1.0. It uses the OSGi Coordinator spec to share an EntityManager session on a thread. It works together with Aries transaction blueprint 1.3.0 which now also uses a Coordination. Both are available in Apache Karaf 4.0.1.

    So to achieve a session that is kept over several calls between beans you annotate the outermost method involved with @Transactional. If you do not want an actual transaction but just the shared EM then you can use @Transaction with type Support. So starting from this method all calls made downwards will share the same em.

    So for example you can do something like this:

    @Transactional
    public void myServiceMethod() {
       Person person = personRepo.getPerson();
       List<Task> person.getTask();
    }
    

    So in the example above the PersonRepo would inject the EntityManager using @PersistenceContext and work with it.

    MyService.myServiceMethod would be on the service layer and should not know about jpa or the EntityManager. Still using the @Transactional annoation the method would provide a coordinaton over the execution of the method that holds the EntityManager.

    Also see my example Apache Karaf Tutorial Part 9 - Annotation based blueprint and JPA. The example does not show the overarching @Transactional but should get you started easily if you want to dig into it. As soon as the upcoming Aries releases are done I will also create an example that shows exactly the case you are looking for.