You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Yuri <yd...@gmail.com> on 2008/11/14 07:04:04 UTC
Customizing OpenJPA
I started running through a few debugging sessions to understand the design
and come up for a course of action in terms of extending OpenJPA. A few
questions came up:
- How can a ProductDerivation be used to extend OpenJPA (I am assuming that
is its purpose)?
- What is the difference between ProductDerivation.TYPE_PRODUCT and
ProductDerivation.TYPE_FEATURE
- What is the difference between ClassMetadata and MappingInfo? It seems
that the latter is a temporary holder of schema objects until the final
ClassMetadata is assembled. Is that correct?
- Noticed that the enhancement on class loading is no using the classes I
created to extend OpenJPA (i.e. Configuration and what follows from that).
- Also noticed that MetadataRepository is created at least two times once
when enhancing and once for real.
I am planning initially to add a new @Temporal annotation and to make sure
that this annotation translates into additional columns in the table, into a
modified primary key and custom handling of the SQL statements. What would
be the main touch points in the code to make that happen?
thanks,
-- yuri
--
View this message in context: http://n2.nabble.com/Customizing-OpenJPA-tp1497344p1497344.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.
Re: Customizing OpenJPA
Posted by Yuri <yd...@gmail.com>.
FWIW, here is a simple class diagram to help me navigate the design...
http://n2.nabble.com/file/n1623649/openjpa.gif
--
View this message in context: http://n2.nabble.com/Customizing-OpenJPA-tp1497344p1623649.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.
Re: Customizing OpenJPA
Posted by Yuri <yd...@gmail.com>.
Patrick Linskey-2 wrote:
>
>> - Noticed that the enhancement on class loading is no using the
>> classes I
>> created to extend OpenJPA (i.e. Configuration and what follows from
>> that).
>> - Also noticed that MetadataRepository is created at least two times
>> once
>> when enhancing and once for real.
>
> These are probably related -- the enhancer by default uses a plain
> OpenJPAConfigurationImpl instance instead of a JDBCConfigurationImpl
> or whatever subclass is available in the environment. In general, the
> enhancement contract is simply a way to plug into objects for the
> purposes of interacting with their persistent state, and so the back-
> end-specific details must not be relevant. IOW, it is a design goal to
> be able to support different back-ends for the same enhanced classes.
>
> Is there something that you find that you need to do during
> enhancement for your task?
>
Not at this point. It was a question that came up while trying to create a
mental picture of the design and the main components. The more I learn about
the design the more it makes sense the fact that it will be very unlikely I
will have to mess with the enhancer.
Patrick Linskey-2 wrote:
>
> What is the goal of your work? Also, is @Temporal targeted at the
> class level or the field level, or both?
>
The goal is to provide versioning of persistent models by simply adding
@Temporal to the classes one wishes to version (with a few additional
parameters for customizations e.g. what is the name of the valid time
column, granularity - millis, days, hours). At this point I am not
interested in providing a full bi-temporal solution just a valid time
temporality that is, to the extent possible, orthogonal to the persistent
model.
This extension starts with the @Temporal annotation, transforms the
persistent class' id into id + validEnd, rewrite the implementation of a
logical inserts, updates, deletes, and selects, internally forces the
immutability of the persistent model (the Entity state will be divided into
two objects: a temporal aware proxy and a state object that is a mirror of
what is in the db - the proxy will be aware of what is the current time for
the query). Then once the main infra is implemented I am planning to extend
the query language to allow for queries across valid time.
Patrick Linskey-2 wrote:
>
> Assuming that you're looking into adding object versioning support to
> OpenJPA, I believe that there are two general approaches that you
> should consider:
>
> 1. change the ClassMappings (or things they use) to know about
> temporal information, and to translate the various Broker-level / EM
> APIs to their temporal equivalents (EntityManager.remove() => an
> UPDATE statement; modifications => UPDATE / INSERT pairs, add
> timestamp range qualifications to queries and relationships, etc.)
>
> 2. add a new StoreManager implementation that does the above
> translations at the generic object level and delegates to an
> underlying StoreManager.
>
>
> I'm not sure which approach I like the most. #2 seems more natural, as
> it operates at the object persistence level, rather than in the JDBC
> nitty-gritty. But #1 might be more straightforward to implement, since
> there isn't currently a clean and simple way to add synthetic
> persistent fields or field-like things to a class, whereas it is
> straightforward to do so at the JDBC layer.
>
I think my confused thoughts are more in line with your #1 above, although
it seems to me that the touch points will be much larger than just the
ClassMapping. I am sure that half of it is my ignorance of the
implementation.
Here is my understanding so far of what needs to be done:
- The first thing I need to do is create the class level @Temporal
annotation and make sure the AnnotationPersistenceMappingParser is able to
handle it. It seems that I will need to subclass
AnnotationPersistenceMappingParser and override
handleUnknownClassMappingAnnotation() (Later support for xml can be added).
- The annotation parser will then add two FieldMappings, one for validStart
and one for validEnd. The validEnd FieldMapping will be set as primary key.
Here I am assuming that the back end will automatically generate the right
table schema with the two added columns and the composite pk.
* Is this the right place to be adding these synthetic FieldMappings? I
think I saw a subclass of ClassStrategy.map() performing metadata and/or
schema modifications somewhere in the code.
- Then I will need to install custom ClassStrategy that rewrites
inserts/updates/selects/deletes. Not sure if I need also to override
FieldStrategy or even if I need to create a custom TemporalClassMapping
and/or TemporalFieldMapping. It seems that there is much more here than meet
the eyes...
- Then I need to extend StateManager to include two new attributes
validStart and validEnd since they dont actually exist in the PC. I also
need to figure how to make sure that the impl doesnt try to get these two
values from the PC object (not sure exactly where yet)
- I am also expecting some sort of StateManager proxy that holds a given
point in time (timestamp) in addition to a reference to the original
StateManager. This is needed I think since the row that comes back from a
given PC is valid for a data range and the fact that each end of a relation
could have different ranges: basically different queries could thread
differently through the relations.
At this point I am also not sure how/where #2 fits in the above steps.
Hope my loose thoughts above are not too confusing.
thanks for you help,
-- yuri
--
View this message in context: http://n2.nabble.com/Customizing-OpenJPA-tp1497344p1623623.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.
Re: Customizing OpenJPA
Posted by Patrick Linskey <pl...@gmail.com>.
> - What is the difference between ClassMetadata and MappingInfo? It
> seems
> that the latter is a temporary holder of schema objects until the
> final
> ClassMetadata is assembled. Is that correct?
Yes. OpenJPA parses from various different formats into MappingInfo
data structures, and then the ClassMetaDatas are created from the
MappingInfo.
> - Noticed that the enhancement on class loading is no using the
> classes I
> created to extend OpenJPA (i.e. Configuration and what follows from
> that).
> - Also noticed that MetadataRepository is created at least two times
> once
> when enhancing and once for real.
These are probably related -- the enhancer by default uses a plain
OpenJPAConfigurationImpl instance instead of a JDBCConfigurationImpl
or whatever subclass is available in the environment. In general, the
enhancement contract is simply a way to plug into objects for the
purposes of interacting with their persistent state, and so the back-
end-specific details must not be relevant. IOW, it is a design goal to
be able to support different back-ends for the same enhanced classes.
Is there something that you find that you need to do during
enhancement for your task?
> I am planning initially to add a new @Temporal annotation and to
> make sure
> that this annotation translates into additional columns in the
> table, into a
> modified primary key and custom handling of the SQL statements. What
> would
> be the main touch points in the code to make that happen?
What is the goal of your work? Also, is @Temporal targeted at the
class level or the field level, or both?
Assuming that you're looking into adding object versioning support to
OpenJPA, I believe that there are two general approaches that you
should consider:
1. change the ClassMappings (or things they use) to know about
temporal information, and to translate the various Broker-level / EM
APIs to their temporal equivalents (EntityManager.remove() => an
UPDATE statement; modifications => UPDATE / INSERT pairs, add
timestamp range qualifications to queries and relationships, etc.)
2. add a new StoreManager implementation that does the above
translations at the generic object level and delegates to an
underlying StoreManager.
I'm not sure which approach I like the most. #2 seems more natural, as
it operates at the object persistence level, rather than in the JDBC
nitty-gritty. But #1 might be more straightforward to implement, since
there isn't currently a clean and simple way to add synthetic
persistent fields or field-like things to a class, whereas it is
straightforward to do so at the JDBC layer.
-Patrick
On Nov 13, 2008, at 10:04 PM, Yuri wrote:
>
> I started running through a few debugging sessions to understand the
> design
> and come up for a course of action in terms of extending OpenJPA. A
> few
> questions came up:
>
> - How can a ProductDerivation be used to extend OpenJPA (I am
> assuming that
> is its purpose)?
> - What is the difference between ProductDerivation.TYPE_PRODUCT and
> ProductDerivation.TYPE_FEATURE
> - What is the difference between ClassMetadata and MappingInfo? It
> seems
> that the latter is a temporary holder of schema objects until the
> final
> ClassMetadata is assembled. Is that correct?
> - Noticed that the enhancement on class loading is no using the
> classes I
> created to extend OpenJPA (i.e. Configuration and what follows from
> that).
> - Also noticed that MetadataRepository is created at least two times
> once
> when enhancing and once for real.
>
> I am planning initially to add a new @Temporal annotation and to
> make sure
> that this annotation translates into additional columns in the
> table, into a
> modified primary key and custom handling of the SQL statements. What
> would
> be the main touch points in the code to make that happen?
>
> thanks,
>
> -- yuri
> --
> View this message in context: http://n2.nabble.com/Customizing-OpenJPA-tp1497344p1497344.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>
--
Patrick Linskey
202 669 5907