Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Gemini » Best way to use Gemini JPA in Eclipse e4 RCP application
Best way to use Gemini JPA in Eclipse e4 RCP application [message #1008416] Tue, 12 February 2013 12:10 Go to next message
Tom Berger is currently offline Tom BergerFriend
Messages: 3
Registered: February 2013
Junior Member
Hi,

I use gemini JPA 1.1 in a e4 RCP application. To access the gemini OSGI service, I used the serviceTracker described in the "basic sample" which comes with the gemini jpa jars.

This sample conatains an addingService method (in the e4 application bundle Activator) to be called by the serivce tracker.

    public Object addingService(ServiceReference ref) {
        Bundle b = ref.getBundle();
        Object service = b.getBundleContext().getService(ref);
        String unitName = (String)ref.getProperty(EntityManagerFactoryBuilder.JPA_UNIT_NAME);

        if (unitName.equals("myPersistenceUnit")) {
            new AccountClient().run((EntityManagerFactory)service);
        }
        return service;


However, this method is /*not*/ called by the serviceTracker as soon as the gemini JPA service is available(=started). 2 questions remain:

1) How do I have to start the gemini JPA OSGI bundle? With all bundles in "default" start level in my e4 launch config, I have to manually start the bundle via the OSGI console AFTER starting the application; when trying to modify the start order of the bundle to get the gemini JPA service started earlier, the e4 Allication cannot start anymore.

2) which is the best way to get the EntityManagerFactory retrieved by the addingService permanently available in my application? Via the IEclipseContext, e.g. like this:

...
if (unitName.equals("myPersistenceUnit")) {
EntityManagerFactory emf = (EntityManagerFactory)service);
       eclipseContext.set(EntityManagerFactory.class, emf); // instance of IEclipseContext via @Inject
        }

...


thanks for advice,
Tom

[Updated on: Fri, 15 February 2013 09:55]

Report message to a moderator

Re: Best way to use Gemini JPA in Eclipse e4 RCP application [message #1008676 is a reply to message #1008416] Wed, 13 February 2013 14:34 Go to previous messageGo to next message
Michael Keith is currently offline Michael KeithFriend
Messages: 216
Registered: July 2009
Senior Member
Hi Tom,

A few comments and questions to help clarify:

1) If the service tracker is being registered by your application but is not being invoked then it is likely just that the EMF is not being registered by Gemini JPA for some reason. You might also want to register a tracker against the EMF Builder service to debug when the application actually gets processed by Gemini JPA. If you don't see the builder get registered then Gemini JPA is not even finding the application. Another way to see what Gemini JPA is seeing is to turn on debugging.

2) You said "when trying to modify the start order of the bundle to get the gemini JPA service started earlier, the e4 Allication cannot start anymore."
What happens to the application that makes you say it cannot start anymore? Is there an exception? Some other problem?

3) What is the packaging of your app? Is the persistence unit bundle separate or is it just part of your e4 application? Is the Meta-Persistence manifest header properly specified?

4) There is no hard requirement to start Gemini JPA before the application, although it definitely is preferred/recommended. If it isn't then it will do a refresh on the bundle, which may also be causing you problems. See the doc on refreshing to get a better understanding of what I am talking about, or to disable it.

5) You could in theory use e4 injection to inject the EMF as long as the service is available when your application is being injected, but a) that relies on the fact that the service will be there and e4 is very time-sensitive; if the service is not available in the window when it is injecting then you have missed your chance and it won't come back later on, b) there would need to be only one persistence unit since I don't believe e4 can distinguish between different persistence units, and c) I don't see too many people doing this. Manual service tracker would be more reliable, I think.

-Mike
Re: Best way to use Gemini JPA in Eclipse e4 RCP application [message #1008777 is a reply to message #1008676] Wed, 13 February 2013 20:50 Go to previous messageGo to next message
Tom Berger is currently offline Tom BergerFriend
Messages: 3
Registered: February 2013
Junior Member
Hi Mike,

thanks for your answer. It led me (and other research I did on this issue) to a solution.

Quote:
If the service tracker is being registered by your application but is not being invoked then it is likely just that the EMF is not being registered by Gemini JPA for some reason


Sorry, that was a misunderstanding / typing error. The service tracker was sucessfully invoked, but only for the "runtime" of the bundle Activator (since the "basic sample" which comes with gemini jpa jars contains an Activator that implements the ServiceTrackerCustomizer interface). The question was, how to access the EntityManagerFactory provided by the ServiceTracker for the whole runtime of my allication.

I created an own class for accessing the EntityManager:

public class DBHandler implements ServiceTrackerCustomizer 
{

	private ServiceTracker emfTracker;
	private EntityManager entityManager;
	private BundleContext ctx;
	@SuppressWarnings("unchecked")
	public DBHandler()
	
	{ 
	ctx = FrameworkUtil.getBundle(DBHandler.class).getBundleContext();
		emfTracker = new ServiceTracker(ctx, EntityManagerFactory.class.getName(), this);
    emfTracker.open();
		
	}
	
	/* We are in the same bundle as the persistence unit so the services should be 
     * available when we start up (if nothing bad happened) and the tracker is really 
     * just saving us the lookup, but this is the idea of how you would listen for a 
     * persistence unit coming from another bundle.
     */
   
	
	
	/*========================*/
    /* ServiceTracker methods */
    /*========================*/

    public Object addingService(ServiceReference ref) {
        Bundle b = ref.getBundle();
        Object service = b.getBundleContext().getService(ref);
        String unitName = (String)ref.getProperty(EntityManagerFactoryBuilder.JPA_UNIT_NAME);

        if (unitName.equals(HalliGalliConstants.PERSISTENCE_UNIT_NAME)) {
        	//new JPAClient().run((EntityManagerFactory)service);
        	EntityManagerFactory emf = (EntityManagerFactory)service;
        	this.entityManager = emf.createEntityManager();
        	
           
        }
        return service;
    }

	public EntityManager getEntityManager() {
		return entityManager;
	}


In my e4 part views, I can now instantiate this class to get an EntityManager. For an improvement, I could use IEclipseContext to store one instance of EntityManager application wide. But it works so far.

The second issue was the starting of the bundles; my e4 product launch config had previously had "auto start" set to "default" for the gemini bundle. After setting "auto start" to "true", the bundle startet with the e4 application. One question remained:

Quote:

2) You said "when trying to modify the start order of the bundle to get the gemini JPA service started earlier, the e4 Allication cannot start anymore."
What happens to the application that makes you say it cannot start anymore? Is there an exception? Some other problem?


I got a series of java.io.IOException at application startup. The platform could not access the resource files (such as icons, gifs, etc.) which are referenced in the Application.e4xmi in the product bundle. (!??!?!?) But after adding "-DREFRESH_BUNDLES=FALSE" to VM args in launch config, this issue was gone.

The only thing is, that i get a warining on gemini startup:
"WARNING: Refreshing disabled - entities in bundle at.lintner.halligalli may not be woven"

Is there any drawbacks, or can I just ignore the warning?

Next thing I try is a e4 product export, in order to check if everything runs fine on the exported application.

regards,
Tom




Re: Best way to use Gemini JPA in Eclipse e4 RCP application [message #1009295 is a reply to message #1008777] Thu, 14 February 2013 21:05 Go to previous messageGo to next message
Michael Keith is currently offline Michael KeithFriend
Messages: 216
Registered: July 2009
Senior Member
Hi Tom,

Yes, I suspected that refreshing was happening and that was messing up e4. It seems that many of these frameworks do not really like it when refreshes happen, even though that is the only way to guarantee dynamic weaving when a bundle has already been resolved.

The warning you are getting is simply informing you that it may be too late for Gemini/EclipseLink to do dynamic weaving of the entity classes since they may have already been loaded. If you are happy with your current performance then you need not worry about the warning.

The issue is that if you don't get weaving you won't be able to get lazy one-to-one/many-to-one relationships or lazy basic attributes. While you will be able to mark these as lazy, they will in actual fact end up being eagerly loaded at runtime. The way to get around this is to statically weave. See the EclipseLink weaving documentation for more background on weaving, and see the static weaving instructions for directions on how to perform static weaving.

-Mike
Re: Best way to use Gemini JPA in Eclipse e4 RCP application [message #1009543 is a reply to message #1009295] Fri, 15 February 2013 09:48 Go to previous message
Tom Berger is currently offline Tom BergerFriend
Messages: 3
Registered: February 2013
Junior Member
Hi Mike,

thank you for the hint on the weaving issue. By now, performance is not an issue, but as tables grow it might cause trouble some time since my PU includes several OneToMany and ManyToMany relations.

This topic can be marked as [solved]. Thanks!

[Updated on: Fri, 15 February 2013 09:48]

Report message to a moderator

Previous Topic:Gemini Blueprint 2.0.0.M01
Next Topic:Gemini Blueprint: NoClassDefFoundError
Goto Forum:
  


Current Time: Mon Nov 24 12:39:01 GMT 2014

Powered by FUDForum. Page generated in 0.02621 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software