Skip to content
This repository has been archived by the owner on Nov 16, 2021. It is now read-only.

JPA Service should cooperate with Config Admin Service #12

Open
bjhargrave opened this issue Sep 2, 2011 · 18 comments
Open

JPA Service should cooperate with Config Admin Service #12

bjhargrave opened this issue Sep 2, 2011 · 18 comments
Labels
publiccomment Public comment

Comments

@bjhargrave
Copy link
Member

Original bug ID: BZ#123
From: Christoph Läubrich <[email protected]>
Reported version: R4 V4.3

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

The JPA Service helps a lot integrating persistence into OSGi systems.

There is just one thing drawback in the current specification:
Each persistence unit is described by it's persistence descriptor (persistence.xml) which must provide additional properties for the JPA Service especially the javax.persistence.jdbc.driver, infact most current providers also require the url/user/password.
(ignoring the case that these can be omitted and provided manually by EntityManagerFactoryBuilderService here)

This introduce the following problem:
If one decides to change any of these properties there are two cases:

  • change the bundle directly each time something changes
  • extract the persitence descriptor to a fragment and provide different fragments per configuration

In the first case a simple change of (for example) the password would require a ne deployment/update of the persitence bundle, in the second case it would require to duplicate the persitence file multiple times and replace the fragment.

To solve this issue, and to add more dynamic configuration option i would suggest the following enhancements:
Like in the "Declarative Service Specification" let the JPA Service cooperate with the Configuration Admin Service(CM), for example with the following procedure:

The JPA Service Provider observes the CM for a configuration in the following format javax.persistence..
If it founds one (or one gets updated) it takes the (static) properties from the persistence unit, combine them with the (dynamic) properties of the CM and behaves as if the persistent bundle where updated like described in the current specification.

This way persitence bundles can provide a default set of properties, as well as receiving dynamic configuration option through CM, and client bundles don't need to find and track EntityManagerFactoryBuilderService and create/destroy custom EntityManagerFactory but can just listent to a matching service even if they must be configured dynamically.

@bjhargrave
Copy link
Member Author

Comment author: Michael Keith <[email protected]>

Thanks very much for your comments and suggestions, Christoph.

As you mentioned, the EntityManagerFactoryBuilder was created for that exact scenario, i.e. to dynamically pass in JDBC properties. You are right that it requires the client to track the EMFB instead of the EMF (and make an extra API call to get an EMF), but the part you didn't mention is that it also puts the onus on the client to track the data source :-) Since the properties are dynamic, the client that passes in the JDBC properties is the only one to know when the data source is available and when it is safe to create an EMF. It should also figure out when the data source disappears to ensure that the EMF is closed.

I mention the above because if the properties were defined as part of a configuration object in config admin then it would be the responsibility of the configurer to know when a given data source is available. The timing and life cycle of the EMF is implicitly tied to the data source for the JDBC database driver, so one might not be any better off using config admin than the EMFB.

Anyway, feel free to continue to detail how you would expect to use it.

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

Created attachment 18
JPA CM interaction simplified overview

The PDF shows a (simplified) diagram of the current "steps", and how the JPA Service could interact with the Configuration Admin Service.

Attached file: JPA_CM_Interaction_simplified.pdf (application/pdf, 31832 bytes)
Description: JPA CM interaction simplified overview

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

Hello Michael,
thanks for taking the time reading and your reply.

I think I described it a little confusing, I have attached a PDF which hopefully describes a little better what my intention is.

but the part you didn't mention is that it also puts the
onus on the client to track the data source
Yes, thats the other point, so for any client bundle who wants to emulate it has to track:

  • The data source
  • The EMFB
  • The ConfigurationAdmin (and Configuration)

Thats why I'd like to suggest the enhancement with the JPA Service interacting with the CM, because it is already doing two of the three tasks.

if the properties were defined as part of a
configuration object in config admin then it would be the responsibility
of the configurer to know when a given data source is available.
As you can see in the diagram, the configurer can provide a configuration before or after the JPA service actually discovers any peristence bundle or datasource, it will just "be there" waiting to be used.

Anyway, feel free to continue to detail how you would expect to use it.
I hope the attached file clrifies it a bit :-)

@bjhargrave
Copy link
Member Author

Comment author: Michael Keith <[email protected]>

Thanks for the figure Christoph. I don't see any problems with this, except for the two red arrows on the left. I confess that my automatic reaction is to recoil when I see people wanting to redefine the data source parameters for an active persistence unit. I have had one other person want to do that in a different way, but in an attempt to achieve the same result. Would you be hoping to be able to use the fact that a change in the javax.persistence. config would cause the EM to get unregistered and re-registered to a different data source or did you just include that for completeness to go along with the config updated callback?

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

I confess that my automatic reaction is to
recoil when I see people wanting to redefine the data source parameters for an
active persistence unit.

Just curious, what's the reason for this? :)

Would you be
hoping to be able to use the fact that a change in the javax.persistence.
config would cause the EM to get unregistered and re-registered to a different
data source

Yes for example, I have a use-case where there are two different datasource one for development and one for production using different database drivers. The application is shipped with both, just the configuration is different.

In cooperation with the Metatype Service the user is even capable of changing e.g. the username/password or servername of the datasources.

or did you just include that for completeness to go along with the
config updated callback?

I also included it for completeness and consistency. Since one paradigma on OSGi is, that at any time a services can come and go as well as the JPA Service must handle the case where a bundle is uninstalled/updated/refreshed I think it won't cause any problems.

It might be worth to think about something that is called configuration policy in the Declarative Services you can either

  • require (--> the configuration admin is needed as well as a valid configuration)
  • optinally use (--> the CM and configuration is only used when available)
  • ignore (--> the CM and configuration is ignored)
    a configuration, but thats more a detail.

@bjhargrave
Copy link
Member Author

Comment author: Michael Keith <[email protected]>

I confess that my automatic reaction is to
recoil when I see people wanting to redefine the data source parameters for an
active persistence unit.

Just curious, what's the reason for this? :)

When we created the notion of a persistence unit in the JPA spec the whole point of it was to represent a certain named (static) configuration. Having that name suddenly refer to a different configuration was just not what we had in mind. However, I recognize that people have dynamic needs, and you are not the first person to ask, so we should probably make the appropriate changes to the JPA spec. In the meantime it might make sense to do some experimenting with different ways to offer it in OSGi JPA.

Would you be
hoping to be able to use the fact that a change in the javax.persistence.
config would cause the EM to get unregistered and re-registered to a different
data source

Yes for example, I have a use-case where there are two different datasource one
for development and one for production using different database drivers. The
application is shipped with both, just the configuration is different.

In cooperation with the Metatype Service the user is even capable of changing
e.g. the username/password or servername of the datasources.

Yes, the usual way people solve this is to have two different persistence unit config files, one for development and one for production, but I guess you did't want to have two different artifacts.

or did you just include that for completeness to go along with the
config updated callback?

I also included it for completeness and consistency. Since one paradigma on
OSGi is, that at any time a services can come and go as well as the JPA Service
must handle the case where a bundle is uninstalled/updated/refreshed I think it
won't cause any problems.

It might be worth to think about something that is called configuration policy
in the Declarative Services you can either

  • require (--> the configuration admin is needed as well as a valid
    configuration)
  • optinally use (--> the CM and configuration is only used when available)
  • ignore (--> the CM and configuration is ignored)
    a configuration, but thats more a detail.

Yes, we can consider these kinds of options.
Thanks, again, for your input.

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

When we created the notion of a persistence unit in the JPA spec the whole
point of it was to represent a certain named (static) configuration. Having
that name suddenly refer to a different configuration was just not what we had
in mind.
Ok I see. I personally like the concept of persistence units, its just the demand for configuration that cames up when using them :)

the usual way people solve this is to have two different persistence unit
config files, one for development and one for production,
but I guess you did't want to have two different artifacts.

it would be okay for two configurations (even if I don't like replication neither in code nor in configuration) but think about three or for differen configurations (each customer might use a differen server/username etc..) which becomes very fast a real nightmare exspecially when you need to add a ne Entity to many files...

Yes, we can consider these kinds of options.

I lately came up with another idea, it might be also possible to not bound the configuration to a specific name (javax.persistence.) as I sugested, but just use a serviceproperty for this purpose like it is done with ManagedService wich uses the service.pid property to determine the actual configuration.
This won't force people to use a specific name, and might allow to use the same configuration for multiple persitence units.

Thanks, again, for your input.
Thanks for the time reading and commenting my suggestions, let me know when something is done regarding this :)

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

EclipseLink implemented a similar aproach: https://bugs.eclipse.org/bugs/show_bug.cgi?id=365619

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

EclipseLink implemented a similar aproach:
Eclipse Gemini of course!

@bjhargrave
Copy link
Member Author

Comment author: Michael Keith <[email protected]>

Yes, the input from you and others is the reason why I recently added that to Gemini JPA in the last release :-)
Will be interested to get feedback on it to see how/if it meets people's needs. Once we get that then we can see about whether updating the spec is necessary/appropriate.

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

Will be interested to get feedback on it to see how/if it meets people's needs.
I have tried this today and for me it works fine and serves its purpose. I like the idea of having to define a "Standalone Configuration".

Just one thing: I assume it might be easier to use one scheme on the implementation/Gemini side, but for "Incremental Configuration" it would IMO better to not use a factory cfg and better use a single pid with name gemini.jpa.punit. for the following reasons:

  • there is no need to introduce an indirect restriction to just have one cfg per punit because it would be implicit (every PID is already unique)
  • less problems with determine if a cfg exits or what to update
  • "Standalone Configuration" can be further modified by "Incremental Configuration" providing even more felxibility

updating the spec is necessary/appropriate.
I defenately vote for having this in the spec since it helps alot with common configuration problems when it comes to OSGi JPA.

BTW: Maybe its worth to think extend the Manifestheader to allow some syntax like this:
Meta-Persistence: cm:punit1, cm:punit2
to get rid of the gemini.jpa.punit.bsn and still be able to linkt bundle<->cm<->punit

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

Just wondering: When using "Standalone Configuration " is the transaction-type always "RESOURCE_LOCAL"? I assume yes, but it is not mentioned in the docs.

@bjhargrave
Copy link
Member Author

Comment author: Michael Keith <[email protected]>

Thanks for your comments Christoph.

There is currently no support for JTA transactions in OSGi JPA (or Gemini JPA) so the transaction type should always be RESOURCE_LOCAL, at least for now.

@bjhargrave
Copy link
Member Author

Comment author: mrafi <[email protected]>

Hi Michael,

I have a similar scenario where I need to override the JPA properties for different customers and reuse the same code/bundle.

My application needs to support multiple customers with their specific database.

I have created a persistence bundle for one specific customer as POC. It works well.

Now I am planning to install the same bundle for other customers with different database. I wanted to reuse the same bundle but with customer specific unit.name and datasource properties.

I am unable to do this as neither JPA or OSGI has support to override these properties, unit.name, datasource name, other properties at the deployment time (if not at the runtime!).

Also if could instruct the JPA container to use the additional user defined properties say customer Id while it creates and registers the EMF also can be one of the options which allow me to filter based on the customer Id to get the corresponding EMF and ignore the PU name, and possibly create and inject the datasource through JNDI.

I think we should have atleast deployment time overriding of the JPA configurations if runtime has several constraints to think of (runtime changes through ConfigAdminService is a much better option though!).

Else either I have to rely on the manually updating the bundle for each new customer deployment or else go for creating multiple EMF and manage explicitly within a same bundle (which is the last option I am considering).

When you speak of EMFB service,
Aries doesn't provide that service and
I am not planning for Gemeni until JTA support available.

Appreciate your feedback on the above suggestion and any workaround.

thanks,
Rafi

@bjhargrave
Copy link
Member Author

Comment author: mrafi <[email protected]>

with respect to my previous comment on deployment time override, I meant ldwith property placeholders with persistence.xml.

Also the JPA container does not provide way to override them during bundle start up with bundle activator.

thanks,
Rafi

@bjhargrave
Copy link
Member Author

Comment author: Hoff <[email protected]>

I wish everything was interoperable one day. ,https://www.maxvisits.com/

@bjhargrave
Copy link
Member Author

Comment author: Christoph Läubrich <[email protected]>

Its a long time but I just wanted to let you know that I implemented in PAX JPA support for extending properties of the persistenceunit in the following way:

  • the persitence.xml is parsed for PUs
  • a ManagedService is registered with PID

"org.ops4j.pax.jpa.pu." + persistenceUnit.getName().replace(' ', '_')

  • everytime 'updated' is called the properties of the PU are extended
  • the EMFB is notified that properties have changed so it can reevaluate if the changes and refresh the EMF

What do you think, would it be possible to standardize such behavior?

@bjhargrave bjhargrave added the publiccomment Public comment label May 1, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
publiccomment Public comment
Projects
None yet
Development

No branches or pull requests

1 participant