I just implemented another "solution".
https://github.com/cschneider/jpa-experiments/blob/master/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceProviderTracker.java
I call EntityManagerFactory emf =
provider.createContainerEntityManagerFactory(punit, null); with a Dummy
DataSource in punit. This makes at least openjpa and
ecliseplink add their transformer. Will do a test with hibernate
tomorrow. All tests from Aries seem to work fine with that. I still have
a possible timing issue in my code if the PersistenceProvider is not
available when the bundle starts.
What do you think? Does this make sense or is it a bad idea?
Would the Bootstrap way you showed allow to work without a DataSource?
After all the enhancement should be independent of the database used.
Christian
On 16.05.2015 19:51, sebersole wrote:
Christian you hit a point we actually brought up to in both the JPA AND EE
expert groups: timing in terms of various EE component bootstrappings,
especially as more and more of them start to define integrations between
each other (CDI, BV, etc). What we proposed is a phased bootstrap to give a
well defined phase to each of these things being available. That was of
course not incorporated into the EE spec, but we did do this for Hibernate
by introducing a 2-phase bootstrap which containers could take optionally
advantage of, rather than using the standard JPA bootstrap SPI. We use this
in WildFly e.g to circumvent issues exactly like the one you describe. Not
to mention issues like BV and CDI pontentially not being available
immediately.
The first phase is the construction of
org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder. This can be done
directly by instantiating
org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl (not
supported) or by org.hibernate.jpa.boot.spi.Bootstrap (supported).
Hibernate will register its transformer, if at all, during this first phase.
Hibernate itself will try as hard as possible to not access the entity
classes until the second phase to allow the transformations to happen. This
part is not perfected yet for a number of reasons. See after the break for
a lesson as to why this is, if you care :) Anyway, all that said we do not
enable enhancement by default. Users must explicitly enable it via
"hibernate.ejb.use_class_enhancer=true"
We do in fact add a transformer if asked to perform runtime enhacement via
"hibernate.ejb.use_class_enhancer". Maybe you are not seeing that called
because that setting is not enabled. Either way, we always work with an
abstraction of PersistenceUnitInfo via
org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor. The point of
PersistenceUnitDescriptor is to abstract the difference in whether this is
an "SE" or an "EE" bootstrap environment. For EE bootstrapping, the
PersistenceUnitInfo is wrapped in a PersistenceUnitDescriptor and when we
call PersistenceUnitDescriptor#pushClassTransformer, that gets delegated to
javax.persistence.spi.PersistenceUnitInfo#addTransformer
----
Unlike most (every?) other JPA providers, Hibernate does not prefer bytecode
enhancement. Instead we prefer proxying. Partially the reason for that is
historical. So our bytecode enhancing is still progressing. In fact I
started back at it in 4.2. The original bytecode enhancing was very much
"bolted on" (which is the euphemism we use for band aids).
https://hibernate.atlassian.net/browse/HHH-7963 and its linked issues and
sub tasks represent the bulk of the work in this area.
Also I mentioned before the desire to move to Jandex. Part of that is to
better find and recognize everything that needs to be enhanced without
loading Class references specifically to better work with runtime
enhancement
--
View this message in context:
http://karaf.922171.n3.nabble.com/Hibernate-OSGi-Integration-tp4040190p4040405.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