Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc) » [CDO] Teneo/Hibernate integration
| |
Re: Hibernate Questions [message #110264 is a reply to message #110231] |
Wed, 30 January 2008 14:19 |
Eclipse User |
|
|
|
Originally posted by: tom.eiswind.de
HI Eike,
although I worked with hibernate for many years its the first time I
hear about such a difference. Ok something learned.
Have a look at
http://www.hibernate.org/377.html
theres an example.
Eike Stepper schrieb:
> Hopefully here is a Hibernate expert listening (Martin?) ;-)
>
> From my first scan of the Hibernate docs I begin to believe that
> EntityTuplizers are what we need to integrate Hibernate with a CDO
> server. DynamicMaps would also go but seem less efficient to me.
>
> 1) What is the difference between a Hibernate Entity and a Hibernate
> Component? There seem to be separate respective Tuplizers for each.
>
> 2) In
> http://www.hibernate.org/hib_docs/v3/reference/en/html/persi stent-classes.html#persistent-classes-tuplizers
> I see that Tuplizers are specified in the mapping file. Would it be
> possible to programatically specify one when the session is created?
>
> 3) The really interesting chapter is empty (TODO: Document
> user-extension framework in the property and proxy packages). Does
> anyone have experience with these topics?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
|
|
| | |
Re: Skeleton Implementation [message #111154 is a reply to message #111137] |
Wed, 30 January 2008 22:24 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I checked the project out and the related projects. I must say that you are quick :-). I looked
through the code. A few questions/remarks:
- Can you explain how the version number works in the relational db store you have. I mean
specifically for foreign keys, for example if an object A refers to B and I store a new version of
B, to which version does A then point?
- when is the writepackage method called? The ecore package is stored in the database also in your
view or can this be ignored (for now)?
- The storewriter has a method writeRevision, with hibernate write operations cascade automatically
to refered-to objects, so the writeRevision method will have side effects. This is no problem?
- How does storereader.readResourceID work for the relational store? Is a resource also stored
explicitly?
- I see that each object has a CDOID, which has an internal value of long (correct?), this means
that composite or String primary keys are not supported?
It would not be to difficult to add Teneo here. I can also add the hibernate initialization code. To
get a testcase up and running, can I use the standalone code you specified earlier for this?
I can get the epackage from the cdopackageregistry?
gr. Martin
Eike Stepper wrote:
> Hi Martin,
>
> I've just committed a first version of a plugin to the CVS:
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>
>
> It contains my CDORevisionTuplizer and a skeleton implementation of CDOs
> storage framework.
> I think this is a good point to start from. The obvious places with
> missing code (19x) are marked // TODO Implement me
>
> The 2 main classes to fill with functionality are:
> - HibernateStoreReader
> - HibernateStoreWriter
>
> We can ignore HibernateStoreChunkReader at the beginning.
> I'm sure I can help with the missing functionality, but I have no clue
> how to connect the pieces.
> May be you get an idea when looking at the project...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
> Eike Stepper schrieb:
>> I'd like to start a new thread here which can be used to discuss the
>> given topic.
>>
>> I'll start to write some sub threads, mainly with questions about
>> Hibernate details...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation [message #111170 is a reply to message #111154] |
Wed, 30 January 2008 23:30 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> I checked the project out and the related projects. I must say that
> you are quick :-).
I give my best ;-)
> I looked through the code. A few questions/remarks:
> - Can you explain how the version number works in the relational db
> store you have. I mean specifically for foreign keys, for example if
> an object A refers to B and I store a new version of B, to which
> version does A then point?
The version is never part of reference information.
As you'll have noticed a CDOObject is just a thin wrapper for a
CDORevision, which is identified by CDOID and version. It's the task of
a "view" to associate objects with the correct revision. This depends on
the type of view, CDOView and CDOTransaction deliver always the latest
revision (determined by revised==null) and CDOAudit delivers a revision
where the timeStamp of the view (audit) is between the "created" and
"revised" values of the revision.
All this is not important if we decide to ignore the auditing mode. Then
we (hibernate) would use the version of the revision only for optimistic
locking.
> - when is the writepackage method called? The ecore package is stored
> in the database also in your view or can this be ignored (for now)?
I don't think that we can ignore this.
The method is called by the repository when it receives a
CommitTransactionIndication (a signal over the network after the client
committed a transaction) that contains new packages. If we ignore this
indication the repository would later startup without knowledgeabout
previously used packages.
I also thought about how to store the meta model. The CDO internal meta
model is comparingly simple, it only knows about CDOPackages, CDOClasses
and CDOFeatures. These model elements only carry information that is
necessary for persistence aspects. I see some options:
1) Use Hibernate to create a static model and its mapping to a static
schema. Ideally we could reuse the existing code (CDOPackageImpl,
CDOClassImpl and CDOFeatureImpl). Isn't Hibernate about mapping POJOs?
2) Use the JDBC connection of a Hibernate session (that is used for the
dynamic mapping) and the code from my DBStore.
3) Store the meta model outside of the DB within the file system. This
creates extra configuration and runtime maintenance.
> - The storewriter has a method writeRevision, with hibernate write
> operations cascade automatically to refered-to objects, so the
> writeRevision method will have side effects. This is no problem?
I'm not sure that I understand this. May be I explain the semantics of
the writeRevision() method:
When a client modifies CDOObjects the associated CDOTransaction becomes
dirty. The CDOTransaction remembers all modified objects (in fact it
even temporarily stores their associated, transactional revisions). When
the transaction is committed all the internal state of the transaction
(particularly the transactional revisions of the modified objects) is
transferred to the server where it is deserialized. First added packages
are written to the store via IStoreWriter.writePackages() then each of
the received revisions of the new/modified objects is written to the
store via IStoreWriter.writeRevision(). No matter what kind of
references do exist between the original objects. A CDORevision doesn't
have Java reference handles to other CDORevisions. References between
the original objects are completely represented as CDOIDs (see below).
> - How does storereader.readResourceID work for the relational store?
> Is a resource also stored explicitly?
Yes, a CDOResource implements Resource, Resource.Internal,
InternalCDOObject and InternalEObject. As a consequence it has all the
behaviour of other CDOObjects, i.e. it is persistent. Of course you
can't nest them. See them as a sort of named entry points into the
persistent object wood (multi tree) of a CDO repository. As a CDOObject
a CDOResource also has a CDOID which is used by references from other
objects (eContainer, but could also be normal named xrefs). The "path"
of a CDOResource is only used when creating/loading the resource into a
CDOView. Then IStoreReader.readResourceID(String path) is needed to
determine the real PK of the resource object.
> - I see that each object has a CDOID, which has an internal value of
> long (correct?), this means that composite or String primary keys are
> not supported?
Not at the moment, but I already had discussions with Simon about
possibilities to transfer the responsibility for CDOID creation from the
repository into the store. In fact this has already happened, but the
store is currently not allowed to break the contract of the
CDOID.getValue() API.
>
> It would not be to difficult to add Teneo here. I can also add the
> hibernate initialization code. To get a testcase up and running, can I
> use the standalone code you specified earlier for this?
Yes, that should basically work. I'm already curious ;-)
> I can get the epackage from the cdopackageregistry?
Only if you previously registered it in the same CDOSession or if you
previously registered in in another session and committed it to the
repository (then a CDOPackageDescriptor is automatically registered with
the CDOPackageRegistry of the new session).
I know this is a lot of stuff, but I'm sure that you'll find it logical
if work with it a bit. I think it'd be a good idea to play a bit with
the CDO UI, i.e. the CDO Sessions viewpart and the CDOEditor. Tell me if
you need help with it.
Cheers and good night ;-)
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi Martin,
>>
>> I've just committed a first version of a plugin to the CVS:
>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>>
>>
>> It contains my CDORevisionTuplizer and a skeleton implementation of
>> CDOs storage framework.
>> I think this is a good point to start from. The obvious places with
>> missing code (19x) are marked // TODO Implement me
>>
>> The 2 main classes to fill with functionality are:
>> - HibernateStoreReader
>> - HibernateStoreWriter
>>
>> We can ignore HibernateStoreChunkReader at the beginning.
>> I'm sure I can help with the missing functionality, but I have no
>> clue how to connect the pieces.
>> May be you get an idea when looking at the project...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>> Eike Stepper schrieb:
>>> I'd like to start a new thread here which can be used to discuss the
>>> given topic.
>>>
>>> I'll start to write some sub threads, mainly with questions about
>>> Hibernate details...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>
>
|
|
|
Re: Skeleton Implementation [message #111180 is a reply to message #111170] |
Thu, 31 January 2008 08:25 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my remarks/questions below.
A new question: when the client commits its transaction the objects are sent to the cdo server and
de-serialized to cdoobjects/cdorevisions. These objects are then persisted. After the persist step
are the cdoobjects/cdorevisions discarded or are they kept in-memory (so the server keeps state
between commit transactions)?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> I checked the project out and the related projects. I must say that
>> you are quick :-).
> I give my best ;-)
>
>> I looked through the code. A few questions/remarks:
>> - Can you explain how the version number works in the relational db
>> store you have. I mean specifically for foreign keys, for example if
>> an object A refers to B and I store a new version of B, to which
>> version does A then point?
> The version is never part of reference information.
> As you'll have noticed a CDOObject is just a thin wrapper for a
> CDORevision, which is identified by CDOID and version. It's the task of
> a "view" to associate objects with the correct revision. This depends on
> the type of view, CDOView and CDOTransaction deliver always the latest
> revision (determined by revised==null) and CDOAudit delivers a revision
> where the timeStamp of the view (audit) is between the "created" and
> "revised" values of the revision.
MT>> As it interests me how you did this I'll bug you with some more questions :-): what I
understand is that in audit mode the different versions of one object are stored in the same table.
In the database do the foreign key constraints contain the version also?
Old versions of a deleted object are also present in the db, I assume? How do you prevent queries
from returning old versions of deleted objects (maybe maintain a deleted flag in all versions?)?
Do you keep a flag in the db which keeps track of the last version of each object, so that it is
possible to easily query for the last version?
>
> All this is not important if we decide to ignore the auditing mode. Then
> we (hibernate) would use the version of the revision only for optimistic
> locking.
>
>> - when is the writepackage method called? The ecore package is stored
>> in the database also in your view or can this be ignored (for now)?
> I don't think that we can ignore this.
> The method is called by the repository when it receives a
> CommitTransactionIndication (a signal over the network after the client
> committed a transaction) that contains new packages. If we ignore this
> indication the repository would later startup without knowledgeabout
> previously used packages.
MT>>
With Teneo the epackages are explicitly set by the user when the store initializes. With CDO I
understand now that you can register new epackages on the fly or when the user commits for the first
time, correct?
Is it possible for the user to specify/pass the epackages when the cdo server starts? Is there such
an explicit initialization step?
With Teneo annotations can also be specified in a separate xml file and there is a property file
which allows you to set several options. Is there a possibility to pass this information through CDO
to Teneo. For example using custom cdo properties, does cdo have a property file somewhere for
simple configuration options which can be read when the cdo server starts?
>
> I also thought about how to store the meta model. The CDO internal meta
> model is comparingly simple, it only knows about CDOPackages, CDOClasses
> and CDOFeatures. These model elements only carry information that is
> necessary for persistence aspects. I see some options:
> 1) Use Hibernate to create a static model and its mapping to a static
> schema. Ideally we could reuse the existing code (CDOPackageImpl,
> CDOClassImpl and CDOFeatureImpl). Isn't Hibernate about mapping POJOs?
> 2) Use the JDBC connection of a Hibernate session (that is used for the
> dynamic mapping) and the code from my DBStore.
> 3) Store the meta model outside of the DB within the file system. This
> creates extra configuration and runtime maintenance.
>
>> - The storewriter has a method writeRevision, with hibernate write
>> operations cascade automatically to refered-to objects, so the
>> writeRevision method will have side effects. This is no problem?
> I'm not sure that I understand this. May be I explain the semantics of
> the writeRevision() method:
> When a client modifies CDOObjects the associated CDOTransaction becomes
> dirty. The CDOTransaction remembers all modified objects (in fact it
> even temporarily stores their associated, transactional revisions). When
> the transaction is committed all the internal state of the transaction
> (particularly the transactional revisions of the modified objects) is
> transferred to the server where it is deserialized. First added packages
> are written to the store via IStoreWriter.writePackages() then each of
> the received revisions of the new/modified objects is written to the
> store via IStoreWriter.writeRevision(). No matter what kind of
> references do exist between the original objects. A CDORevision doesn't
> have Java reference handles to other CDORevisions. References between
> the original objects are completely represented as CDOIDs (see below).
MT>> I think to get this working with hibernate the propertyaccessor for a ereference property
should not return the cdoid but the cdorevision identified by the cdoid. Hibernate will then
depending on the cascade options also automatically persist the refered-to objects.
>
>> - How does storereader.readResourceID work for the relational store?
>> Is a resource also stored explicitly?
> Yes, a CDOResource implements Resource, Resource.Internal,
> InternalCDOObject and InternalEObject. As a consequence it has all the
> behaviour of other CDOObjects, i.e. it is persistent. Of course you
> can't nest them. See them as a sort of named entry points into the
> persistent object wood (multi tree) of a CDO repository. As a CDOObject
> a CDOResource also has a CDOID which is used by references from other
> objects (eContainer, but could also be normal named xrefs). The "path"
> of a CDOResource is only used when creating/loading the resource into a
> CDOView. Then IStoreReader.readResourceID(String path) is needed to
> determine the real PK of the resource object.
>
>> - I see that each object has a CDOID, which has an internal value of
>> long (correct?), this means that composite or String primary keys are
>> not supported?
> Not at the moment, but I already had discussions with Simon about
> possibilities to transfer the responsibility for CDOID creation from the
> repository into the store. In fact this has already happened, but the
> store is currently not allowed to break the contract of the
> CDOID.getValue() API.
MT>> if the getValue would return Object then this would already solve it I think. What do you think?
>
>>
>> It would not be to difficult to add Teneo here. I can also add the
>> hibernate initialization code. To get a testcase up and running, can I
>> use the standalone code you specified earlier for this?
> Yes, that should basically work. I'm already curious ;-)
MT>> I have to do a few hours of customer work, after that I can look further into how to integrate
Teneo.
>
>> I can get the epackage from the cdopackageregistry?
> Only if you previously registered it in the same CDOSession or if you
> previously registered in in another session and committed it to the
> repository (then a CDOPackageDescriptor is automatically registered with
> the CDOPackageRegistry of the new session).
>
> I know this is a lot of stuff, but I'm sure that you'll find it logical
> if work with it a bit. I think it'd be a good idea to play a bit with
> the CDO UI, i.e. the CDO Sessions viewpart and the CDOEditor. Tell me if
> you need help with it.
>
> Cheers and good night ;-)
> /Eike
>
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Hi Martin,
>>>
>>> I've just committed a first version of a plugin to the CVS:
>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>>>
>>>
>>> It contains my CDORevisionTuplizer and a skeleton implementation of
>>> CDOs storage framework.
>>> I think this is a good point to start from. The obvious places with
>>> missing code (19x) are marked // TODO Implement me
>>>
>>> The 2 main classes to fill with functionality are:
>>> - HibernateStoreReader
>>> - HibernateStoreWriter
>>>
>>> We can ignore HibernateStoreChunkReader at the beginning.
>>> I'm sure I can help with the missing functionality, but I have no
>>> clue how to connect the pieces.
>>> May be you get an idea when looking at the project...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>>>
>>>
>>> Eike Stepper schrieb:
>>>> I'd like to start a new thread here which can be used to discuss the
>>>> given topic.
>>>>
>>>> I'll start to write some sub threads, mainly with questions about
>>>> Hibernate details...
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111235 is a reply to message #111170] |
Thu, 31 January 2008 09:17 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------030608020900070407090304
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Eike Stepper schrieb:
> Martin Taal schrieb:
>> - I see that each object has a CDOID, which has an internal value of
>> long (correct?), this means that composite or String primary keys are
>> not supported?
> Not at the moment, but I already had discussions with Simon about
> possibilities to transfer the responsibility for CDOID creation from
> the repository into the store. In fact this has already happened, but
> the store is currently not allowed to break the contract of the
> CDOID.getValue() API.
I thought again about how to make the format of the CDOID more flexible.
The main problem I see is a deployment issue. In a client-server setup
deployment usually looks like:
CDO Client:
*org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol --> org.eclipse.net4j
--> org-eclipse.emf.ecore
*
CDO Server:
*org.eclipse.emf.cdo.server --> org.eclipse.emf.cdo.protocol -->
org.eclipse.net4j
*org.eclipse.emf.cdo.server.hibernate --> *org.eclipse.emf.cdo.server
--> org.hibernate
*
org.eclipse.emf.cdo.server.db --> *org.eclipse.emf.cdo.server
--> org.eclipse.net4j.db
** *-->
org.eclipse.net4j.db.derby --> *org.eclipse.net4j.db*
* *-->
org.eclipse.net4j.db.mysql --> *org.eclipse.net4j.db*
* *-->
org.eclipse.net4j.db.hsqldb --> *org.eclipse.net4j.db*
org.eclipse.emf.cdo.server.oodb --> *org.eclipse.emf.cdo.server
--> com.objectivity
*/*bold = mandatory plugins*
non-bold = optional plugins with extensions
/
The org.eclipse.emf.cdo.protocol plugin is the lowest dependency level
in the CDO plugin stack. It has no dependency on Ecore!!! Here the
following basic concepts are defined:
1) [internal part] The name of the *CDO Protocol* and the IDs of the
particular *Net4j Signals* being exchanged between client side and
server side of the protocol. With Net4j signals you can implement an
asymmetrical protocol (like the CDO protocol) by having different
implementations on client side (extends Request or
RequestWithConfirmation) and on server side (extends Indication or
IndicationWithResponse). The implementations of the signals get a
DataOutputStream and/or a DataInputStream passed by the Net4j signalling
framework. The protocol itself is automatically associated with a Net4j
IChannel, which represents a logical connection between client and
server, multiplexed through an IConnector as the physical connection.
The signals are also multiplexed through one IChannel so they can be
transmitted and received at any point in time. Internally Net4j
transport works with DirectByteBuffers and is completely asynchron, this
makes two-level multiplexing fast and reliable. By using the signalling
framework a protocol implementor can nevertheless code the actual
communications use cases (each being implemented as a pair of Signal
classes) against a streaming API and doesn't have tobother with
threading strategies.
|*public interface *CDOProtocolConstants
{
*public static final *String PROTOCOL_NAME = "cdo";
*public static final **short *SIGNAL_OPEN_SESSION = 1;
*public static final **short *SIGNAL_VIEWS_CHANGED = 2;
*public static final **short *SIGNAL_RESOURCE_ID = 3;
*public static final **short *SIGNAL_RESOURCE_PATH = 4;
*public static final **short *SIGNAL_LOAD_PACKAGE = 5;
*public static final **short *SIGNAL_LOAD_REVISION = 6;
*public static final **short *SIGNAL_LOAD_REVISION_BY_TIME = 7;
*public static final **short *SIGNAL_LOAD_REVISION_BY_VERSION = 8;
*public static final **short *SIGNAL_LOAD_CHUNK = 9;
*public static final **short *SIGNAL_VERIFY_REVISION = 10;
*public static final **short *SIGNAL_QUERY_OBJECT_TYPES = 11;
*public static final **short *SIGNAL_COMMIT_TRANSACTION = 12;
*public static final **short *SIGNAL_INVALIDATION = 13;
*public static final **int *ERROR_REPOSITORY_NOT_FOUND = -1;
*public static final **int *ERROR_NO_SESSION = -2;
*public static final **byte *VIEW_TRANSACTION = 1;
*public static final **byte *VIEW_AUDIT = 2;
*public static final **byte *VIEW_READONLY = 3;
*public static final **byte *VIEW_CLOSED = 4;
}|
2) *CDOID *is the interface for persistent object identifiers.
Internally it's represented by a long integer. Important methods are
isTemporary() and isMeta(). Temporary CDOIDs (meta or not) are created
at client side for new objects in a transaction. Meta CDOIDs (temporary
or not) identify the EModelElements contained in the used EPackages. The
four possible combinations of temporary and meta are coded into long
integer value, temporary IDs are negative, non-temporary IDs are
positive, NULL is zero, meta IDs are odd, non-meta IDs are even. This
way all operations, including network transfer, of CDOIDs are possible
and very efficient. There is also the sub interface *CDOIDTyped *which
is only needed for sessions with legacy support. Legacy models are those
models that haven't been generated for CDO and as a consequence must
cope with eager instantiation of EMF proxies. To be able to instantiate
an EMF proxy for an object identified by a CDOID the CDO client
framework must know about the EClass of that object (CDO native models
don't need that, the pure CDOID value is sufficient because no class of
the model is eagerly created). A CDOIDTyped contains the needed type
information in addition to the ID value. Both types have streaming API
so that they can easily being transferred through protocol signals.
|*public interface *CDOID *extends *Comparable<CDOID>
{
*public static final *CDOID NULL = *new *CDOIDNull();
*public **long *getValue();
*public **boolean *isNull();
*public **boolean *isTemporary();
*public **boolean *isMeta();
*public *CDOID getNext();
}|
|*public interface *CDOIDTyped *extends *CDOID
{
*public *CDOClassRef getType();
}|
3) *CDOPackageManager*, *CDOPackage*, *CDOClass* and *CDOFeature *model
and manage a meta model that corresponds to an EPackage on client side.
CDOPackages are identified by packageURI, CDOClasses by classifierID and
CDOFeatures by featureID. These identifiers are the same as their Ecore
pendants and ensure convertability to Ecore EModelElements and vice
versa. All CDOModelElements have streaming API so that they can easily
being transferred through protocol signals. There are the two system
packages CDOCorePackage and CDOResourcePackage which contain the classes
CDOObjectClass and CDOResourceClass.
|*public interface *CDOPackageManager *extends *IContainer<CDOPackage>
{
*public **int *getPackageCount();
*public *CDOPackage[] getPackages();
*public *CDOPackage lookupPackage(String packageURI);
*public *CDOCorePackage getCDOCorePackage();
*public *CDOResourcePackage getCDOResourcePackage();
}|
|*public interface *CDOPackage *extends *CDOModelElement, Comparable<CDOPackage>
{
*public *CDOPackageManager getPackageManager();
*public *String getPackageURI();
*public **int *getClassCount();
*public *CDOClass[] getClasses();
*public *CDOClass[] getConcreteClasses();
*public *CDOClass lookupClass(*int *classifierID);
*public *String getEcore();
*public **boolean *isSystem();
*public **boolean *isDynamic();
*public **boolean *isProxy();
*public **boolean *isPersistent();
*public *CDOIDRange getMetaIDRange();
}|
|*public interface *CDOClass *extends *CDOModelElement, Comparable<CDOClass>
{
*public **int *getClassifierID();
*public **boolean *isAbstract();
*public **boolean *isResource();
*public **boolean *isRoot();
*public **int *getSuperTypeCount();
*public *CDOClass getSuperType(*int *index);
*public *CDOClass[] getSuperTypes();
*public *CDOClass[] getAllSuperTypes();
*public **int *getFeatureCount();
*public *CDOFeature lookupFeature(*int *featureID);
*public *CDOFeature lookupFeature(String name);
*public *CDOFeature[] getFeatures();
*public *CDOFeature[] getAllFeatures();
*public *CDOClassRef createClassRef();
*public *CDOPackage getContainingPackage();
}|
|*public interface *CDOFeature *extends *CDOModelElement
{
*public **int *getFeatureID();
*public **int *getFeatureIndex();
*public *CDOType getType();
*public **boolean *isMany();
*public **boolean *isReference();
*public **boolean *isContainment();
*public *CDOClass getReferenceType();
*public *CDOClass getContainingClass();
*public *CDOPackage getContainingPackage();
}|
4) *CDORevision *and *CDORevisionData *represent an immutable state of
an object during a defined timespan. This timespan is demarkated by
"created", which is the timestamp of the commit-transaction operation
that created the revision, and "revised", which is the timestamp - 1 of
the commit-transaction operation that created the next revision. The
"version" is incremented with each new revision. Each CDORevision also
carries the CDOID of its object and a java reference to the CDOClass of
its object. While the internal information is represented by CDORevision
the actual data of the the object is represented by CDORevisionData
which looks a bit similar to the EStore interface with the object handle
missing from the signatures! A CDORevisionResolver manages/caches
CDORevisions so that the important getRevisionXYZ() methods are
efficient. There are different subclasses on client and on server side,
depending onhow to reload missing revisions into the cache. The client
will request them via Net4j signals from the server and the server will
read them via IStoreReader from its store. There are also
CDORevisionDeltas that can result from client side transactions or the
CDORevision.compare() method. I'll postpone this disccusion ;-)
|*public interface *CDORevisionResolver
{
*public *CDOClass getObjectType(CDOID id);
*public **boolean *containsRevision(CDOID id);
*public **boolean *containsRevisionByTime(CDOID id, *long *timeStamp);
*public *CDORevision getRevision(CDOID id, *int *referenceChunk);
*public *CDORevision getRevisionByTime(CDOID id, *int *referenceChunk, *long *timeStamp);
*public *CDORevision getRevisionByVersion(CDOID id, *int *referenceChunk, *int *version);
*public *List<CDORevision> getRevisions(Collection<CDOID> ids, *int *referenceChunk);
*public *List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, *int *referenceChunk, *long *timeStamp);
*public *CDOID resolveReferenceProxy(CDOReferenceProxy referenceProxy);
*public *List<Integer> analyzeReferenceRanges(List<Object> list);
}|
|*public interface *CDORevision
{
*public static final **long *UNSPECIFIED_DATE = 0;
*public static final **int *UNCHUNKED = -1;
*public *CDORevisionResolver getRevisionResolver();
*public *CDOClass getCDOClass();
*public *CDOID getID();
*public **int *getVersion();
*public **long *getCreated();
*public **long *getRevised();
*public **boolean *isCurrent();
*public **boolean *isValid(*long *timeStamp);
*public **boolean *isTransactional();
*public **boolean *isResource();
*public *CDORevisionData getData();
*public *CDORevisionDelta compare(CDORevision origin);
*public **void *merge(CDORevisionDelta delta);
*public **void *write(ExtendedDataOutput out, CDOIDProvider idProvider, *int *referenceChunk) *throws *IOException;
}|
|*public interface *CDORevisionData
{
*public *CDORevision getRevision();
*public *CDOID getResourceID();
*public *CDOID getContainerID();
*public **int *getContainingFeatureID();
*public *Object get(CDOFeature feature, *int *index);
*public **int *size(CDOFeature feature);
*public **boolean *isEmpty(CDOFeature feature);
*public **boolean *contains(CDOFeature feature, Object value);
*public **int *indexOf(CDOFeature feature, Object value);
*public **int *lastIndexOf(CDOFeature feature, Object value);
*public **boolean *isSet(CDOFeature feature);
*public *<T> T[] toArray(CDOFeature feature, T[] array);
*public *Object[] toArray(CDOFeature feature);
*public **int *hashCode(CDOFeature feature);
}|
Ok, this was lots of information ;-)
Now back to the problem with the store-defined CDOID format.
Currently CDOIDImpl is part of the protocol plugin and thus deployed to
both client and server. If we give the store (only deployed to the
server) the capability to instantiate other implementations of CDOID we
need to deploy that code also to the client. The client should per
definition not be aware of implementation details of the repository! We
could try to make the internal format of a CDOID more flexible (a Map or
an array or whatever) but this flexible implementation should be part of
the protocol plugin.
Cheers
/Eike
--------------030608020900070407090304
Content-Type: multipart/related;
boundary="------------070300060607030406090005"
--------------070300060607030406090005
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Eike Stepper schrieb:
<blockquote cite="mid:fnr1bf$uqk$1@build.eclipse.org" type="cite">Martin
Taal schrieb:
<br>
<blockquote type="cite">- I see that each object has a CDOID, which
has an internal value of long (correct?), this means that composite or
String primary keys are not supported?
<br>
</blockquote>
Not at the moment, but I already had discussions with Simon about
possibilities to transfer the responsibility for CDOID creation from
the repository into the store. In fact this has already happened, but
the store is currently not allowed to break the contract of the
CDOID.getValue() API.
<br>
</blockquote>
I thought again about how to make the format of the CDOID more
flexible. The main problem I see is a deployment issue. In a
client-server setup deployment usually looks like:<br>
<br>
CDO Client:<br>
<b>org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol -->
org.eclipse.net4j<br>
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111280 is a reply to message #111235] |
Thu, 31 January 2008 10:17 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Indeed a fair amount of info :-).
Btw, when an object is read from the server to the client, then how do you keep track of the cdoid
on the client? I mean how do you know that the object I persist back to the server had a certain
cdoid? If the cdoid is based on a field in the model, how do you tag this field as being the id?
(many questionmarks but I think it is all one question :-).
Hibernate only requires the id-object to be serializable. For hibernate the id is known to the
client/user of the model, I mean it is the code field in a product or the order number in an order.
In case of a composite id, the id is modelled using a class (containing the id-fields), also this
class is known to the user.
Would the requirement that the id-object is serializable help to get from the client to the server
(the client-server layer does not need to know the actual implementation)?
I understand that you code extra info in the id (making it negative or odd/even), would it be
possible to code this in a separate field?
Another possibility is to store a server side map of cdoid to hibernate id mappings. But I am not
sure how to accomplish that because this map will grow indefinitely and is difficult to prune (you
don't know which objects are still used at the client).
gr. Martin
Eike Stepper wrote:
> Eike Stepper schrieb:
>> Martin Taal schrieb:
>>> - I see that each object has a CDOID, which has an internal value of
>>> long (correct?), this means that composite or String primary keys are
>>> not supported?
>> Not at the moment, but I already had discussions with Simon about
>> possibilities to transfer the responsibility for CDOID creation from
>> the repository into the store. In fact this has already happened, but
>> the store is currently not allowed to break the contract of the
>> CDOID.getValue() API.
> I thought again about how to make the format of the CDOID more flexible.
> The main problem I see is a deployment issue. In a client-server setup
> deployment usually looks like:
>
> CDO Client:
> *org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol --> org.eclipse.net4j
> --> org-eclipse.emf.ecore
> *
> CDO Server:
> *org.eclipse.emf.cdo.server --> org.eclipse.emf.cdo.protocol -->
> org.eclipse.net4j
>
> *org.eclipse.emf.cdo.server.hibernate --> *org.eclipse.emf.cdo.server
> --> org.hibernate
> *
> org.eclipse.emf.cdo.server.db --> *org.eclipse.emf.cdo.server
> --> org.eclipse.net4j.db
> ** *-->
> org.eclipse.net4j.db.derby --> *org.eclipse.net4j.db*
> * *-->
> org.eclipse.net4j.db.mysql --> *org.eclipse.net4j.db*
> * *-->
> org.eclipse.net4j.db.hsqldb --> *org.eclipse.net4j.db*
>
> org.eclipse.emf.cdo.server.oodb --> *org.eclipse.emf.cdo.server
> --> com.objectivity
>
> */*bold = mandatory plugins*
> non-bold = optional plugins with extensions
> /
> The org.eclipse.emf.cdo.protocol plugin is the lowest dependency level
> in the CDO plugin stack. It has no dependency on Ecore!!! Here the
> following basic concepts are defined:
>
>
>
> 1) [internal part] The name of the *CDO Protocol* and the IDs of the
> particular *Net4j Signals* being exchanged between client side and
> server side of the protocol. With Net4j signals you can implement an
> asymmetrical protocol (like the CDO protocol) by having different
> implementations on client side (extends Request or
> RequestWithConfirmation) and on server side (extends Indication or
> IndicationWithResponse). The implementations of the signals get a
> DataOutputStream and/or a DataInputStream passed by the Net4j signalling
> framework. The protocol itself is automatically associated with a Net4j
> IChannel, which represents a logical connection between client and
> server, multiplexed through an IConnector as the physical connection.
> The signals are also multiplexed through one IChannel so they can be
> transmitted and received at any point in time. Internally Net4j
> transport works with DirectByteBuffers and is completely asynchron, this
> makes two-level multiplexing fast and reliable. By using the signalling
> framework a protocol implementor can nevertheless code the actual
> communications use cases (each being implemented as a pair of Signal
> classes) against a streaming API and doesn't have tobother with
> threading strategies.
>
> |*public interface *CDOProtocolConstants
> {
> *public static final *String PROTOCOL_NAME = "cdo";
>
> *public static final **short *SIGNAL_OPEN_SESSION = 1;
>
> *public static final **short *SIGNAL_VIEWS_CHANGED = 2;
>
> *public static final **short *SIGNAL_RESOURCE_ID = 3;
>
> *public static final **short *SIGNAL_RESOURCE_PATH = 4;
>
> *public static final **short *SIGNAL_LOAD_PACKAGE = 5;
>
> *public static final **short *SIGNAL_LOAD_REVISION = 6;
>
> *public static final **short *SIGNAL_LOAD_REVISION_BY_TIME = 7;
>
> *public static final **short *SIGNAL_LOAD_REVISION_BY_VERSION = 8;
>
> *public static final **short *SIGNAL_LOAD_CHUNK = 9;
>
> *public static final **short *SIGNAL_VERIFY_REVISION = 10;
>
> *public static final **short *SIGNAL_QUERY_OBJECT_TYPES = 11;
>
> *public static final **short *SIGNAL_COMMIT_TRANSACTION = 12;
>
> *public static final **short *SIGNAL_INVALIDATION = 13;
>
> *public static final **int *ERROR_REPOSITORY_NOT_FOUND = -1;
>
> *public static final **int *ERROR_NO_SESSION = -2;
>
> *public static final **byte *VIEW_TRANSACTION = 1;
>
> *public static final **byte *VIEW_AUDIT = 2;
>
> *public static final **byte *VIEW_READONLY = 3;
>
> *public static final **byte *VIEW_CLOSED = 4;
> }|
>
>
> 2) *CDOID *is the interface for persistent object identifiers.
> Internally it's represented by a long integer. Important methods are
> isTemporary() and isMeta(). Temporary CDOIDs (meta or not) are created
> at client side for new objects in a transaction. Meta CDOIDs (temporary
> or not) identify the EModelElements contained in the used EPackages. The
> four possible combinations of temporary and meta are coded into long
> integer value, temporary IDs are negative, non-temporary IDs are
> positive, NULL is zero, meta IDs are odd, non-meta IDs are even. This
> way all operations, including network transfer, of CDOIDs are possible
> and very efficient. There is also the sub interface *CDOIDTyped *which
> is only needed for sessions with legacy support. Legacy models are those
> models that haven't been generated for CDO and as a consequence must
> cope with eager instantiation of EMF proxies. To be able to instantiate
> an EMF proxy for an object identified by a CDOID the CDO client
> framework must know about the EClass of that object (CDO native models
> don't need that, the pure CDOID value is sufficient because no class of
> the model is eagerly created). A CDOIDTyped contains the needed type
> information in addition to the ID value. Both types have streaming API
> so that they can easily being transferred through protocol signals.
>
> |*public interface *CDOID *extends *Comparable<CDOID>
> {
> *public static final *CDOID NULL = *new *CDOIDNull();
>
> *public **long *getValue();
>
> *public **boolean *isNull();
>
> *public **boolean *isTemporary();
>
> *public **boolean *isMeta();
>
> *public *CDOID getNext();
> }|
>
>
> |*public interface *CDOIDTyped *extends *CDOID
> {
> *public *CDOClassRef getType();
> }|
>
>
> 3) *CDOPackageManager*, *CDOPackage*, *CDOClass* and *CDOFeature *model
> and manage a meta model that corresponds to an EPackage on client side.
> CDOPackages are identified by packageURI, CDOClasses by classifierID and
> CDOFeatures by featureID. These identifiers are the same as their Ecore
> pendants and ensure convertability to Ecore EModelElements and vice
> versa. All CDOModelElements have streaming API so that they can easily
> being transferred through protocol signals. There are the two system
> packages CDOCorePackage and CDOResourcePackage which contain the classes
> CDOObjectClass and CDOResourceClass.
>
> |*public interface *CDOPackageManager *extends *IContainer<CDOPackage>
> {
> *public **int *getPackageCount();
>
> *public *CDOPackage[] getPackages();
>
> *public *CDOPackage lookupPackage(String packageURI);
>
> *public *CDOCorePackage getCDOCorePackage();
>
> *public *CDOResourcePackage getCDOResourcePackage();
> }|
>
>
> |*public interface *CDOPackage *extends *CDOModelElement, Comparable<CDOPackage>
> {
> *public *CDOPackageManager getPackageManager();
>
> *public *String getPackageURI();
>
> *public **int *getClassCount();
>
> *public *CDOClass[] getClasses();
>
> *public *CDOClass[] getConcreteClasses();
>
> *public *CDOClass lookupClass(*int *classifierID);
>
> *public *String getEcore();
>
> *public **boolean *isSystem();
>
> *public **boolean *isDynamic();
>
> *public **boolean *isProxy();
>
> *public **boolean *isPersistent();
>
> *public *CDOIDRange getMetaIDRange();
> }|
>
>
> |*public interface *CDOClass *extends *CDOModelElement, Comparable<CDOClass>
> {
> *public **int *getClassifierID();
>
> *public **boolean *isAbstract();
>
> *public **boolean *isResource();
>
> *public **boolean *isRoot();
>
> *public **int *getSuperTypeCount();
>
> *public *CDOClass getSuperType(*int *index);
>
> *public *CDOClass[] getSuperTypes();
>
> *public *CDOClass[] getAllSuperTypes();
>
> *public **int *getFeatureCount();
>
> *public *CDOFeature lookupFeature(*int *featureID);
>
> *public *CDOFeature lookupFeature(String name);
>
> *public *CDOFeature[] getFeatures();
>
> *public *CDOFeature[] getAllFeatures();
>
> *public *CDOClassRef createClassRef();
>
> *public *CDOPackage getContainingPackage();
> }|
>
>
> |*public interface *CDOFeature *extends *CDOModelElement
> {
> *public **int *getFeatureID();
>
> *public **int *getFeatureIndex();
>
> *public *CDOType getType();
>
> *public **boolean *isMany();
>
> *public **boolean *isReference();
>
> *public **boolean *isContainment();
>
> *public *CDOClass getReferenceType();
>
> *public *CDOClass getContainingClass();
>
> *public *CDOPackage getContainingPackage();
> }|
>
>
> 4) *CDORevision *and *CDORevisionData *represent an immutable state of
> an object during a defined timespan. This timespan is demarkated by
> "created", which is the timestamp of the commit-transaction operation
> that created the revision, and "revised", which is the timestamp - 1 of
> the commit-transaction operation that created the next revision. The
> "version" is incremented with each new revision. Each CDORevision also
> carries the CDOID of its object and a java reference to the CDOClass of
> its object. While the internal information is represented by CDORevision
> the actual data of the the object is represented by CDORevisionData
> which looks a bit similar to the EStore interface with the object handle
> missing from the signatures! A CDORevisionResolver manages/caches
> CDORevisions so that the important getRevisionXYZ() methods are
> efficient. There are different subclasses on client and on server side,
> depending onhow to reload missing revisions into the cache. The client
> will request them via Net4j signals from the server and the server will
> read them via IStoreReader from its store. There are also
> CDORevisionDeltas that can result from client side transactions or the
> CDORevision.compare() method. I'll postpone this disccusion ;-)
>
> |*public interface *CDORevisionResolver
> {
> *public *CDOClass getObjectType(CDOID id);
>
> *public **boolean *containsRevision(CDOID id);
>
> *public **boolean *containsRevisionByTime(CDOID id, *long *timeStamp);
>
> *public *CDORevision getRevision(CDOID id, *int *referenceChunk);
>
> *public *CDORevision getRevisionByTime(CDOID id, *int *referenceChunk, *long *timeStamp);
>
> *public *CDORevision getRevisionByVersion(CDOID id, *int *referenceChunk, *int *version);
>
> *public *List<CDORevision> getRevisions(Collection<CDOID> ids, *int *referenceChunk);
>
> *public *List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, *int *referenceChunk, *long *timeStamp);
>
> *public *CDOID resolveReferenceProxy(CDOReferenceProxy referenceProxy);
>
> *public *List<Integer> analyzeReferenceRanges(List<Object> list);
> }|
>
>
> |*public interface *CDORevision
> {
> *public static final **long *UNSPECIFIED_DATE = 0;
>
> *public static final **int *UNCHUNKED = -1;
>
> *public *CDORevisionResolver getRevisionResolver();
>
> *public *CDOClass getCDOClass();
>
> *public *CDOID getID();
>
> *public **int *getVersion();
>
> *public **long *getCreated();
>
> *public **long *getRevised();
>
> *public **boolean *isCurrent();
>
> *public **boolean *isValid(*long *timeStamp);
>
> *public **boolean *isTransactional();
>
> *public **boolean *isResource();
>
> *public *CDORevisionData getData();
>
> *public *CDORevisionDelta compare(CDORevision origin);
>
> *public **void *merge(CDORevisionDelta delta);
>
> *public **void *write(ExtendedDataOutput out, CDOIDProvider idProvider, *int *referenceChunk) *throws *IOException;
> }|
>
>
> |*public interface *CDORevisionData
> {
> *public *CDORevision getRevision();
>
> *public *CDOID getResourceID();
>
> *public *CDOID getContainerID();
>
> *public **int *getContainingFeatureID();
>
> *public *Object get(CDOFeature feature, *int *index);
>
> *public **int *size(CDOFeature feature);
>
> *public **boolean *isEmpty(CDOFeature feature);
>
> *public **boolean *contains(CDOFeature feature, Object value);
>
> *public **int *indexOf(CDOFeature feature, Object value);
>
> *public **int *lastIndexOf(CDOFeature feature, Object value);
>
> *public **boolean *isSet(CDOFeature feature);
>
> *public *<T> T[] toArray(CDOFeature feature, T[] array);
>
> *public *Object[] toArray(CDOFeature feature);
>
> *public **int *hashCode(CDOFeature feature);
> }|
>
>
>
>
> Ok, this was lots of information ;-)
> Now back to the problem with the store-defined CDOID format.
>
> Currently CDOIDImpl is part of the protocol plugin and thus deployed to
> both client and server. If we give the store (only deployed to the
> server) the capability to instantiate other implementations of CDOID we
> need to deploy that code also to the client. The client should per
> definition not be aware of implementation details of the repository! We
> could try to make the internal format of a CDOID more flexible (a Map or
> an array or whatever) but this flexible implementation should be part of
> the protocol plugin.
>
> Cheers
> /Eike
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation [message #111295 is a reply to message #111180] |
Thu, 31 January 2008 10:25 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------060102040105060602010609
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> See my remarks/questions below.
>
> A new question: when the client commits its transaction the objects
> are sent to the cdo server and de-serialized to
> cdoobjects/cdorevisions. These objects are then persisted. After the
> persist step are the cdoobjects/cdorevisions discarded or are they
> kept in-memory (so the server keeps state between commit transactions)?
CDOObjects are EMF-dependent and only known to the client. Each
CDOObject has an association to a CDORevision which is EMF-independent
an can be transferred over the network to the server. The server
(repository) passes the revisions to the store to persist them and is
also allowed to cache them. IRepository is like a thin facade for
different manager facilities. The IRevisionManager is responsible for
all the revision handling in the server. The default implementation has
a configurable fixed size cache built in.
So, yes and no. The stored revisions can remain in memory but need not.
In general I'd expect written revisions to remain in memory for a
certain period in time. But as the server load grows...
>> The version is never part of reference information.
>> As you'll have noticed a CDOObject is just a thin wrapper for a
>> CDORevision, which is identified by CDOID and version. It's the task
>> of a "view" to associate objects with the correct revision. This
>> depends on the type of view, CDOView and CDOTransaction deliver
>> always the latest revision (determined by revised==null) and CDOAudit
>> delivers a revision where the timeStamp of the view (audit) is
>> between the "created" and "revised" values of the revision.
> MT>> As it interests me how you did this I'll bug you with some more
> questions :-): what I understand is that in audit mode the different
> versions of one object are stored in the same table. In the database
> do the foreign key constraints contain the version also?
In fact the DBStore doesn't add real foreign key constraints to the
tables but manages them implicitely. For simplicity reasons we can
assume there were real constraints. Then these constraints would not
contain the version column! If they did instead, all referers of a
modified object (new revision with ++version) would have to be notified
and theeir table rows updated accordingly, which would clearly not scale
so well ;-)
> Old versions of a deleted object are also present in the db, I assume?
Basically depends on the auditing mode of the repository/store. When
auditing is switched off (which is currently not possible with the
DBStore) there is no need to store old revisions. If auditing is
switched on they are there.
> How do you prevent queries from returning old versions of deleted
> objects (maybe maintain a deleted flag in all versions?)?
Depends on what you mean by "queries" ;-)
The client side API currently doesn't support querying in the sense of
HQL, OCL, SQL, etc.
The only queries implemented by the framework (IStores) are
| *public *CDORevision getRevision(*CDOID id*, *int *referenceChunk);
*public *CDORevision getRevisionByTime(*CDOID id*, *int *referenceChunk, *long timeStamp*);
*public *CDORevision getRevisionByVersion(*CDOID id*, *int *referenceChunk, *int version*);|
If an object is deleted (removed from the CDOView/ResourceSet) the
DBStore writes the timestamp of the commit-operation into the "revised"
column of the latest revision (the only one with a null value in the
revised column previously). This way the object is excluded from all
read-only views and transactional views. Only auditing views could catch
that revision (if the audit timestamp is between the "created" and
"revised" value of the revision) and thus deliver an object for it.
> Do you keep a flag in the db which keeps track of the last version of
> each object, so that it is possible to easily query for the last version?
Latest (undeleted) revision of an object has a null value in the revised
column.
>> All this is not important if we decide to ignore the auditing mode.
>> Then we (hibernate) would use the version of the revision only for
>> optimistic locking.
>>
>>> - when is the writepackage method called? The ecore package is
>>> stored in the database also in your view or can this be ignored (for
>>> now)?
>> I don't think that we can ignore this.
>> The method is called by the repository when it receives a
>> CommitTransactionIndication (a signal over the network after the
>> client committed a transaction) that contains new packages. If we
>> ignore this indication the repository would later startup without
>> knowledgeabout previously used packages.
>
> MT>>
> With Teneo the epackages are explicitly set by the user when the store
> initializes. With CDO I understand now that you can register new
> epackages on the fly or when the user commits for the first time,
> correct?
Exactly. A CDO Model Repository manages/stores the meta models along
with the depending models. No need for the client to anticipate which
packages have to be registered before lazy loading can be attempted.
> Is it possible for the user to specify/pass the epackages when the cdo
> server starts? Is there such an explicit initialization step?
I never tried it but the IRepository facade has a CDOPackageManager
associated which could be used to register packages via CDO API.
Basically my opinion is that this is an admin task (I guess you meant
that with "user") and the easiest way (EPackage-based instead of
CDOPackage-based) is to open a normal CDOSession (could be embedded in
the server) and start a transaction to commit the packages.
> With Teneo annotations can also be specified in a separate xml file
> and there is a property file which allows you to set several options.
> Is there a possibility to pass this information through CDO to Teneo.
> For example using custom cdo properties, does cdo have a property file
> somewhere for simple configuration options which can be read when the
> cdo server starts?
I knew this would become a semantical challenge ;-)
Technically there's the possibility to query the whole serialized XML
string of the EPackage definition, including EAnnotations. If we make
the org.eclipse.emf.cdo.server.hibernate plugin dependent on Ecore we
could easily process this information in IStoreWriter.writePackages().
Do you think this is sufficient?
>>> - The storewriter has a method writeRevision, with hibernate write
>>> operations cascade automatically to refered-to objects, so the
>>> writeRevision method will have side effects. This is no problem?
>> I'm not sure that I understand this. May be I explain the semantics
>> of the writeRevision() method:
>> When a client modifies CDOObjects the associated CDOTransaction
>> becomes dirty. The CDOTransaction remembers all modified objects (in
>> fact it even temporarily stores their associated, transactional
>> revisions). When the transaction is committed all the internal state
>> of the transaction (particularly the transactional revisions of the
>> modified objects) is transferred to the server where it is
>> deserialized. First added packages are written to the store via
>> IStoreWriter.writePackages() then each of the received revisions of
>> the new/modified objects is written to the store via
>> IStoreWriter.writeRevision(). No matter what kind of references do
>> exist between the original objects. A CDORevision doesn't have Java
>> reference handles to other CDORevisions. References between the
>> original objects are completely represented as CDOIDs (see below).
>
> MT>> I think to get this working with hibernate the propertyaccessor
> for a ereference property should not return the cdoid but the
> cdorevision identified by the cdoid. Hibernate will then depending on
> the cascade options also automatically persist the refered-to objects.
I think this cascading thing is also done by the CDO client and it would
be best to disable this feature of Hibernate. Is that possible?
Although I'm absolutely not sure what exactly Hibernate assumes a
"proxy" to be, I thought we could use the CDOID of the target object
(which we simply have in the source revision) as a kind of pseudo proxy
and let it resolve through the IRevisionManager if needed. Thoughts?
>>> - I see that each object has a CDOID, which has an internal value of
>>> long (correct?), this means that composite or String primary keys
>>> are not supported?
>> Not at the moment, but I already had discussions with Simon about
>> possibilities to transfer the responsibility for CDOID creation from
>> the repository into the store. In fact this has already happened, but
>> the store is currently not allowed to break the contract of the
>> CDOID.getValue() API.
>
> MT>> if the getValue would return Object then this would already solve
> it I think. What do you think?
See my other (long) posting ;-)
Cheers
/Eike
--------------060102040105060602010609
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
See my remarks/questions below.
<br>
<br>
A new question: when the client commits its transaction the objects are
sent to the cdo server and de-serialized to cdoobjects/cdorevisions.
These objects are then persisted. After the persist step are the
cdoobjects/cdorevisions discarded or are they kept in-memory (so the
server keeps state between commit transactions)?
<br>
</blockquote>
CDOObjects are EMF-dependent and only known to the client. Each
CDOObject has an association to a CDORevision which is EMF-independent
an can be transferred over the network to the server. The server
(repository) passes the revisions to the store to persist them and is
also allowed to cache them. IRepository is like a thin facade for
different manager facilities. The IRevisionManager is responsible for
all the revision handling in the server. The default implementation has
a configurable fixed size cache built in.<br>
<br>
So, yes and no. The stored revisions can remain in memory but need not.
In general I'd expect written revisions to remain in memory for a
certain period in time. But as the server load grows...<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">
<blockquote type="cite">The version is never part of reference
information.
<br>
As you'll have noticed a CDOObject is just a thin wrapper for a
CDORevision, which is identified by CDOID and version. It's the task of
a "view" to associate objects with the correct revision. This depends
on the type of view, CDOView and CDOTransaction deliver always the
latest revision (determined by revised==null) and CDOAudit delivers a
revision where the timeStamp of the view (audit) is between the
"created" and "revised" values of the revision.
<br>
</blockquote>
MT>> As it interests me how you did this I'll bug you with some
more questions :-): what I understand is that in audit mode the
different versions of one object are stored in the same table. In the
database do the foreign key constraints contain the version also?
<br>
</blockquote>
In fact the DBStore doesn't add real foreign key constraints to the
tables but manages them implicitely. For simplicity reasons we can
assume there were real constraints. Then these constraints would not
contain the version column! If they did instead, all referers of a
modified object (new revision with ++version) would have to be notified
and theeir table rows updated accordingly, which would clearly not
scale so well ;-)<br>
<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">Old
versions of a deleted object are also present in the db, I assume? </blockquote>
Basically depends on the auditing mode of the repository/store. When
auditing is switched off (which is currently not possible with the
DBStore) there is no need to store old revisions. If auditing is
switched on they are there.<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">How
do you prevent queries from returning old versions of deleted objects
(maybe maintain a deleted flag in all versions?)?
<br>
</blockquote>
Depends on what you mean by "queries" ;-)<br>
The client side API currently doesn't support querying in the sense of
HQL, OCL, SQL, etc.<br>
The only queries implemented by the framework (IStores) are <br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#ffffff">
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111323 is a reply to message #111280] |
Thu, 31 January 2008 10:40 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------010507060809090300030603
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Indeed a fair amount of info :-).
> Btw, when an object is read from the server to the client, then how do
> you keep track of the cdoid on the client? I mean how do you know that
> the object I persist back to the server had a certain cdoid? If the
> cdoid is based on a field in the model, how do you tag this field as
> being the id?
> (many questionmarks but I think it is all one question :-).
Hehe, but there's a wrong assumption: The CDOID is not part of the model
because it is a technical information. Nevertheless it is stored in each
CDOObjectImpl:
|*public class *CDOObjectImpl *extends *EStoreEObjectImpl *implements *InternalCDOObject
{
*private static final *ContextTracer TRACER = *new *ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.*class*);
*_private CDOID id;
_*
*private *CDOState state;
*private *CDOResourceImpl resource;
*private *InternalCDORevision revision;
*public *CDOObjectImpl()
{
state = CDOState.TRANSIENT;
eContainer = *null*;
}
// ...|
If the genmodel contains "Root Extends Interface =
org.eclipse.emf.cdo.CDOObject", which is the default, then the user can
query it via the generated public API:
|*public interface *CDOObject *extends *EObject
{
*public *CDOClass cdoClass();
*_public CDOID cdoID();_*
*public *CDOState cdoState();
*public *CDOView cdoView();
*public *CDOResource cdoResource();
*public *CDORevision cdoRevision();
*public **void *cdoReload();
}|
> Hibernate only requires the id-object to be serializable. For
> hibernate the id is known to the client/user of the model, I mean it
> is the code field in a product or the order number in an order. In
> case of a composite id, the id is modelled using a class (containing
> the id-fields), also this class is known to the user.
It's easy to make CDOID serializable. Should we (I) start with that?
> Would the requirement that the id-object is serializable help to get
> from the client to the server (the client-server layer does not need
> to know the actual implementation)?
Wouldn't that require the client to have the actual .class file(s) of
the implementation deployed and accessible?
That's the real problem because a client doesn't know in general about
the store implementation of a repository.
May be we could transfer the needed .class files from the server to the
client with the OpenSessionResponse...
>
> I understand that you code extra info in the id (making it negative or
> odd/even), would it be possible to code this in a separate field?
Absolutely! This is just an optimization that a store would be free to
apply or not - if we move the responsibility for the CDOID format to the
store.
> Another possibility is to store a server side map of cdoid to
> hibernate id mappings. But I am not sure how to accomplish that
> because this map will grow indefinitely and is difficult to prune (you
> don't know which objects are still used at the client).
I already had this mechanism once and removed it again due to user
complaints ;-)
We should avoid this extra mapping.
Cheers
/Eike
--------------010507060809090300030603
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fns77o$7mu$1@build.eclipse.org" type="cite">Indeed
a fair amount of info :-).
<br>
Btw, when an object is read from the server to the client, then how do
you keep track of the cdoid on the client? I mean how do you know that
the object I persist back to the server had a certain cdoid? If the
cdoid is based on a field in the model, how do you tag this field as
being the id?
<br>
(many questionmarks but I think it is all one question :-).
<br>
</blockquote>
Hehe, but there's a wrong assumption: The CDOID is not part of the
model because it is a technical information. Nevertheless it is stored
in each CDOObjectImpl:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111350 is a reply to message #111323] |
Thu, 31 January 2008 10:58 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
So we can assume that all model objects inherit from CDOObject and have a cdoid member?
Related to your remark that the client should know the class of the id. Afaics this is no problem as
in case of hibernate the id is often (let's say always :-) an explicit field in the model (even if
it is a composite id). So the client always knows about it anyway. Hibernate has the concept of
synthetic id's (as I remember) but these map to the current cdoid anyway.
As far as I can see the following changes (please correct me here) should make it all very mappable
to hibernate (with explicit primary keys):
- change the type of the value in the cdoid to serializable
- move the extra information coded in the value field in cdoid to a separate field
The cdoid can then be constructed from the hibernate id object and vice versa.
What do you think?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Indeed a fair amount of info :-).
>> Btw, when an object is read from the server to the client, then how do
>> you keep track of the cdoid on the client? I mean how do you know that
>> the object I persist back to the server had a certain cdoid? If the
>> cdoid is based on a field in the model, how do you tag this field as
>> being the id?
>> (many questionmarks but I think it is all one question :-).
> Hehe, but there's a wrong assumption: The CDOID is not part of the model
> because it is a technical information. Nevertheless it is stored in each
> CDOObjectImpl:
>
> |*public class *CDOObjectImpl *extends *EStoreEObjectImpl *implements *InternalCDOObject
> {
> *private static final *ContextTracer TRACER = *new *ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.*class*);
>
> *_private CDOID id;
> _*
> *private *CDOState state;
>
> *private *CDOResourceImpl resource;
>
> *private *InternalCDORevision revision;
>
> *public *CDOObjectImpl()
> {
> state = CDOState.TRANSIENT;
> eContainer = *null*;
> }
>
> // ...|
>
>
> If the genmodel contains "Root Extends Interface =
> org.eclipse.emf.cdo.CDOObject", which is the default, then the user can
> query it via the generated public API:
>
> |*public interface *CDOObject *extends *EObject
> {
> *public *CDOClass cdoClass();
>
> *_public CDOID cdoID();_*
>
> *public *CDOState cdoState();
>
> *public *CDOView cdoView();
>
> *public *CDOResource cdoResource();
>
> *public *CDORevision cdoRevision();
>
> *public **void *cdoReload();
> }|
>
>
>> Hibernate only requires the id-object to be serializable. For
>> hibernate the id is known to the client/user of the model, I mean it
>> is the code field in a product or the order number in an order. In
>> case of a composite id, the id is modelled using a class (containing
>> the id-fields), also this class is known to the user.
> It's easy to make CDOID serializable. Should we (I) start with that?
>
>> Would the requirement that the id-object is serializable help to get
>> from the client to the server (the client-server layer does not need
>> to know the actual implementation)?
> Wouldn't that require the client to have the actual .class file(s) of
> the implementation deployed and accessible?
> That's the real problem because a client doesn't know in general about
> the store implementation of a repository.
> May be we could transfer the needed .class files from the server to the
> client with the OpenSessionResponse...
>
>>
>> I understand that you code extra info in the id (making it negative or
>> odd/even), would it be possible to code this in a separate field?
> Absolutely! This is just an optimization that a store would be free to
> apply or not - if we move the responsibility for the CDOID format to the
> store.
>
>> Another possibility is to store a server side map of cdoid to
>> hibernate id mappings. But I am not sure how to accomplish that
>> because this map will grow indefinitely and is difficult to prune (you
>> don't know which objects are still used at the client).
> I already had this mechanism once and removed it again due to user
> complaints ;-)
> We should avoid this extra mapping.
>
> Cheers
> /Eike
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111362 is a reply to message #111350] |
Thu, 31 January 2008 11:46 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> So we can assume that all model objects inherit from CDOObject and
> have a cdoid member?
Yes. If not (because the genmodel didn't specify "Root Extends Interface
= org.eclipse.emf.cdo.CDOObject") we can "downcast" the EObject to
InternalCDOObject. The recommended way to do the downcast is
InternalCDOObject cdoObject = FSMUtil.adapt(Object pojo, CDOView view);
This also considers the legacy objects (EObjects that don't extend
CDOObjectImpl). We can do this everywhere in the client. But not in the
server!
> Related to your remark that the client should know the class of the
> id. Afaics this is no problem as in case of hibernate the id is often
> (let's say always :-) an explicit field in the model (even if it is a
> composite id). So the client always knows about it anyway.
Hmm, I have the feeling that here is a misunderstanding. The fields in
the model (EAttributes/EReferences) are *only* known to the client and
not to the server! The server operates on java.lang.Object values which
in reality are of a subset of String, primitive wrappers and List (i.e.
IMoveableList).
I think we should first clarify which of the following two, completely
different, integration strategies we want to follow in the server:
1) Let Hibernate operate directly on the CDORevisions
2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
string value and use Teneo/Hibernate to map EObjects
While 2) would probably be easier to implement it seems a bit of a brute
force solution to me ;-) This would not only duplicate the footprint of
meta model and model in the server but, even worse, introduce cache
eviction issues (if ot unsolveable problems). I clearly tend to 1) until
we get the impression that we're not able to do it with Hibernate.
> Hibernate has the concept of synthetic id's (as I remember) but these
> map to the current cdoid anyway.
>
> As far as I can see the following changes (please correct me here)
> should make it all very mappable to hibernate (with explicit primary
> keys):
> - change the type of the value in the cdoid to serializable
That's easy.
> - move the extra information coded in the value field in cdoid to a
> separate field
That'd be easy although I'm a bit reluctant to force all stores touse
this new implementation. I'm still thinking about copletely
store-defined CDOID implementations...
>
> The cdoid can then be constructed from the hibernate id object and
> vice versa.
You mean there's an explicit mapping somewhere between IRepository and
IStore? Both of these entities won't like to do that because of the
scalability issues ;-(
Cheers
/Eike
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111370 is a reply to message #111362] |
Thu, 31 January 2008 12:01 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Eike Stepper schrieb:
> That'd be easy although I'm a bit reluctant to force all stores touse
> this new implementation. I'm still thinking about copletely
> store-defined CDOID implementations...
Do you know of a portable way (i.e. no class loader
overriding/intercepting) to get access to the byte[] array of a class
definition?
I couldn't find anything in the java.lang.Class API or the
java.lang.ClassLoader API ;-(
Cheers
/Eike
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111383 is a reply to message #111370] |
Thu, 31 January 2008 12:03 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Ahh, java.lang.Class implements Serializable ;-)
Eike Stepper schrieb:
> Eike Stepper schrieb:
>> That'd be easy although I'm a bit reluctant to force all stores touse
>> this new implementation. I'm still thinking about copletely
>> store-defined CDOID implementations...
> Do you know of a portable way (i.e. no class loader
> overriding/intercepting) to get access to the byte[] array of a class
> definition?
> I couldn't find anything in the java.lang.Class API or the
> java.lang.ClassLoader API ;-(
>
> Cheers
> /Eike
>
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111395 is a reply to message #111362] |
Thu, 31 January 2008 12:09 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my comments below.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> So we can assume that all model objects inherit from CDOObject and
>> have a cdoid member?
> Yes. If not (because the genmodel didn't specify "Root Extends Interface
> = org.eclipse.emf.cdo.CDOObject") we can "downcast" the EObject to
> InternalCDOObject. The recommended way to do the downcast is
> InternalCDOObject cdoObject = FSMUtil.adapt(Object pojo, CDOView view);
>
> This also considers the legacy objects (EObjects that don't extend
> CDOObjectImpl). We can do this everywhere in the client. But not in the
> server!
>
>> Related to your remark that the client should know the class of the
>> id. Afaics this is no problem as in case of hibernate the id is often
>> (let's say always :-) an explicit field in the model (even if it is a
>> composite id). So the client always knows about it anyway.
> Hmm, I have the feeling that here is a misunderstanding. The fields in
> the model (EAttributes/EReferences) are *only* known to the client and
> not to the server! The server operates on java.lang.Object values which
> in reality are of a subset of String, primitive wrappers and List (i.e.
> IMoveableList).
>
> I think we should first clarify which of the following two, completely
> different, integration strategies we want to follow in the server:
> 1) Let Hibernate operate directly on the CDORevisions
> 2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
> string value and use Teneo/Hibernate to map EObjects
MT>> I am targeting 1 also, teneo can generate a native hibernate mapping (without teneo
dependencies) in the beginning (initialization time, or at compile time) but after that (during the
real runtime) hibernate can/should work directly on the cdorevision.
Teneo should not be present after the mapping has been done. CDO should have its own hibernate
runtime layer which does not depend on teneo. For the mapping cdo can use a mapping component which
generates a hibernate mapping. The mapping component is then a pluggable component which implements
a generic interface (something like: String getMapping(EPackage[] epackages)), teneo can then supply
an implementation of such a mapping component.
Another mapping component can read a mapping from a file somewhere (as an example).
>
> While 2) would probably be easier to implement it seems a bit of a brute
> force solution to me ;-) This would not only duplicate the footprint of
> meta model and model in the server but, even worse, introduce cache
> eviction issues (if ot unsolveable problems). I clearly tend to 1) until
> we get the impression that we're not able to do it with Hibernate.
MT>> Same for me,
>
>> Hibernate has the concept of synthetic id's (as I remember) but these
>> map to the current cdoid anyway.
>>
>> As far as I can see the following changes (please correct me here)
>> should make it all very mappable to hibernate (with explicit primary
>> keys):
>> - change the type of the value in the cdoid to serializable
> That's easy.
>> - move the extra information coded in the value field in cdoid to a
>> separate field
> That'd be easy although I'm a bit reluctant to force all stores touse
> this new implementation. I'm still thinking about copletely
> store-defined CDOID implementations...
MT>> yes, the cdoid can have different implementations which decide themselves how this info is encoded.
>>
>> The cdoid can then be constructed from the hibernate id object and
>> vice versa.
> You mean there's an explicit mapping somewhere between IRepository and
> IStore? Both of these entities won't like to do that because of the
> scalability issues ;-(
MT>> What's an IRepository (newbie question :-)?
When an object is read from the db through hibernate it is possible to intercept that and ask
hibernate for the id and construct a cdoid object which is set in the object. So the cdoid is not
stored explicitly in the db but is constructed when the object is read from the db, this should be
very similar as it is now already (the value in the cdoid is the value of the identity column in the
db I assume).
The same for when an object is persisted for the first time, after the persist action hibernate can
be queried for the id and a cdoid object can be created.
So the mapping from data in the object to the id is present in hibernate and using the hibernate
mapping information the cdo-hibernate store can create cdoid objects. At least that's how I think it
can work...
Or maybe I do not understand what you mean...?
>
> Cheers
> /Eike
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
| |
Re: Skeleton Implementation (CDOID format) [message #111424 is a reply to message #111395] |
Thu, 31 January 2008 13:04 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------040904050104090604090501
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
>> I think we should first clarify which of the following two,
>> completely different, integration strategies we want to follow in the
>> server:
>> 1) Let Hibernate operate directly on the CDORevisions
>> 2) Reconstruct the original Ecore model from the
>> CDOPackage.getEcore() string value and use Teneo/Hibernate to map
>> EObjects
> MT>> I am targeting 1 also, teneo can generate a native hibernate
> mapping (without teneo dependencies) in the beginning (initialization
> time, or at compile time) but after that (during the real runtime)
> hibernate can/should work directly on the cdorevision.
> Teneo should not be present after the mapping has been done. CDO
> should have its own hibernate runtime layer which does not depend on
> teneo. For the mapping cdo can use a mapping component which generates
> a hibernate mapping. The mapping component is then a pluggable
> component which implements a generic interface (something like: String
> getMapping(EPackage[] epackages)), teneo can then supply an
> implementation of such a mapping component.
> Another mapping component can read a mapping from a file somewhere (as
> an example).
That sounds very good!
>>> - move the extra information coded in the value field in cdoid to a
>>> separate field
>> That'd be easy although I'm a bit reluctant to force all stores touse
>> this new implementation. I'm still thinking about copletely
>> store-defined CDOID implementations...
> MT>> yes, the cdoid can have different implementations which decide
> themselves how this info is encoded.
I'm just applying a refactoring to make the CDOIDs internally
session-aware...
>>> The cdoid can then be constructed from the hibernate id object and
>>> vice versa.
>> You mean there's an explicit mapping somewhere between IRepository
>> and IStore? Both of these entities won't like to do that because of
>> the scalability issues ;-(
> MT>> What's an IRepository (newbie question :-)?
A repository on the server side. There can be multiple repositories
configured for a single server node. IRepository represents such a
repository in the form of a thin facade which delegates most
responsibilities to various managers:
|*public interface *IRepository *extends *IContainer<IRepositoryElement>
{
*public *String getName();
*public *IStore getStore();
*public *Map<String, String> getProperties();
*public *String getUUID();
*public **boolean *isSupportingAudits();
*public **boolean *isVerifyingRevisions();
_*public IPackageManager getPackageManager();
public ISessionManager getSessionManager();
public IResourceManager getResourceManager();
public IRevisionManager getRevisionManager();*_
}|
After a client opened a CDOSession with an IRepository the following is
valid:
session.getRepositoryName() equals repository.getName()
And the managers of the IRepository logically correspond to the managers
of the CDOSession (if applicable):
|*public interface *CDOSession *extends *IContainer<CDOView>
{
*public *String getRepositoryName();
*public *String getRepositoryUUID();
_* public CDOSessionPackageManager getPackageManager();
public CDORevisionManager getRevisionManager();*_ |
> When an object is read from the db through hibernate it is possible to
> intercept that and ask hibernate for the id and construct a cdoid
> object which is set in the object. So the cdoid is not stored
> explicitly in the db but is constructed when the object is read from
> the db, this should be very similar as it is now already (the value in
> the cdoid is the value of the identity column in the db I assume).
Yes, but how could Hibernate (or our interceptor) construct a flat CDOID
from PK columns without extra persistent information?
> The same for when an object is persisted for the first time, after the
> persist action hibernate can be queried for the id and a cdoid object
> can be created.
> So the mapping from data in the object to the id is present in
> hibernate and using the hibernate mapping information the
> cdo-hibernate store can create cdoid objects. At least that's how I
> think it can work...
>
> Or maybe I do not understand what you mean...?
I guess, although I'm not sure ;-)
Basically I'd like to avoid mapping from PKs to CDOIDs, regardless of
where this mapping info comes from (additional column in mapped tables,
additional table in the db, external hashing, etc.)
The solution I have in mind is the following:
There are two places in CDO where (new) CDOIDs are logically created.
These are the client-side CDOTransaction where new temporary CDOIDs are
created for new objects/resources and the server-side transaction
(currently in CommitTransactionIndication) where the temporary CDOIDs
are mapped to persistent ones. This CDOID mapping result is transferred
back to the client so that all the source and target IDs of the client
objects can be adjusted accordingly. All other places where CDOIDs are
physically created the value of an existing ID is kept unchanged. This
happens for example during deserialization or copy().
When the client must create new temporary CDOIDs I could use a special
CDOIDTemporaryImpl. A 32-bit integer would even be sufficient to
identify it. Both client and server would have to have access to this
class. Easy, since it can be final and would live in the protocol plugin.
The real challenge is to make the persistent CDOIDs that are currently
created by the IRepository completely independent of their
implementation, so that they can:
a) be created by the IStore in any internal format that might be
appropriate, including arbitrary structures for model-dependent values
or composite PKs.
b) copied, compared, hashed within one VM (easy)
c) transferred over the net to the client, stored there and sent back.
This step includes the problem that the implementation class file will
be contained in the plugin that implements the store (our new hibernate
plugin) and this plugin is not present on the client! Even factoring
this class out of the store plugin (if possible at all) is not a good
idea because the new id plugin would have to be deployed to the client
than and this would break the basic requirement that the client doesn't
need to know how the repository is implemented/configured.
Possible solution to c)
Before the first persistent CDOID is transferred from the server to the
client the needed class files are transferred to the client so that they
can be used when deserializing (and all the other operations later on).
Since the store implementation of a repository must not change after
after the initial startup (where store-specific initialization occurs) I
can even cache the transferred class files on the client keyed by
repositoryUUID.
For our HibernateStore this would mean that we could implement CDOID
with whatever Hibernate likes as a PK mapping.
Does that sound reasonable?
Cheers
/Eike
--------------040904050104090604090501
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">I think we should first clarify which of the
following two, completely different, integration strategies we want to
follow in the server:
<br>
1) Let Hibernate operate directly on the CDORevisions
<br>
2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
string value and use Teneo/Hibernate to map EObjects
<br>
</blockquote>
MT>> I am targeting 1 also, teneo can generate a native hibernate
mapping (without teneo dependencies) in the beginning (initialization
time, or at compile time) but after that (during the real runtime)
hibernate can/should work directly on the cdorevision.
<br>
Teneo should not be present after the mapping has been done. CDO should
have its own hibernate runtime layer which does not depend on teneo.
For the mapping cdo can use a mapping component which generates a
hibernate mapping. The mapping component is then a pluggable component
which implements a generic interface (something like: String
getMapping(EPackage[] epackages)), teneo can then supply an
implementation of such a mapping component.
<br>
Another mapping component can read a mapping from a file somewhere (as
an example).
<br>
</blockquote>
That sounds very good!<br>
<br>
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">
<blockquote type="cite">- move the extra information coded in the
value field in cdoid to a separate field
<br>
</blockquote>
That'd be easy although I'm a bit reluctant to force all stores touse
this new implementation. I'm still thinking about copletely
store-defined CDOID implementations...
<br>
</blockquote>
MT>> yes, the cdoid can have different implementations which
decide themselves how this info is encoded.
<br>
</blockquote>
I'm just applying a refactoring to make the CDOIDs internally
session-aware...<br>
<br>
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">
<blockquote type="cite">The cdoid can then be constructed from the
hibernate id object and vice versa.
<br>
</blockquote>
You mean there's an explicit mapping somewhere between IRepository and
IStore? Both of these entities won't like to do that because of the
scalability issues ;-(
<br>
</blockquote>
MT>> What's an IRepository (newbie question :-)?
<br>
</blockquote>
A repository on the server side. There can be multiple repositories
configured for a single server node. IRepository represents such a
repository in the form of a thin facade which delegates most
responsibilities to various managers:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111442 is a reply to message #111409] |
Thu, 31 January 2008 13:13 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> I also learned something here :-).
>
> What I mean is that the classes of the values which together make up
> the id are (by definition) also known client side, otherwise the
> client can not work with the objects anyway (as the id is constructed
> from values in the object itself).
>
> For example, a type customerorder has an order number field and this
> field is tagged as the id. The client knows how to handle the class of
> the order number field (otherwise the client can not handle the
> customer order at all), the class of the order number will be present
> in the generated code on the client. So if the client can handle the
> order number field then the client can also handle the id object
> (which by definition is the same as the value in the order number field).
>
> Or do you mean something else?
Heaven, this is complicated!!! I'm still not sure if we both have the
same picture and if not, which one is better ;-)
If I got the above right I see a problem: The assumption that the
classes of the model values that a user deals with are identical with
the classes of the corresponding model values that the server deals with
is not generally correct. Primitive types have the same class on both
sides of the network, Strings too. The differences may start with
multi-valued features and with user-defined EDataTypes (which arrive as
Strings at the server-side).
Let's wait if my other answer (with the possible solution) takes us a
step further...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111451 is a reply to message #111442] |
Thu, 31 January 2008 13:25 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
I should wait for your answer...
Actually it is kind of the other way around than I thought you ment. The client knows all the
implementation classes of the model (as the client has the generated code). However the server side
does not know all the implementation classes as the server side is generic. To overcome this issue
cdo currently maps the custom client side object types to strings.
Is this a fair description?
Btw, it can all be a bit theoritical (except for composite id's) as most (=all) field values will be
primitive types. And for composite id's we can think of a different solution (maybe use a specific
cdo composite class which is always used in the hibernate mapping for composite id's).
Would it be an idea to ignore this issue for now and assume that an id is always a primitive type
(long or string basically)? Then we can later think about how to solve composite id's.
The same for the other field values they are always primitive types (which is really most common).
One specific is enumeration, you have a cdo specific enumeration type which can be used to transfer
enum values back and forth? Or do you use the string/int value of an enum?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> I also learned something here :-).
>>
>> What I mean is that the classes of the values which together make up
>> the id are (by definition) also known client side, otherwise the
>> client can not work with the objects anyway (as the id is constructed
>> from values in the object itself).
>>
>> For example, a type customerorder has an order number field and this
>> field is tagged as the id. The client knows how to handle the class of
>> the order number field (otherwise the client can not handle the
>> customer order at all), the class of the order number will be present
>> in the generated code on the client. So if the client can handle the
>> order number field then the client can also handle the id object
>> (which by definition is the same as the value in the order number field).
>>
>> Or do you mean something else?
> Heaven, this is complicated!!! I'm still not sure if we both have the
> same picture and if not, which one is better ;-)
>
> If I got the above right I see a problem: The assumption that the
> classes of the model values that a user deals with are identical with
> the classes of the corresponding model values that the server deals with
> is not generally correct. Primitive types have the same class on both
> sides of the network, Strings too. The differences may start with
> multi-valued features and with user-defined EDataTypes (which arrive as
> Strings at the server-side).
>
> Let's wait if my other answer (with the possible solution) takes us a
> step further...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation (CDOID format) [message #111463 is a reply to message #111451] |
Thu, 31 January 2008 14:28 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> I should wait for your answer...
>
> Actually it is kind of the other way around than I thought you ment.
> The client knows all the implementation classes of the model (as the
> client has the generated code). However the server side does not know
> all the implementation classes as the server side is generic. To
> overcome this issue cdo currently maps the custom client side object
> types to strings.
>
> Is this a fair description?
Yes, with the very small exception that only custom EDataTypes are
mapped to String. Primitive values and primitive Object values are
transferred binary and and deserialized to the same representation on
the server:
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.protocol/src/or g/eclipse/emf/cdo/protocol/model/CDOType.java?revision=1.6&a mp;root=Modeling_Project&view=markup
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.protocol/src/or g/eclipse/emf/cdo/internal/protocol/model/CDOTypeImpl.java?r evision=1.14&root=Modeling_Project&view=markup
And of course references are transferred as CDOIDs but this is the topic
of this thread ;-)
> Btw, it can all be a bit theoritical (except for composite id's) as
> most (=all) field values will be primitive types. And for composite
> id's we can think of a different solution (maybe use a specific cdo
> composite class which is always used in the hibernate mapping for
> composite id's).
>
> Would it be an idea to ignore this issue for now and assume that an id
> is always a primitive type (long or string basically)? Then we can
> later think about how to solve composite id's.
>
> The same for the other field values they are always primitive types
> (which is really most common).
I prefer to play a bit with the store-defined CDOID implementation. One
reason is that I think that design is clearer and more flexible, another
reason is that Simon already asked for this feature weeks ago because
he'd like to optimize his ObjectivityStore.
> One specific is enumeration, you have a cdo specific enumeration type
> which can be used to transfer enum values back and forth? Or do you
> use the string/int value of an enum?
I must admit that I'm unsure at the moment but I believe they're treated
like custom EDataTypes, i.e. converted to Strings. But that could be
changed to ints. For sure there is no special enumeration type in CDO ;-)
Cheers
/Eike
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111573 is a reply to message #110204] |
Fri, 01 February 2008 19:36 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------000900060703040905050607
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Hi Martin,
CDOID format can now be defined by the IStore:
|*public interface *CDOID *extends *Serializable
{
*public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
*public *Type getType();
*public **boolean *isNull();
*public **boolean *isObject();
*public **boolean *isLegacy();
*public **boolean *isMeta();
*public **boolean *isTemporary();
*public **void *read(ExtendedDataInput in) *throws *IOException;
*public **void *write(ExtendedDataOutput out) *throws *IOException;
/**
* @author Eike Stepper
*/
*public enum *Type
{
NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
}
}|
There are 6 CDOID types but we are only occupied with OBJECT and
LEGACY_OBJECT (currently broken).
Each IStore implementation must deliver a CDOIDObjectFactory:
|*public interface *CDOIDObjectFactory
{
*public *Class<?>[] getCDOIDObjectClasses();
*public *CDOIDObject createCDOIDObject();
}|
The Class[] array is used to transafer the needed classes to the client.
This is all handled by the framework. Currently there is no caching in
the client.
The DBStore (look there for an example) passes all test cases but it
uses a CDOID implementation that is located as a default in the
underlying protocol plugin. If we want to implement things like CDOIDs
for composite PKs I guess that class loading won't work at once. But
it's too late now. I'll investigate that later...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
--------------000900060703040905050607
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Martin,<br>
<br>
CDOID format can now be defined by the IStore:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111583 is a reply to message #111573] |
Fri, 01 February 2008 20:00 |
Simon Mc Duff Messages: 596 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_089D_01C864E3.27A68F40
Content-Type: text/plain;
charset="ISO-8859-15"
Content-Transfer-Encoding: quoted-printable
Does it have an overhead compare to before if we are using CDOID with =
long ? (default behavior)
In this case, I assume you will not transfer .class ?
"Eike Stepper" <stepper@sympedia.de> wrote in message =
news:fnvscr$gbr$1@build.eclipse.org...
Hi Martin,
CDOID format can now be defined by the IStore:
public interface CDOID extends Serializable
{
public static final CDOID NULL =3D =
org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
public Type getType();
public boolean isNull();
public boolean isObject();
public boolean isLegacy();
public boolean isMeta();
public boolean isTemporary();
public void read(ExtendedDataInput in) throws IOException;
public void write(ExtendedDataOutput out) throws IOException;
/**
* @author Eike Stepper
*/
public enum Type
{
NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
}
} =20
There are 6 CDOID types but we are only occupied with OBJECT and =
LEGACY_OBJECT (currently broken).
Each IStore implementation must deliver a CDOIDObjectFactory:
public interface CDOIDObjectFactory
{
public Class<?>[] getCDOIDObjectClasses();
public CDOIDObject createCDOIDObject();
} =20
The Class[] array is used to transafer the needed classes to the =
client. This is all handled by the framework. Currently there is no =
caching in the client.
The DBStore (look there for an example) passes all test cases but it =
uses a CDOID implementation that is located as a default in the =
underlying protocol plugin. If we want to implement things like CDOIDs =
for composite PKs I guess that class loading won't work at once. But =
it's too late now. I'll investigate that later...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
------=_NextPart_000_089D_01C864E3.27A68F40
Content-Type: text/html;
charset="ISO-8859-15"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=3DContent-Type =
content=3Dtext/html;charset=3DISO-8859-15>
<META content=3D"MSHTML 6.00.2900.3199" name=3DGENERATOR></HEAD>
<BODY text=3D#000000 bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Does it have an overhead compare to =
before if we=20
are using CDOID with long ? (default behavior)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>In this case, I assume you will not =
transfer .class=20
?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>"Eike Stepper" <<A=20
href=3D"mailto:stepper@sympedia.de">stepper@sympedia.de</A>> wrote in =
message=20
<A=20
href=3D"news:fnvscr$gbr$1@build.eclipse.org">news:fnvscr$gbr$1@build.ecli=
pse.org</A>...</DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">Hi=20
Martin,<BR><BR>CDOID format can now be defined by the IStore:<BR><BR>
<STYLE type=3Dtext/css>CODE {
FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: Courier New, Courier
}
</STYLE>
<!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><!-- =3D Java Sourcecode to HTML automatically =
converted code =3D --><!-- =3D Java2Html Converter 5.0 [2006-02-26] by =
Markus Gebhard markus@jave.de =3D --><!-- =3D Further =
information: http://www.java2html.de =3D -->
<DIV class=3Djava align=3Dleft>
<TABLE cellSpacing=3D0 cellPadding=3D3 bgColor=3D#ffffff border=3D0>
<TBODY>
<TR><!-- start source code -->
<TD vAlign=3Dtop noWrap align=3Dleft><CODE><FONT=20
color=3D#7f0055><B>public interface </B ></FONT><FONT=20
color=3D#000000>CDOID </FONT><FONT=20
color=3D#7f0055><B>extends </B></FONT><FONT=20
color=3D#000000>Serializable</FONT><BR><FONT=20
color=3D#000000>{</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
=
color=3D#7f0055><B>public static final </B></FONT><FONT=20
=
color=3D#000000> CDOID NULL =3D org.eclipse.emf.cd o.interna=
l.protocol.id.CDOIDNullImpl.INSTANCE;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>Type getType</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isNull</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isObject</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isLegacy</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isMeta</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isTemporary</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>void </B></FONT><FONT=20
color=3D#000000>read</FONT><FONT color=3D#000000>(</FONT><FONT=20
color=3D#000000>ExtendedDataInput in</FONT><FONT=20
color=3D#000000>) </FONT><FONT=20
color=3D#7f0055><B>throws </B></FONT><FONT=20
color=3D#000000>IOException;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>void </B></FONT><FONT=20
color=3D#000000>write</FONT><FONT color=3D#000000>(</FONT><FONT=20
color=3D#000000>ExtendedDataOutput out</FONT><FONT=20
color=3D#000000>) </FONT><FONT=20
color=3D#7f0055><B>throws </B></FONT><FONT=20
color=3D#000000>IOException;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>/**</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>* </FONT><FONT=20
color=3D#7f9fbf>@author </FONT><FONT=20
color=3D#3f5fbf>Eike Stepper</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>*/</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public enum </B></FONT ><FONT=20
color=3D#000000>Type</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT =
color=3D#000000>{</FONT><BR><FONT=20
color=3D#ffffff> </FONT ><FONT=20
=
color=3D#000000> NULL, OBJECT, LEGACY_OBJECT, TEMP _OBJECT,&=
nbsp;META, TEMP_META</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT =
color=3D#000000>}</FONT><BR><FONT=20
color=3D#000000>}</FONT></CODE>=20
</TD><!-- end source code --></TR></TBODY></TABLE></DIV><!-- =3D =
END of automatically generated HTML code =3D --><!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><BR>There=20
are 6 CDOID types but we are only occupied with OBJECT and =
LEGACY_OBJECT=20
(currently broken).<BR><BR>Each IStore implementation must deliver a=20
CDOIDObjectFactory:<BR><BR>
<STYLE type=3Dtext/css>
<!--code { font-family: Courier New, Courier; font-size: 10pt; =
margin: 0px; }-->
</STYLE>
<!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><!-- =3D Java Sourcecode to HTML automatically =
converted code =3D --><!-- =3D Java2Html Converter 5.0 [2006-02-26] by =
Markus Gebhard markus@jave.de =3D --><!-- =3D Further =
information: http://www.java2html.de =3D -->
<DIV class=3Djava align=3Dleft>
<TABLE cellSpacing=3D0 cellPadding=3D3 bgColor=3D#ffffff border=3D0>
<TBODY>
<TR><!-- start source code -->
<TD vAlign=3Dtop noWrap align=3Dleft><CODE><FONT=20
color=3D#7f0055><B>public interface </B ></FONT><FONT=20
color=3D#000000>CDOIDObjectFactory</FONT><BR><FONT=20
color=3D#000000>{</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>Class<?></FONT><FONT=20
color=3D#000000>[] </FONT><FONT=20
color=3D#000000>getCDOIDObjectClasses</FONT><FONT=20
color=3D#000000>()</FONT><FONT color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>CDOIDObject createCDOIDObject</FONT ><FONT=20
color=3D#000000>()</FONT><FONT color=3D#000000>;</FONT><BR><FONT =
color=3D#000000>}</FONT></CODE>=20
</TD><!-- end source code --></TR></TBODY></TABLE></DIV><!-- =3D =
END of automatically generated HTML code =3D --><!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><BR>The=20
Class[] array is used to transafer the needed classes to the client. =
This is=20
all handled by the framework. Currently there is no caching in the=20
client.<BR><BR>The DBStore (look there for an example) passes all test =
cases=20
but it uses a CDOID implementation that is located as a default in the =
underlying protocol plugin. If we want to implement things like CDOIDs =
for=20
composite PKs I guess that class loading won't work at once. But it's =
too late=20
now. I'll investigate that later...<BR><BR>Regards,<BR>Eike=20
Stepper<BR>----<BR><A class=3Dmoz-txt-link-freetext=20
=
href=3D"http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</A><BR><=
A=20
class=3Dmoz-txt-link-freetext=20
=
href=3D"http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</A><=
BR><BR><BR><BR><BR></BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_089D_01C864E3.27A68F40--
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111592 is a reply to message #111583] |
Fri, 01 February 2008 20:10 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------080302060008010403080906
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Simon McDuff schrieb:
>
> Does it have an overhead compare to before if we are using CDOID with
> long ? (default behavior)
> In this case, I assume you will not transfer .class ?
Currently I do because I just wanted to test if that works ;-)
Later it won't be necessary anymore.
The overhead is minimal. The 3 classes are only transferred with (each)
OpenSessionIndication.responding().
A CDOID value has at least 1 byte, the ID type. Depending on that type
there are many cases now where fewer bytes are transferred. CDOID.NULL,
for instance, has only 1 byte total. All temporary IDs (TEMP_OBJECT and
TEMP_META) have an additional 32 bit integer. The OBJECT and
LEGACY_OBJECT ids are now store-dependent and the DBStore uses ids with
an additional 8-byte integer.
Cheers
/Eike
>
>
> "Eike Stepper" <stepper@sympedia.de <mailto:stepper@sympedia.de>>
> wrote in message news:fnvscr$gbr$1@build.eclipse.org...
>
> Hi Martin,
>
> CDOID format can now be defined by the IStore:
>
> |*public interface *CDOID *extends *Serializable
> {
> *public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>
> *public *Type getType();
>
> *public **boolean *isNull();
>
> *public **boolean *isObject();
>
> *public **boolean *isLegacy();
>
> *public **boolean *isMeta();
>
> *public **boolean *isTemporary();
>
> *public **void *read(ExtendedDataInput in) *throws *IOException;
>
> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>
> /**
> * @author Eike Stepper
> */
> *public enum *Type
> {
> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
> }
> }|
>
>
> There are 6 CDOID types but we are only occupied with OBJECT and
> LEGACY_OBJECT (currently broken).
>
> Each IStore implementation must deliver a CDOIDObjectFactory:
>
> |*public interface *CDOIDObjectFactory
> {
> *public *Class<?>[] getCDOIDObjectClasses();
>
> *public *CDOIDObject createCDOIDObject();
> }|
>
>
> The Class[] array is used to transafer the needed classes to the
> client. This is all handled by the framework. Currently there is
> no caching in the client.
>
> The DBStore (look there for an example) passes all test cases but
> it uses a CDOID implementation that is located as a default in the
> underlying protocol plugin. If we want to implement things like
> CDOIDs for composite PKs I guess that class loading won't work at
> once. But it's too late now. I'll investigate that later...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
>
--------------080302060008010403080906
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Simon McDuff schrieb:
<blockquote cite="mid:fnvtog$mo7$1@build.eclipse.org" type="cite">
<title></title>
<meta http-equiv="Content-Type"
content="text/html;charset=ISO-8859-15">
<meta content="MSHTML 6.00.2900.3199" name="GENERATOR">
<div>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111618 is a reply to message #111573] |
Fri, 01 February 2008 21:17 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I did not have time today (too much customer work) :-(.
Related to the cdoidfactory, what I am not sure about is how to create a cdoid object without access
to the underlying database id object or the object itself. I mean when I look at the api of
cdoidfactory it seems that it assumes that id's are autogenerated?
Btw, I am looking through the cdo code to see how cdoid is used, what does ResourceIDRequest do?
gr. Martin
Eike Stepper wrote:
> Hi Martin,
>
> CDOID format can now be defined by the IStore:
>
> |*public interface *CDOID *extends *Serializable
> {
> *public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>
> *public *Type getType();
>
> *public **boolean *isNull();
>
> *public **boolean *isObject();
>
> *public **boolean *isLegacy();
>
> *public **boolean *isMeta();
>
> *public **boolean *isTemporary();
>
> *public **void *read(ExtendedDataInput in) *throws *IOException;
>
> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>
> /**
> * @author Eike Stepper
> */
> *public enum *Type
> {
> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
> }
> }|
>
>
> There are 6 CDOID types but we are only occupied with OBJECT and
> LEGACY_OBJECT (currently broken).
>
> Each IStore implementation must deliver a CDOIDObjectFactory:
>
> |*public interface *CDOIDObjectFactory
> {
> *public *Class<?>[] getCDOIDObjectClasses();
>
> *public *CDOIDObject createCDOIDObject();
> }|
>
>
> The Class[] array is used to transafer the needed classes to the client.
> This is all handled by the framework. Currently there is no caching in
> the client.
>
> The DBStore (look there for an example) passes all test cases but it
> uses a CDOID implementation that is located as a default in the
> underlying protocol plugin. If we want to implement things like CDOIDs
> for composite PKs I guess that class loading won't work at once. But
> it's too late now. I'll investigate that later...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111631 is a reply to message #111618] |
Sat, 02 February 2008 07:05 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------020005010506040504080003
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> I did not have time today (too much customer work) :-(.
That will start next wee for me again, too ;-)
>
> Related to the cdoidfactory, what I am not sure about is how to create
> a cdoid object without access to the underlying database id object or
> the object itself. I mean when I look at the api of cdoidfactory it
> seems that it assumes that id's are autogenerated?
I also thought about that and I guess there's still refactoring to be
done. I'm thinking about a 2-split factory:
|*public interface *CDOIDObjectFactory
{
*public *Class<?>[] getCDOIDObjectClasses();
*public *CDOIDObject createCDOIDObject(CDORevision revision);
*public *CDOIDObject readCDOIDObject(ExtendedDataInput in);
}|
>
> Btw, I am looking through the cdo code to see how cdoid is used, what
> does ResourceIDRequest do?
When a client calls one of ResourceSet.getResource(URI uri) or
CDOView.getResource(String path), which are equivalent if uri ==
"cdo:path", the ResourceIDRequest asks the server to deliver the CDOID
that belongs to the named resource. The server will do so in the class
ResourceIDIndication.
The reverse mapping CDOID --> resourcePath can be queried with
ResourcePathRequest/Indication.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
--------------020005010506040504080003
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fo028n$7el$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
I did not have time today (too much customer work) :-(.
<br>
</blockquote>
That will start next wee for me again, too ;-)<br>
<br>
<blockquote cite="mid:fo028n$7el$1@build.eclipse.org" type="cite"><br>
Related to the cdoidfactory, what I am not sure about is how to create
a cdoid object without access to the underlying database id object or
the object itself. I mean when I look at the api of cdoidfactory it
seems that it assumes that id's are autogenerated?
<br>
</blockquote>
I also thought about that and I guess there's still refactoring to be
done. I'm thinking about a 2-split factory:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
|
|
|
Hibernate Configuration/SessionFactory/Session/Transaction [message #111638 is a reply to message #110231] |
Sat, 02 February 2008 07:59 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
I'm thinking about how to map these Hibernate concepts to the IStore
concepts. I learned about the following facts (please correct me or add
comments):
a) A Transaction instance is needed when data is to be written. A
Transaction can/must be obtained from a Session. Can there be multiple
concurrent transactions on a single session?
b) A Session instance is needed when data is to be read or a Transaction
is to be started. It can/must be obtained from a SessionFactory. Each
thread must use its own Session instance (cheap creation).
c) A SessionFactory can be built out of a Configuration and can't be
altered after that. Can there be multiple concurrent factories built out
of a single configuration?
d) A Configuration instance is used to add/remove mappings and to create
SessionFactories for these mappings. Can this be done if
SessionFactories have already been built? An empty Configuration
instance is created via default ctor.
My idea is the following:
1) HibernateStore has a Configuration to manage the mappings
2) In addition it builds and keeps a SessionFactory which must be
rebuilt after each modification of the Configuration
3) If an IStoreReader is requested by the framework, HibernateStore
creates a new HibernateStoreReader which uses the current SessionFactory
to open a new Session
4) If an IStoreWriter is requested by the framework, HibernateStore
creates a new HibernateStoreWriter (extends the reader and thus already
has a Session) which uses the Session to begin a new Transaction
5) There are 2 different events that can cause the Configuration to be
changed:
5.1) A client commits a *new* package. This leads to
IStoreWriter.writePackages() being called. The HibernateStoreWriter
implementation will persist the packages (so that they can be retrieved
after restarts, see 5.2) and pass them to HibernateStore (see 1 + 2)
5.2) A client loads an object with a class that is in an *existing*
package (which hasn't been loaded before). This leads to
IStoreReader.readPackage() being called. The HibernateStoreReader will
read/return the persisted package and also pass it to HibernateStore (se
1 + 2)
Open questions:
- How must 1) + 2) be protected /synchronized in a concurrent server
environment, i.e. can a new SessionFactory be built/used while "old"
SessionFactories (based on previous Configuration states) are still in
use? Or do we have to use proper ReadWriteLocks, which would cause all
repository access to halt on each change of mappings?
- How should the actual JDBC Connection/DataSource be managed? Is this
part of the Hibernate Configuration/SessionFactory/Session? Should we
pass a DataSource into the HibernateStore which a HibernateStoreReader
can use to obtain a Connection when it must create its Hibernate Session?
- Where do the mappings come from? In 5.1 and 5.2 we have access to a
CDOPackage which can deliver the XML string of the corresponding
EPackage. Is this the place where Teneo comes into game?
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111645 is a reply to message #111618] |
Sat, 02 February 2008 08:13 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> I did not have time today (too much customer work) :-(.
>
> Related to the cdoidfactory, what I am not sure about is how to create
> a cdoid object without access to the underlying database id object or
> the object itself. I mean when I look at the api of cdoidfactory it
> seems that it assumes that id's are autogenerated?
Ignore my previous answer to this particular question!!! I was confused ;-)
The factory is only used to recreate existing CDOIDs from a stream. The
factory must create/return a "naked" instance which is subsequently used
by the framework to read() the actual state. For this purpose the CDOID
implementation class will usually have a default ctor. May be I could
make this more obvious by adding the stream parameter to the create()
method of the factory, which also has the advantage that the factory can
read from the stream before deciding about the actual implementation class.
To create new CDOID values we can just call additional ctors on our
implementation class!
Cheers
/Eike
>
> Btw, I am looking through the cdo code to see how cdoid is used, what
> does ResourceIDRequest do?
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi Martin,
>>
>> CDOID format can now be defined by the IStore:
>>
>> |*public interface *CDOID *extends *Serializable
>> {
>> *public static final *CDOID NULL =
>> org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>>
>> *public *Type getType();
>>
>> *public **boolean *isNull();
>>
>> *public **boolean *isObject();
>>
>> *public **boolean *isLegacy();
>>
>> *public **boolean *isMeta();
>>
>> *public **boolean *isTemporary();
>>
>> *public **void *read(ExtendedDataInput in) *throws *IOException;
>>
>> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>>
>> /**
>> * @author Eike Stepper
>> */
>> *public enum *Type
>> {
>> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
>> }
>> }|
>>
>>
>> There are 6 CDOID types but we are only occupied with OBJECT and
>> LEGACY_OBJECT (currently broken).
>>
>> Each IStore implementation must deliver a CDOIDObjectFactory:
>>
>> |*public interface *CDOIDObjectFactory
>> {
>> *public *Class<?>[] getCDOIDObjectClasses();
>>
>> *public *CDOIDObject createCDOIDObject();
>> }|
>>
>>
>> The Class[] array is used to transafer the needed classes to the
>> client. This is all handled by the framework. Currently there is no
>> caching in the client.
>>
>> The DBStore (look there for an example) passes all test cases but it
>> uses a CDOID implementation that is located as a default in the
>> underlying protocol plugin. If we want to implement things like
>> CDOIDs for composite PKs I guess that class loading won't work at
>> once. But it's too late now. I'll investigate that later...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>>
>
>
|
|
|
Mapping the Meta Model [message #111652 is a reply to message #110231] |
Sat, 02 February 2008 09:19 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
To persist/load the meta model I'd like to use Hibernate.
The following classes must be mapped:
1) CDOPackageImpl
2) CDOClassImpl
3) CDOFeatureImpl
There are also some subclasses of these classes that represent the
system packages CDOCorePackage and CDOResourcePackage. Their instances
need not be persisted.
Questions:
- Do the three classes need to be Serializable and derived properties
marked transient?
- Does the usage of JPA annotations require ejb3-persistence.jar to be
present on the classpath of the protocol plugin (where the three classes
are located)?
- To go without the ejb3-persistence.jar could/should I use XML files
directly in the org.eclipse.emf.cdo.server.hibernate plugin?
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
|
|
|
Re: Mapping the Meta Model [message #111658 is a reply to message #111652] |
Sat, 02 February 2008 09:23 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Eike Stepper schrieb:
> To persist/load the meta model I'd like to use Hibernate.
> The following classes must be mapped:
> 1) CDOPackageImpl
> 2) CDOClassImpl
> 3) CDOFeatureImpl
>
> There are also some subclasses of these classes that represent the
> system packages CDOCorePackage and CDOResourcePackage. Their instances
> need not be persisted.
>
> Questions:
> - Do the three classes need to be Serializable and derived properties
> marked transient?
> - Does the usage of JPA annotations require ejb3-persistence.jar to be
> present on the classpath of the protocol plugin (where the three
> classes are located)?
If yes, another solution could be to specify an optional dependency on a
plugin with hibernate-annotations.jar and ejb3-persistence.jar.
Then we could use the annotations in the protocol plugin. Any idea what
happens with the annotated classes if the optional dependency is not
satisfied at runtime???
> - To go without the ejb3-persistence.jar could/should I use XML files
> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
|
|
|
Re: Mapping the Meta Model [message #111664 is a reply to message #111652] |
Sat, 02 February 2008 11:18 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------030808090306080600040104
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
I've started with an initial version of a hbm.xml file in
/org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.eclipse.emf.cdo.internal.protocol.model"
default-access="field">
<class name="CDOPackageImpl" table="cdo_packages">
<property name="packageURI"
column-name="uri"
type="string"
not-null="true"
length="255"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="ecore"
type="java.sql.Clob"
not-null="false"
lazy="true"/>
<property name="dynamic"
type="boolean"
not-null="true"/>
</class>
<class name="CDOClassImpl" table="cdo_classes">
<property name="classifierID"
column-name="classifier"
type="int"
not-null="true"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="isAbstract"
column-name="abstract"
type="boolean"
not-null="true"/>
</class>
<class name="CDOFeatureImpl" table="cdo_features">
<property name="featureID"
column-name="feature"
type="int"
not-null="true"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="type"
type="int"
not-null="true"/>
<property name="referenceType"
column-name="reftype"
type="string"
not-null="false"/>
<property name="many"
type="boolean"
not-null="true"/>
<property name="containment"
type="boolean"
not-null="false"/>
</class>
</hibernate-mapping>
Open Questions:
- The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
which is internally a structure of a long integer (lower bound meta
CDOID) and a normal int (size of the range). I'd like to persist it as
two long values (lower bound and upper bound, both have getters in
CDOIDMetaRange). How is this possible?
- The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
which is internally a structure of a String (package URI) and an int
(classifierID). How should we map this?
- The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
which works similar to the aforementioned referenceType.
- The three classes have bidi containment associations
(CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't know
how to map them.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Eike Stepper schrieb:
> To persist/load the meta model I'd like to use Hibernate.
> The following classes must be mapped:
> 1) CDOPackageImpl
> 2) CDOClassImpl
> 3) CDOFeatureImpl
>
> There are also some subclasses of these classes that represent the
> system packages CDOCorePackage and CDOResourcePackage. Their instances
> need not be persisted.
>
> Questions:
> - Do the three classes need to be Serializable and derived properties
> marked transient?
> - Does the usage of JPA annotations require ejb3-persistence.jar to be
> present on the classpath of the protocol plugin (where the three
> classes are located)?
> - To go without the ejb3-persistence.jar could/should I use XML files
> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--------------030808090306080600040104
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body alink="#ee0000" bgcolor="#ffffff" link="#0000ee" text="#000000"
vlink="#551a8b">
I've started with an initial version of a hbm.xml file in
/org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml: <br>
<br>
<table bgcolor="#ffffcc" border="0" cellpadding="2" cellspacing="2"
width="100%">
<tbody>
<tr>
<td valign="top"><?xml version="1.0"?><br>
<!DOCTYPE hibernate-mapping SYSTEM
<a class="moz-txt-link-rfc2396E" href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"</a>><br>
<br>
<hibernate-mapping
package="org.eclipse.emf.cdo.internal.protocol.model"
default-access="field"><br>
<br>
|
|
|
Re: Mapping the Meta Model [message #111671 is a reply to message #111664] |
Sat, 02 February 2008 14:34 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
A simple way of storing it, is to store the model as a char blob in a epackage table. This ofcourse
only works if you don't need database access to the individual model elements, as you read most
information in-memory anyway this seems pretty workable.
If you have an ecore model for the mapping then I can generate a mapping for you.
To answer your questions:
I am not sure are CDOIDMetaRange independent classes which are also referenced from other classes?
Same question for CDOClassProxy?
If they are embedded types then they can be mapped like this:
<component name="referenceType" class="full_class_name_to_CDOClassProxy">
<property name="package URI" lazy="false" insert="true" update="true" not-null="true"
unique="false" type="java.lang.String"/>
<property name="classifierID" lazy="false" insert="true" update="true" not-null="false"
unique="false" type="int"/>
</component>
A single reference to another type which is also used by other classes:
<many-to-one name="referenceType" class="CDOClassProxy"/>
Here is an example of how a bidirectional list is mapped for the library example, note that on the
many side the insert and update attributes both are false. Also because possibly the package-class
relation is containment you should use a cascade of all, delete-orphan in the list. Instead of using
the entity-name you can also use the class attribute (with the classname);
<list name="books" lazy="true" cascade="merge,persist,save-update,lock,refresh">
<cache usage="read-write"/>
<key update="true">
<column name="`book_author_e_id`" not-null="false" unique="false"/>
</key>
<list-index column="`writer_books_idx`"/>
<one-to-many entity-name="Book"/>
</list>
<many-to-one name="author" entity-name="Writer" cascade="merge,persist,save-update,lock,refresh"
foreign-key="book_author" lazy="false" insert="false" update="false" not-null="false">
<column not-null="false" unique="false" name="`book_author_e_id`"/>
</many-to-one>
gr. Martin
Eike Stepper wrote:
> I've started with an initial version of a hbm.xml file in
> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>
> <?xml version="1.0"?>
> <!DOCTYPE hibernate-mapping SYSTEM
> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>
> <hibernate-mapping package="org.eclipse.emf.cdo.internal.protocol.model"
> default-access="field">
>
> <class name="CDOPackageImpl" table="cdo_packages">
> <property name="packageURI"
> column-name="uri"
> type="string"
> not-null="true"
> length="255"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="ecore"
> type="java.sql.Clob"
> not-null="false"
> lazy="true"/>
> <property name="dynamic"
> type="boolean"
> not-null="true"/>
> </class>
>
> <class name="CDOClassImpl" table="cdo_classes">
> <property name="classifierID"
> column-name="classifier"
> type="int"
> not-null="true"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="isAbstract"
> column-name="abstract"
> type="boolean"
> not-null="true"/>
> </class>
>
> <class name="CDOFeatureImpl" table="cdo_features">
> <property name="featureID"
> column-name="feature"
> type="int"
> not-null="true"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="type"
> type="int"
> not-null="true"/>
> <property name="referenceType"
> column-name="reftype"
> type="string"
> not-null="false"/>
> <property name="many"
> type="boolean"
> not-null="true"/>
> <property name="containment"
> type="boolean"
> not-null="false"/>
> </class>
>
> </hibernate-mapping>
>
>
> Open Questions:
> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
> which is internally a structure of a long integer (lower bound meta
> CDOID) and a normal int (size of the range). I'd like to persist it as
> two long values (lower bound and upper bound, both have getters in
> CDOIDMetaRange). How is this possible?
> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
> which is internally a structure of a String (package URI) and an int
> (classifierID). How should we map this?
> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
> which works similar to the aforementioned referenceType.
> - The three classes have bidi containment associations
> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't know
> how to map them.
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
> Eike Stepper schrieb:
>> To persist/load the meta model I'd like to use Hibernate.
>> The following classes must be mapped:
>> 1) CDOPackageImpl
>> 2) CDOClassImpl
>> 3) CDOFeatureImpl
>>
>> There are also some subclasses of these classes that represent the
>> system packages CDOCorePackage and CDOResourcePackage. Their instances
>> need not be persisted.
>>
>> Questions:
>> - Do the three classes need to be Serializable and derived properties
>> marked transient?
>> - Does the usage of JPA annotations require ejb3-persistence.jar to be
>> present on the classpath of the protocol plugin (where the three
>> classes are located)?
>> - To go without the ejb3-persistence.jar could/should I use XML files
>> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Mapping the Meta Model [message #111679 is a reply to message #111671] |
Sun, 03 February 2008 09:48 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------040109000904050209000902
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> A simple way of storing it, is to store the model as a char blob in a
> epackage table. This ofcourse only works if you don't need database
> access to the individual model elements, as you read most information
> in-memory anyway this seems pretty workable.
I also thought about this option and it would be really easy. But the
current solution also has 2 advantages: The user/admin can better
interpret the meta information (including usage for queries) and I can
better learn about Hibernate ;-)
> If you have an ecore model for the mapping then I can generate a
> mapping for you.
>
> To answer your questions:
> I am not sure are CDOIDMetaRange independent classes which are also
> referenced from other classes? Same question for CDOClassProxy?
> If they are embedded types then they can be mapped like this:
> <component name="referenceType" class="full_class_name_to_CDOClassProxy">
> <property name="package URI" lazy="false" insert="true"
> update="true" not-null="true" unique="false" type="java.lang.String"/>
> <property name="classifierID" lazy="false" insert="true"
> update="true" not-null="false" unique="false" type="int"/>
> </component>
>
> A single reference to another type which is also used by other classes:
> <many-to-one name="referenceType" class="CDOClassProxy"/>
>
> Here is an example of how a bidirectional list is mapped for the
> library example, note that on the many side the insert and update
> attributes both are false. Also because possibly the package-class
> relation is containment you should use a cascade of all, delete-orphan
> in the list. Instead of using the entity-name you can also use the
> class attribute (with the classname);
> <list name="books" lazy="true"
> cascade="merge,persist,save-update,lock,refresh">
> <cache usage="read-write"/>
> <key update="true">
> <column name="`book_author_e_id`" not-null="false"
> unique="false"/>
> </key>
> <list-index column="`writer_books_idx`"/>
> <one-to-many entity-name="Book"/>
> </list>
>
> <many-to-one name="author" entity-name="Writer"
> cascade="merge,persist,save-update,lock,refresh"
> foreign-key="book_author" lazy="false" insert="false" update="false"
> not-null="false">
> <column not-null="false" unique="false"
> name="`book_author_e_id`"/>
> </many-to-one>
Thanks for the hints. I'll try them ASAP.
In CVS there is now a test class that does all the setup of a standalone
client/server with Mysql. It commits a simple model to the repository.
It seems to work pretty well until it runs into the first
UnsupportedOperationExceptions of the new HibernateStore. Now we can
implement one method after the other:
|*public class *HibernateTest
{
*private static final *String REPOSITORY_NAME = "repo1";
*public static **void *main(String[] args) *throws *Exception
{
IManagedContainer container = initContainer();
// Start the transport and create a repository
JVMUtil.getAcceptor(container, "default"); // Start the JVM transport
CDOServerUtil.addRepository(container, createRepository()); // Start a CDO respository
// Establish a communications connection and open a session with the repository
IConnector connector = JVMUtil.getConnector(container, "default"); // Open a JVM connection
CDOSession session = CDOUtil.openSession(connector, REPOSITORY_NAME, *true*);// Open a CDO session
session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);// Not needed after first commit!!!
// Open a transaction, and create a new resource
CDOTransaction transaction = session.openTransaction();
Resource resource = transaction.createResource("/my/big/resource");
resource.getContents().add(getInputModel());
transaction.commit();
// Cleanup
session.close();
connector.disconnect();
}
*private static *IManagedContainer initContainer()
{
// Turn on tracing
OMPlatform.INSTANCE.setDebugging(*true*);
OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
// Prepare the standalone infra structure (not needed when running inside Eclipse)
IManagedContainer container = ContainerUtil.createContainer(); // Create a wiring container
Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
JVMUtil.prepareContainer(container); // Prepare the JVM transport
CDOServerUtil.prepareContainer(container); // Prepare the CDO server
CDOUtil.prepareContainer(container, *false*); // Prepare the CDO client
*return *container;
}
*private static *IRepository createRepository() *throws *Exception
{
Map<String, String> props = *new *HashMap<String, String>();
props.put(Props.PROP_SUPPORTING_AUDITS, "false");
props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
props.put(Props.PROP_VERIFYING_REVISIONS, "false");
props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
*return *CDOServerUtil.createRepository(REPOSITORY_NAME, createStore(), props);
}
*private static *IStore createStore() *throws *Exception
{
DriverManager.setLogWriter(*new *PrintWriter(System.out));
Driver driver = *new *com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
String driverName = driver.getClass().getName();
String dialectName = MySQLDialect.*class*.getName();
Configuration configuration = *new *Configuration();
configuration.setProperty(Environment.DRIVER, driverName);
configuration.setProperty(Environment.URL, "jdbc:mysql://localhost/cdohibernate");
configuration.setProperty(Environment.USER, "root");
configuration.setProperty(Environment.DIALECT, dialectName);
configuration.setProperty(Environment.SHOW_SQL, "true");
*return new *HibernateStore(configuration);
}
*private static *EObject getInputModel()
{
Category cat1 = Model1Factory.eINSTANCE.createCategory();
cat1.setName("CAT1");
Category cat2 = Model1Factory.eINSTANCE.createCategory();
cat2.setName("CAT2");
cat1.getCategories().add(cat2);
Product p1 = Model1Factory.eINSTANCE.createProduct();
p1.setName("P1");
cat1.getProducts().add(p1);
Product p2 = Model1Factory.eINSTANCE.createProduct();
p2.setName("P2");
cat1.getProducts().add(p2);
Product p3 = Model1Factory.eINSTANCE.createProduct();
p3.setName("P3");
cat2.getProducts().add(p3);
*return *cat1;
}
}|
BTW do you know if you're able/allowed to commit into the CDO CVS??
From tomorrow on I'll be working in Switzerland. That could have a
slightly negative impact on my responsiveness. I hope the hotel I chose
has a good WLAN at least for the evening hours ;-)
Cheers
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> I've started with an initial version of a hbm.xml file in
>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>
>> <?xml version="1.0"?>
>> <!DOCTYPE hibernate-mapping SYSTEM
>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>
>> <hibernate-mapping
>> package="org.eclipse.emf.cdo.internal.protocol.model"
>> default-access="field">
>>
>> <class name="CDOPackageImpl" table="cdo_packages">
>> <property name="packageURI"
>> column-name="uri"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="ecore"
>> type="java.sql.Clob"
>> not-null="false"
>> lazy="true"/>
>> <property name="dynamic"
>> type="boolean"
>> not-null="true"/>
>> </class>
>>
>> <class name="CDOClassImpl" table="cdo_classes">
>> <property name="classifierID"
>> column-name="classifier"
>> type="int"
>> not-null="true"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="isAbstract"
>> column-name="abstract"
>> type="boolean"
>> not-null="true"/>
>> </class>
>>
>> <class name="CDOFeatureImpl" table="cdo_features">
>> <property name="featureID"
>> column-name="feature"
>> type="int"
>> not-null="true"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="type"
>> type="int"
>> not-null="true"/>
>> <property name="referenceType"
>> column-name="reftype"
>> type="string"
>> not-null="false"/>
>> <property name="many"
>> type="boolean"
>> not-null="true"/>
>> <property name="containment"
>> type="boolean"
>> not-null="false"/>
>> </class>
>>
>> </hibernate-mapping>
>>
>>
>> Open Questions:
>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>> which is internally a structure of a long integer (lower bound meta
>> CDOID) and a normal int (size of the range). I'd like to persist it
>> as two long values (lower bound and upper bound, both have getters in
>> CDOIDMetaRange). How is this possible?
>> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
>> which is internally a structure of a String (package URI) and an int
>> (classifierID). How should we map this?
>> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
>> which works similar to the aforementioned referenceType.
>> - The three classes have bidi containment associations
>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>> know how to map them.
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>> Eike Stepper schrieb:
>>> To persist/load the meta model I'd like to use Hibernate.
>>> The following classes must be mapped:
>>> 1) CDOPackageImpl
>>> 2) CDOClassImpl
>>> 3) CDOFeatureImpl
>>>
>>> There are also some subclasses of these classes that represent the
>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>> instances need not be persisted.
>>>
>>> Questions:
>>> - Do the three classes need to be Serializable and derived
>>> properties marked transient?
>>> - Does the usage of JPA annotations require ejb3-persistence.jar to
>>> be present on the classpath of the protocol plugin (where the three
>>> classes are located)?
>>> - To go without the ejb3-persistence.jar could/should I use XML
>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>
>
--------------040109000904050209000902
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fo1v12$n1f$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
A simple way of storing it, is to store the model as a char blob in a
epackage table. This ofcourse only works if you don't need database
access to the individual model elements, as you read most information
in-memory anyway this seems pretty workable.
<br>
</blockquote>
I also thought about this option and it would be really easy. But the
current solution also has 2 advantages: The user/admin can better
interpret the meta information (including usage for queries) and I can
better learn about Hibernate ;-)<br>
<br>
<blockquote cite="mid:fo1v12$n1f$1@build.eclipse.org" type="cite">If
you have an ecore model for the mapping then I can generate a mapping
for you.
<br>
<br>
To answer your questions:
<br>
I am not sure are CDOIDMetaRange independent classes which are also
referenced from other classes? Same question for CDOClassProxy?
<br>
If they are embedded types then they can be mapped like this:
<br>
<component name="referenceType"
class="full_class_name_to_CDOClassProxy">
<br>
|
|
|
Re: Mapping the Meta Model [message #111688 is a reply to message #111679] |
Sun, 03 February 2008 10:11 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
Thanks for the example I will try this out. I just tried but I don't have commit rights. It would
help a bit if I can get commit rights to the cdo-hibernate project. I would not be surpised if we
would require a specific cdo-teneo plugin to override some default teneo mapping behavior. For
example Teneo adds its own types for handling xsddate and enumeration in the mapping file, for cdo
this would be cdo specific classes.
I will answer your other news post shortly.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> A simple way of storing it, is to store the model as a char blob in a
>> epackage table. This ofcourse only works if you don't need database
>> access to the individual model elements, as you read most information
>> in-memory anyway this seems pretty workable.
> I also thought about this option and it would be really easy. But the
> current solution also has 2 advantages: The user/admin can better
> interpret the meta information (including usage for queries) and I can
> better learn about Hibernate ;-)
>
>> If you have an ecore model for the mapping then I can generate a
>> mapping for you.
>>
>> To answer your questions:
>> I am not sure are CDOIDMetaRange independent classes which are also
>> referenced from other classes? Same question for CDOClassProxy?
>> If they are embedded types then they can be mapped like this:
>> <component name="referenceType" class="full_class_name_to_CDOClassProxy">
>> <property name="package URI" lazy="false" insert="true"
>> update="true" not-null="true" unique="false" type="java.lang.String"/>
>> <property name="classifierID" lazy="false" insert="true"
>> update="true" not-null="false" unique="false" type="int"/>
>> </component>
>>
>> A single reference to another type which is also used by other classes:
>> <many-to-one name="referenceType" class="CDOClassProxy"/>
>>
>> Here is an example of how a bidirectional list is mapped for the
>> library example, note that on the many side the insert and update
>> attributes both are false. Also because possibly the package-class
>> relation is containment you should use a cascade of all, delete-orphan
>> in the list. Instead of using the entity-name you can also use the
>> class attribute (with the classname);
>> <list name="books" lazy="true"
>> cascade="merge,persist,save-update,lock,refresh">
>> <cache usage="read-write"/>
>> <key update="true">
>> <column name="`book_author_e_id`" not-null="false"
>> unique="false"/>
>> </key>
>> <list-index column="`writer_books_idx`"/>
>> <one-to-many entity-name="Book"/>
>> </list>
>>
>> <many-to-one name="author" entity-name="Writer"
>> cascade="merge,persist,save-update,lock,refresh"
>> foreign-key="book_author" lazy="false" insert="false" update="false"
>> not-null="false">
>> <column not-null="false" unique="false"
>> name="`book_author_e_id`"/>
>> </many-to-one>
> Thanks for the hints. I'll try them ASAP.
> In CVS there is now a test class that does all the setup of a standalone
> client/server with Mysql. It commits a simple model to the repository.
> It seems to work pretty well until it runs into the first
> UnsupportedOperationExceptions of the new HibernateStore. Now we can
> implement one method after the other:
>
> |*public class *HibernateTest
> {
> *private static final *String REPOSITORY_NAME = "repo1";
>
> *public static **void *main(String[] args) *throws *Exception
> {
> IManagedContainer container = initContainer();
>
> // Start the transport and create a repository
> JVMUtil.getAcceptor(container, "default"); // Start the JVM transport
> CDOServerUtil.addRepository(container, createRepository()); // Start a CDO respository
>
> // Establish a communications connection and open a session with the repository
> IConnector connector = JVMUtil.getConnector(container, "default"); // Open a JVM connection
> CDOSession session = CDOUtil.openSession(connector, REPOSITORY_NAME, *true*);// Open a CDO session
> session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);// Not needed after first commit!!!
>
> // Open a transaction, and create a new resource
> CDOTransaction transaction = session.openTransaction();
> Resource resource = transaction.createResource("/my/big/resource");
> resource.getContents().add(getInputModel());
> transaction.commit();
>
> // Cleanup
> session.close();
> connector.disconnect();
> }
>
> *private static *IManagedContainer initContainer()
> {
> // Turn on tracing
> OMPlatform.INSTANCE.setDebugging(*true*);
> OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
> OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
>
> // Prepare the standalone infra structure (not needed when running inside Eclipse)
> IManagedContainer container = ContainerUtil.createContainer(); // Create a wiring container
> Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
> JVMUtil.prepareContainer(container); // Prepare the JVM transport
> CDOServerUtil.prepareContainer(container); // Prepare the CDO server
> CDOUtil.prepareContainer(container, *false*); // Prepare the CDO client
> *return *container;
> }
>
> *private static *IRepository createRepository() *throws *Exception
> {
> Map<String, String> props = *new *HashMap<String, String>();
> props.put(Props.PROP_SUPPORTING_AUDITS, "false");
> props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
> props.put(Props.PROP_VERIFYING_REVISIONS, "false");
> props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
> props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
> *return *CDOServerUtil.createRepository(REPOSITORY_NAME, createStore(), props);
> }
>
> *private static *IStore createStore() *throws *Exception
> {
> DriverManager.setLogWriter(*new *PrintWriter(System.out));
> Driver driver = *new *com.mysql.jdbc.Driver();
> DriverManager.registerDriver(driver);
> String driverName = driver.getClass().getName();
> String dialectName = MySQLDialect.*class*.getName();
>
> Configuration configuration = *new *Configuration();
> configuration.setProperty(Environment.DRIVER, driverName);
> configuration.setProperty(Environment.URL, "jdbc:mysql://localhost/cdohibernate");
> configuration.setProperty(Environment.USER, "root");
> configuration.setProperty(Environment.DIALECT, dialectName);
> configuration.setProperty(Environment.SHOW_SQL, "true");
> *return new *HibernateStore(configuration);
> }
>
> *private static *EObject getInputModel()
> {
> Category cat1 = Model1Factory.eINSTANCE.createCategory();
> cat1.setName("CAT1");
> Category cat2 = Model1Factory.eINSTANCE.createCategory();
> cat2.setName("CAT2");
> cat1.getCategories().add(cat2);
> Product p1 = Model1Factory.eINSTANCE.createProduct();
> p1.setName("P1");
> cat1.getProducts().add(p1);
> Product p2 = Model1Factory.eINSTANCE.createProduct();
> p2.setName("P2");
> cat1.getProducts().add(p2);
> Product p3 = Model1Factory.eINSTANCE.createProduct();
> p3.setName("P3");
> cat2.getProducts().add(p3);
> *return *cat1;
> }
> }|
>
>
> BTW do you know if you're able/allowed to commit into the CDO CVS??
> From tomorrow on I'll be working in Switzerland. That could have a
> slightly negative impact on my responsiveness. I hope the hotel I chose
> has a good WLAN at least for the evening hours ;-)
>
> Cheers
> /Eike
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> I've started with an initial version of a hbm.xml file in
>>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>>
>>> <?xml version="1.0"?>
>>> <!DOCTYPE hibernate-mapping SYSTEM
>>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>>
>>> <hibernate-mapping
>>> package="org.eclipse.emf.cdo.internal.protocol.model"
>>> default-access="field">
>>>
>>> <class name="CDOPackageImpl" table="cdo_packages">
>>> <property name="packageURI"
>>> column-name="uri"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="ecore"
>>> type="java.sql.Clob"
>>> not-null="false"
>>> lazy="true"/>
>>> <property name="dynamic"
>>> type="boolean"
>>> not-null="true"/>
>>> </class>
>>>
>>> <class name="CDOClassImpl" table="cdo_classes">
>>> <property name="classifierID"
>>> column-name="classifier"
>>> type="int"
>>> not-null="true"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="isAbstract"
>>> column-name="abstract"
>>> type="boolean"
>>> not-null="true"/>
>>> </class>
>>>
>>> <class name="CDOFeatureImpl" table="cdo_features">
>>> <property name="featureID"
>>> column-name="feature"
>>> type="int"
>>> not-null="true"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="type"
>>> type="int"
>>> not-null="true"/>
>>> <property name="referenceType"
>>> column-name="reftype"
>>> type="string"
>>> not-null="false"/>
>>> <property name="many"
>>> type="boolean"
>>> not-null="true"/>
>>> <property name="containment"
>>> type="boolean"
>>> not-null="false"/>
>>> </class>
>>>
>>> </hibernate-mapping>
>>>
>>>
>>> Open Questions:
>>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>>> which is internally a structure of a long integer (lower bound meta
>>> CDOID) and a normal int (size of the range). I'd like to persist it
>>> as two long values (lower bound and upper bound, both have getters in
>>> CDOIDMetaRange). How is this possible?
>>> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
>>> which is internally a structure of a String (package URI) and an int
>>> (classifierID). How should we map this?
>>> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
>>> which works similar to the aforementioned referenceType.
>>> - The three classes have bidi containment associations
>>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>>> know how to map them.
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>>>
>>> Eike Stepper schrieb:
>>>> To persist/load the meta model I'd like to use Hibernate.
>>>> The following classes must be mapped:
>>>> 1) CDOPackageImpl
>>>> 2) CDOClassImpl
>>>> 3) CDOFeatureImpl
>>>>
>>>> There are also some subclasses of these classes that represent the
>>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>>> instances need not be persisted.
>>>>
>>>> Questions:
>>>> - Do the three classes need to be Serializable and derived
>>>> properties marked transient?
>>>> - Does the usage of JPA annotations require ejb3-persistence.jar to
>>>> be present on the classpath of the protocol plugin (where the three
>>>> classes are located)?
>>>> - To go without the ejb3-persistence.jar could/should I use XML
>>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Mapping the Meta Model [message #111696 is a reply to message #111688] |
Sun, 03 February 2008 10:18 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Hi Martin,
I've bcc'ed Nick.
Nick, can we give Martin commit rights for the
/cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugin s/org.eclipse.emf.cdo.server.hibernate
tree?
Have a nice sunday ;-)
/Eike
Martin Taal schrieb:
> Hi Eike,
> Thanks for the example I will try this out. I just tried but I don't
> have commit rights. It would help a bit if I can get commit rights to
> the cdo-hibernate project. I would not be surpised if we would require
> a specific cdo-teneo plugin to override some default teneo mapping
> behavior. For example Teneo adds its own types for handling xsddate
> and enumeration in the mapping file, for cdo this would be cdo
> specific classes.
>
> I will answer your other news post shortly.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal schrieb:
>>> Hi Eike,
>>> A simple way of storing it, is to store the model as a char blob in
>>> a epackage table. This ofcourse only works if you don't need
>>> database access to the individual model elements, as you read most
>>> information in-memory anyway this seems pretty workable.
>> I also thought about this option and it would be really easy. But the
>> current solution also has 2 advantages: The user/admin can better
>> interpret the meta information (including usage for queries) and I
>> can better learn about Hibernate ;-)
>>
>>> If you have an ecore model for the mapping then I can generate a
>>> mapping for you.
>>>
>>> To answer your questions:
>>> I am not sure are CDOIDMetaRange independent classes which are also
>>> referenced from other classes? Same question for CDOClassProxy?
>>> If they are embedded types then they can be mapped like this:
>>> <component name="referenceType"
>>> class="full_class_name_to_CDOClassProxy">
>>> <property name="package URI" lazy="false" insert="true"
>>> update="true" not-null="true" unique="false" type="java.lang.String"/>
>>> <property name="classifierID" lazy="false" insert="true"
>>> update="true" not-null="false" unique="false" type="int"/>
>>> </component>
>>>
>>> A single reference to another type which is also used by other classes:
>>> <many-to-one name="referenceType" class="CDOClassProxy"/>
>>>
>>> Here is an example of how a bidirectional list is mapped for the
>>> library example, note that on the many side the insert and update
>>> attributes both are false. Also because possibly the package-class
>>> relation is containment you should use a cascade of all,
>>> delete-orphan in the list. Instead of using the entity-name you can
>>> also use the class attribute (with the classname);
>>> <list name="books" lazy="true"
>>> cascade="merge,persist,save-update,lock,refresh">
>>> <cache usage="read-write"/>
>>> <key update="true">
>>> <column name="`book_author_e_id`" not-null="false"
>>> unique="false"/>
>>> </key>
>>> <list-index column="`writer_books_idx`"/>
>>> <one-to-many entity-name="Book"/>
>>> </list>
>>>
>>> <many-to-one name="author" entity-name="Writer"
>>> cascade="merge,persist,save-update,lock,refresh"
>>> foreign-key="book_author" lazy="false" insert="false" update="false"
>>> not-null="false">
>>> <column not-null="false" unique="false"
>>> name="`book_author_e_id`"/>
>>> </many-to-one>
>> Thanks for the hints. I'll try them ASAP.
>> In CVS there is now a test class that does all the setup of a
>> standalone client/server with Mysql. It commits a simple model to the
>> repository. It seems to work pretty well until it runs into the first
>> UnsupportedOperationExceptions of the new HibernateStore. Now we can
>> implement one method after the other:
>>
>> |*public class *HibernateTest
>> {
>> *private static final *String REPOSITORY_NAME = "repo1";
>>
>> *public static **void *main(String[] args) *throws *Exception
>> {
>> IManagedContainer container = initContainer();
>>
>> // Start the transport and create a repository
>> JVMUtil.getAcceptor(container, "default"); // Start the JVM
>> transport
>> CDOServerUtil.addRepository(container, createRepository()); //
>> Start a CDO respository
>>
>> // Establish a communications connection and open a session with
>> the repository
>> IConnector connector = JVMUtil.getConnector(container,
>> "default"); // Open a JVM connection
>> CDOSession session = CDOUtil.openSession(connector,
>> REPOSITORY_NAME, *true*);// Open a CDO session
>>
>> session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);//
>> Not needed after first commit!!!
>>
>> // Open a transaction, and create a new resource
>> CDOTransaction transaction = session.openTransaction();
>> Resource resource = transaction.createResource("/my/big/resource");
>> resource.getContents().add(getInputModel());
>> transaction.commit();
>>
>> // Cleanup
>> session.close();
>> connector.disconnect();
>> }
>>
>> *private static *IManagedContainer initContainer()
>> {
>> // Turn on tracing
>> OMPlatform.INSTANCE.setDebugging(*true*);
>> OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
>> OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
>>
>> // Prepare the standalone infra structure (not needed when
>> running inside Eclipse)
>> IManagedContainer container = ContainerUtil.createContainer(); //
>> Create a wiring container
>> Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
>> JVMUtil.prepareContainer(container); // Prepare the JVM transport
>> CDOServerUtil.prepareContainer(container); // Prepare the CDO server
>> CDOUtil.prepareContainer(container, *false*); // Prepare the CDO
>> client
>> *return *container;
>> }
>>
>> *private static *IRepository createRepository() *throws *Exception
>> {
>> Map<String, String> props = *new *HashMap<String, String>();
>> props.put(Props.PROP_SUPPORTING_AUDITS, "false");
>> props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
>> props.put(Props.PROP_VERIFYING_REVISIONS, "false");
>> props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
>> props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
>> *return *CDOServerUtil.createRepository(REPOSITORY_NAME,
>> createStore(), props);
>> }
>>
>> *private static *IStore createStore() *throws *Exception
>> {
>> DriverManager.setLogWriter(*new *PrintWriter(System.out));
>> Driver driver = *new *com.mysql.jdbc.Driver();
>> DriverManager.registerDriver(driver);
>> String driverName = driver.getClass().getName();
>> String dialectName = MySQLDialect.*class*.getName();
>>
>> Configuration configuration = *new *Configuration();
>> configuration.setProperty(Environment.DRIVER, driverName);
>> configuration.setProperty(Environment.URL,
>> "jdbc:mysql://localhost/cdohibernate");
>> configuration.setProperty(Environment.USER, "root");
>> configuration.setProperty(Environment.DIALECT, dialectName);
>> configuration.setProperty(Environment.SHOW_SQL, "true");
>> *return new *HibernateStore(configuration);
>> }
>>
>> *private static *EObject getInputModel()
>> {
>> Category cat1 = Model1Factory.eINSTANCE.createCategory();
>> cat1.setName("CAT1");
>> Category cat2 = Model1Factory.eINSTANCE.createCategory();
>> cat2.setName("CAT2");
>> cat1.getCategories().add(cat2);
>> Product p1 = Model1Factory.eINSTANCE.createProduct();
>> p1.setName("P1");
>> cat1.getProducts().add(p1);
>> Product p2 = Model1Factory.eINSTANCE.createProduct();
>> p2.setName("P2");
>> cat1.getProducts().add(p2);
>> Product p3 = Model1Factory.eINSTANCE.createProduct();
>> p3.setName("P3");
>> cat2.getProducts().add(p3);
>> *return *cat1;
>> }
>> }|
>>
>>
>> BTW do you know if you're able/allowed to commit into the CDO CVS??
>> From tomorrow on I'll be working in Switzerland. That could have a
>> slightly negative impact on my responsiveness. I hope the hotel I
>> chose has a good WLAN at least for the evening hours ;-)
>>
>> Cheers
>> /Eike
>>
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> I've started with an initial version of a hbm.xml file in
>>>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>>>
>>>> <?xml version="1.0"?>
>>>> <!DOCTYPE hibernate-mapping SYSTEM
>>>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>>>
>>>> <hibernate-mapping
>>>> package="org.eclipse.emf.cdo.internal.protocol.model"
>>>> default-access="field">
>>>>
>>>> <class name="CDOPackageImpl" table="cdo_packages">
>>>> <property name="packageURI"
>>>> column-name="uri"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="ecore"
>>>> type="java.sql.Clob"
>>>> not-null="false"
>>>> lazy="true"/>
>>>> <property name="dynamic"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> </class>
>>>>
>>>> <class name="CDOClassImpl" table="cdo_classes">
>>>> <property name="classifierID"
>>>> column-name="classifier"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="isAbstract"
>>>> column-name="abstract"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> </class>
>>>>
>>>> <class name="CDOFeatureImpl" table="cdo_features">
>>>> <property name="featureID"
>>>> column-name="feature"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="type"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="referenceType"
>>>> column-name="reftype"
>>>> type="string"
>>>> not-null="false"/>
>>>> <property name="many"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> <property name="containment"
>>>> type="boolean"
>>>> not-null="false"/>
>>>> </class>
>>>>
>>>> </hibernate-mapping>
>>>>
>>>>
>>>> Open Questions:
>>>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>>>> which is internally a structure of a long integer (lower bound meta
>>>> CDOID) and a normal int (size of the range). I'd like to persist it
>>>> as two long values (lower bound and upper bound, both have getters
>>>> in CDOIDMetaRange). How is this possible?
>>>> - The field CDOFeatureImpl.referenceType has a type of
>>>> CDOClassProxy which is internally a structure of a String (package
>>>> URI) and an int (classifierID). How should we map this?
>>>> - The field CDOClassImpl.superTypes has a type of
>>>> List<CDOClassProxy> which works similar to the aforementioned
>>>> referenceType.
>>>> - The three classes have bidi containment associations
>>>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>>>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>>>> know how to map them.
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>>>
>>>> Eike Stepper schrieb:
>>>>> To persist/load the meta model I'd like to use Hibernate.
>>>>> The following classes must be mapped:
>>>>> 1) CDOPackageImpl
>>>>> 2) CDOClassImpl
>>>>> 3) CDOFeatureImpl
>>>>>
>>>>> There are also some subclasses of these classes that represent the
>>>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>>>> instances need not be persisted.
>>>>>
>>>>> Questions:
>>>>> - Do the three classes need to be Serializable and derived
>>>>> properties marked transient?
>>>>> - Does the usage of JPA annotations require ejb3-persistence.jar
>>>>> to be present on the classpath of the protocol plugin (where the
>>>>> three classes are located)?
>>>>> - To go without the ejb3-persistence.jar could/should I use XML
>>>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>>>
>>>>> Regards,
>>>>> Eike Stepper
>>>>> ----
>>>>> http://wiki.eclipse.org/CDO
>>>>> http://wiki.eclipse.org/Net4j
>>>>>
>>>
>>>
>
>
|
|
| |
Re: Hibernate Configuration/SessionFactory/Session/Transaction [message #111707 is a reply to message #111638] |
Sun, 03 February 2008 10:33 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my comments below.
I will try to spend time this evening on running a first testcase and integrating the teneo mapping
logic.
gr. Martin
Eike Stepper wrote:
> I'm thinking about how to map these Hibernate concepts to the IStore
> concepts. I learned about the following facts (please correct me or add
> comments):
>
> a) A Transaction instance is needed when data is to be written. A
> Transaction can/must be obtained from a Session. Can there be multiple
> concurrent transactions on a single session?
MT>> As far I know this is not possible as at transaction commit the session will be flushed.
Although session flushing can be controlled.
> b) A Session instance is needed when data is to be read or a Transaction
> is to be started. It can/must be obtained from a SessionFactory. Each
> thread must use its own Session instance (cheap creation).
MT>> correct, session is not threadsafe
MT>> I have worked a lot with JBoss Seam lately and there the approach is to have one session per
conversation (which can be multiple requests) and use one transactions per request (actually there
are two one for update and for re-rendering the view).
> c) A SessionFactory can be built out of a Configuration and can't be
> altered after that. Can there be multiple concurrent factories built out
> of a single configuration?
MT>> See answer below
> d) A Configuration instance is used to add/remove mappings and to create
> SessionFactories for these mappings. Can this be done if
> SessionFactories have already been built? An empty Configuration
> instance is created via default ctor.
MT>> One configuration can create multiple sessionfactories. Looking at the hibernate code this
should be possible but the sessionfactory (or its schemaupdate object) has references back to the
configuration. The schemaupdate class is used to update the db schema which is normally done at the
beginning. So as far as I can see one configuration can be used for multiple sf's and it can be
changed in between. However it is neither very difficult to create new configurations.
>
> My idea is the following:
>
> 1) HibernateStore has a Configuration to manage the mappings
> 2) In addition it builds and keeps a SessionFactory which must be
> rebuilt after each modification of the Configuration
MT>> Yes this is also how my example for dynamic emf works, after adding eclasses dynamically the
sessionfactory is rebuild (resulting in a db-schema update)
> 3) If an IStoreReader is requested by the framework, HibernateStore
> creates a new HibernateStoreReader which uses the current SessionFactory
> to open a new Session
MT>> Ok, clear
> 4) If an IStoreWriter is requested by the framework, HibernateStore
> creates a new HibernateStoreWriter (extends the reader and thus already
> has a Session) which uses the Session to begin a new Transaction
MT>> Is this the same session as used by the reader for that client? It is possible to keep a
session open between requests while still opening and closing transactions. This has some advantages
when doing lazy loading but has as disadvantage that the memory-usage grows.
> 5) There are 2 different events that can cause the Configuration to be
> changed:
> 5.1) A client commits a *new* package. This leads to
> IStoreWriter.writePackages() being called. The HibernateStoreWriter
> implementation will persist the packages (so that they can be retrieved
> after restarts, see 5.2) and pass them to HibernateStore (see 1 + 2)
MT>> My experience with relations db's is that schema changes can result in database locks.
Depending on the use case this can be a problem or not ofcourse.
Question: so we can assume that a client always commits a new package before sending instances for
this new epackage over the wire?
> 5.2) A client loads an object with a class that is in an *existing*
> package (which hasn't been loaded before). This leads to
> IStoreReader.readPackage() being called. The HibernateStoreReader will
> read/return the persisted package and also pass it to HibernateStore (se
> 1 + 2)
MT>> Where does the client load the class from?
>
> Open questions:
> - How must 1) + 2) be protected /synchronized in a concurrent server
> environment, i.e. can a new SessionFactory be built/used while "old"
> SessionFactories (based on previous Configuration states) are still in
> use? Or do we have to use proper ReadWriteLocks, which would cause all
> repository access to halt on each change of mappings?
MT>> I would halt further access to the repository.
The update of the db schema can be done separately (before) creating a new sessionfactory. However,
when updating the database schema there are two issues:
1) update of db schema can lead to database locks in the database, or the other way around the
system can't get a database lock and the update fails. This depends on the database I assume.
2) when the database schema is updated and old sessionfactories are still present then they work on
a new schema with an old mapping. This can be a problem.
Would the following scenario be possible:
- when a writepackage is done the cdo server changes to a so-called 'update-schema' mode which means
that no new client requests are accepted.
- the writepackage waits until all current client requests have been completed.
- the writepackage then does its thing and release the cdo server for further connections
> - How should the actual JDBC Connection/DataSource be managed? Is this .
> part of the Hibernate Configuration/SessionFactory/Session? Should we
> pass a DataSource into the HibernateStore which a HibernateStoreReader
> can use to obtain a Connection when it must create its Hibernate Session?
MT>> Yes hibernate does this.
The easiest way is to pass a set of properties to hibernate. These properties can either contain
jdbc parameters or a datasource name.
> - Where do the mappings come from? In 5.1 and 5.2 we have access to a
> CDOPackage which can deliver the XML string of the corresponding
> EPackage. Is this the place where Teneo comes into game?
MT>> Yes that would work fine, as I can use an ecoreresource impl to read those, right?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Hibernate Configuration/SessionFactory/Session/Transaction [message #111763 is a reply to message #111707] |
Mon, 04 February 2008 20:32 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Hi Martin,
only short comments below because I'm forced to release the line ;-(
Martin Taal schrieb:
> Hi Eike,
> See my comments below.
>
> I will try to spend time this evening on running a first testcase and
> integrating the teneo mapping logic.
>
> gr. Martin
>
> Eike Stepper wrote:
>> I'm thinking about how to map these Hibernate concepts to the IStore
>> concepts. I learned about the following facts (please correct me or
>> add comments):
>>
>> a) A Transaction instance is needed when data is to be written. A
>> Transaction can/must be obtained from a Session. Can there be multiple
>> concurrent transactions on a single session?
> MT>> As far I know this is not possible as at transaction commit the
> session will be flushed. Although session flushing can be controlled.
that's ok.
>
>> b) A Session instance is needed when data is to be read or a
>> Transaction is to be started. It can/must be obtained from a
>> SessionFactory. Each thread must use its own Session instance (cheap
>> creation).
> MT>> correct, session is not threadsafe
> MT>> I have worked a lot with JBoss Seam lately and there the approach
> is to have one session per conversation (which can be multiple requests)
> and use one transactions per request (actually there are two one for
> update and for re-rendering the view).
>
>> c) A SessionFactory can be built out of a Configuration and can't be
>> altered after that. Can there be multiple concurrent factories built
>> out of a single configuration?
> MT>> See answer below
>> d) A Configuration instance is used to add/remove mappings and to
>> create SessionFactories for these mappings. Can this be done if
>> SessionFactories have already been built? An empty Configuration
>> instance is created via default ctor.
> MT>> One configuration can create multiple sessionfactories. Looking at
> the hibernate code this should be possible but the sessionfactory (or
> its schemaupdate object) has references back to the configuration. The
> schemaupdate class is used to update the db schema which is normally
> done at the beginning. So as far as I can see one configuration can be
> used for multiple sf's and it can be changed in between. However it is
> neither very difficult to create new configurations.
>
>>
>> My idea is the following:
>>
>> 1) HibernateStore has a Configuration to manage the mappings
>> 2) In addition it builds and keeps a SessionFactory which must be
>> rebuilt after each modification of the Configuration
> MT>> Yes this is also how my example for dynamic emf works, after adding
> eclasses dynamically the sessionfactory is rebuild (resulting in a
> db-schema update)
good ;-)
>
>> 3) If an IStoreReader is requested by the framework, HibernateStore
>> creates a new HibernateStoreReader which uses the current
>> SessionFactory to open a new Session
> MT>> Ok, clear
>
>> 4) If an IStoreWriter is requested by the framework, HibernateStore
>> creates a new HibernateStoreWriter (extends the reader and thus
>> already has a Session) which uses the Session to begin a new Transaction
> MT>> Is this the same session as used by the reader for that client?
yes.
> It
> is possible to keep a session open between requests while still opening
> and closing transactions. This has some advantages when doing lazy
> loading but has as disadvantage that the memory-usage grows.
there's another bugzilla pending asking for pooling of IStoreAccessors.
Let's postpone such optimizations until we got a whole commit-disconnect-connect-load cycle working.
>
>> 5) There are 2 different events that can cause the Configuration to be
>> changed:
>> 5.1) A client commits a *new* package. This leads to
>> IStoreWriter.writePackages() being called. The HibernateStoreWriter
>> implementation will persist the packages (so that they can be
>> retrieved after restarts, see 5.2) and pass them to HibernateStore
>> (see 1 + 2)
> MT>> My experience with relations db's is that schema changes can result
> in database locks. Depending on the use case this can be a problem or
> not ofcourse.
>
> Question: so we can assume that a client always commits a new package
> before sending instances for this new epackage over the wire?
yes, the client detects usage of "new" packages and commits them before new instances (see the new protocol between ITransaction and IStoreWriter -> CommitContext).
>
>> 5.2) A client loads an object with a class that is in an *existing*
>> package (which hasn't been loaded before). This leads to
>> IStoreReader.readPackage() being called. The HibernateStoreReader will
>> read/return the persisted package and also pass it to HibernateStore
>> (se 1 + 2)
> MT>> Where does the client load the class from?
The actual java.lang.class (EClass) must be already deployed on the client. If not, a dynamic package is created from the Ecore XML string.
>
>>
>> Open questions:
>> - How must 1) + 2) be protected /synchronized in a concurrent server
>> environment, i.e. can a new SessionFactory be built/used while "old"
>> SessionFactories (based on previous Configuration states) are still in
>> use? Or do we have to use proper ReadWriteLocks, which would cause all
>> repository access to halt on each change of mappings?
> MT>> I would halt further access to the repository.
ok, i'll work on a read/write lock.
>
> The update of the db schema can be done separately (before) creating a
> new sessionfactory. However, when updating the database schema there are
> two issues:
> 1) update of db schema can lead to database locks in the database, or
> the other way around the system can't get a database lock and the update
> fails. This depends on the database I assume.
> 2) when the database schema is updated and old sessionfactories are
> still present then they work on a new schema with an old mapping. This
> can be a problem.
both are arguments for an IStore internal r/w locking.
>
> Would the following scenario be possible:
> - when a writepackage is done the cdo server changes to a so-called
> 'update-schema' mode which means that no new client requests are accepted.
> - the writepackage waits until all current client requests have been
> completed.
> - the writepackage then does its thing and release the cdo server for
> further connections
that's what i'd like to achieve with the r/w lock ;-)
>
>> - How should the actual JDBC Connection/DataSource be managed? Is this .
>> part of the Hibernate Configuration/SessionFactory/Session? Should we
>> pass a DataSource into the HibernateStore which a HibernateStoreReader
>> can use to obtain a Connection when it must create its Hibernate Session?
> MT>> Yes hibernate does this.
> The easiest way is to pass a set of properties to hibernate. These
> properties can either contain jdbc parameters or a datasource name.
yep, the test program already does do this. pleaase feel free to comment on that implementation ;-)
>
>> - Where do the mappings come from? In 5.1 and 5.2 we have access to a
>> CDOPackage which can deliver the XML string of the corresponding
>> EPackage. Is this the place where Teneo comes into game?
> MT>> Yes that would work fine, as I can use an ecoreresource impl to
> read those, right?
i guess. i'll be working on an example...
Cheers
/Eike
>
>
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>
>
|
|
|
Re: Mapping the Meta Model [message #111769 is a reply to message #111702] |
Mon, 04 February 2008 20:36 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> I missed your three questions below. See below.
>
> gr. Martin
>
> Eike Stepper wrote:
>> To persist/load the meta model I'd like to use Hibernate.
>> The following classes must be mapped:
>> 1) CDOPackageImpl
>> 2) CDOClassImpl
>> 3) CDOFeatureImpl
>>
>> There are also some subclasses of these classes that represent the
>> system packages CDOCorePackage and CDOResourcePackage. Their instances
>> need not be persisted.
>>
>> Questions:
>> - Do the three classes need to be Serializable and derived properties
>> marked transient?
> MT>> only the properties present in the mapping will be persisted, so
> denoting transient won't be required.
ok.
>> - Does the usage of JPA annotations require ejb3-persistence.jar to be
>> present on the classpath of the protocol plugin (where the three
>> classes are located)?
> MT>> not jpa annotations as teneo uses it, these annotations are placed
> in the model or in a separate xml file there is no binary dependency
> with the ejb3-persistence.jar
>> - To go without the ejb3-persistence.jar could/should I use XML files
>> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
> MT>> yes, when using the hibernate mapping you don't need the
> ejb3-persistence.jar or hibernate-annotations or hibernate-entitymanager.
> The hbm mapping logic has more possibilities than the jpa annotations
> and as far as I can see Hibernate will continue to support the hbm
> approach. The hibernate jpa/entitymanager is in many ways a smaller
> layer over the current hibernate product.
i think the current approach with a separate hbm.xml file in the cdo.server.hibernate plugin is good. let's stay with that one. i'm still hoping that you will try to complete these mappings ;-) if you need help/explanation about the used types - i'm here.
Cheers
/Eike
>
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>
>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111887 is a reply to message #110204] |
Thu, 07 February 2008 17:04 |
Eclipse User |
|
|
|
Originally posted by: tom.eiswind.de
Hello Eike & Martin,
I tried to follow, but not everything I read is clear to me.
If the server doesnt know the EMF model (does he ???) how do you map the
classes ?
What I dont like about CDO (if I misunderstand correct me) is that the
model is registered at the server from the client side. Dont understand
why its done this way. When I set up a server he surely can know about
the model I have.
Thomas
|
|
| |
Re: [CDO] Teneo/Hibernate integration [message #111896 is a reply to message #111894] |
Thu, 07 February 2008 19:25 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Hi Thomas, Martin,
The CDO server is really agnostic about EMF at all. Theoretically it could be used to serve clients with other modeling frameworks as well. This independence of client side frameworks is one reason. Another reason is that the server is much more dynamic if it doesn't require generated models to be deployed at both sides. A third reason is htat a CDO repository is completely self contained, it doesn't have any dependencies from stored model data to deployed model code. This way a repository can't be corrupted by taking away packages from the server installation although there are still instances in the store that refer to these packages.
Thomas, I can't understand why you don't like this design. From a client perspective this is completely transparent. Can you elaborate on your use cases where the above behaviour leads to problems?
Cheers
/Eike
Martin Taal schrieb:
> Hi Thomas,
> The emf model is present on the server but it is normally not used by
> the CDO-server. The cdopackage has a member which contains the ecore
> model as a string. Teneo can be initialized using this ecore-string (and
> a separate annotations/property file).
>
> Eike can give a better answer on why the client passes the model.
> From my side I think it could also be possible to initialize the cdo
> server based on server side information (like an emf model in a ecore
> file).
>
> gr. Martin
>
> Thomas wrote:
>> Hello Eike & Martin,
>>
>> I tried to follow, but not everything I read is clear to me.
>> If the server doesnt know the EMF model (does he ???) how do you map
>> the classes ?
>>
>> What I dont like about CDO (if I misunderstand correct me) is that the
>> model is registered at the server from the client side. Dont
>> understand why its done this way. When I set up a server he surely can
>> know about the model I have.
>>
>> Thomas
>
>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111900 is a reply to message #111896] |
Fri, 08 February 2008 09:29 |
Eclipse User |
|
|
|
Originally posted by: tom.eiswind.de
HI,
ok I understand now what I already suspected.
Following scenario: Its all about the server setup. When I setup my
server, I have (for now) some groovy scripts that populate the database
with required initial data. So the server starts up first time hibernate
initializes the database (create-update), the scripts run and populate
the database. After that the server starts to accept connections from
the clients as they need the initial data in the db.
I think I could have a setup with a "special" setup client that is only
for initializing the db. so for server initialization one would have to
run the setup client once. That would be acceptable.
What I still really wonder about (please tell me about the magic:) is
how cdo werver maps to hibernate pojos if he doesnt know the model
classes. I would expect that the teneo mapping is for the emf classes
but if server doesnt now, to what classes goes the mapping ?
I will take some time thinking before I start on that.
I will ask more questions about net4j later, as I do some other things
than model persistence with my server :)
So long
Thomas
Eike Stepper schrieb:
> Hi Thomas, Martin,
>
> The CDO server is really agnostic about EMF at all. Theoretically it
> could be used to serve clients with other modeling frameworks as well.
> This independence of client side frameworks is one reason. Another
> reason is that the server is much more dynamic if it doesn't require
> generated models to be deployed at both sides. A third reason is htat a
> CDO repository is completely self contained, it doesn't have any
> dependencies from stored model data to deployed model code. This way a
> repository can't be corrupted by taking away packages from the server
> installation although there are still instances in the store that refer
> to these packages.
>
> Thomas, I can't understand why you don't like this design. From a client
> perspective this is completely transparent. Can you elaborate on your
> use cases where the above behaviour leads to problems?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Thomas,
>> The emf model is present on the server but it is normally not used by
>> the CDO-server. The cdopackage has a member which contains the ecore
>> model as a string. Teneo can be initialized using this ecore-string
>> (and a separate annotations/property file).
>>
>> Eike can give a better answer on why the client passes the model.
>> From my side I think it could also be possible to initialize the cdo
>> server based on server side information (like an emf model in a ecore
>> file).
>>
>> gr. Martin
>>
>> Thomas wrote:
>>> Hello Eike & Martin,
>>>
>>> I tried to follow, but not everything I read is clear to me.
>>> If the server doesnt know the EMF model (does he ???) how do you map
>>> the classes ?
>>>
>>> What I dont like about CDO (if I misunderstand correct me) is that
>>> the model is registered at the server from the client side. Dont
>>> understand why its done this way. When I set up a server he surely
>>> can know about the model I have.
>>>
>>> Thomas
>>
>>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111902 is a reply to message #111900] |
Fri, 08 February 2008 10:26 |
|
Hi Thomas,
Yes, I think you got it ;-)
If you need initial population of a repository I'd suggest that you deploy
the CDO client plugins to the server as well (without UI) and the Net4j
JVM transport plugins.
Then you can write code as the following (not tested since I've got no
installation here):
// Start a JVM acceptor
IPluginContainer.INSTANCE.getElement("org.eclipse.net4j.acceptors ", "jvm",
"default");
// Open a CDO session via a JVM connector
CDOSession session = CDOUtil.openSession(IPluginContainer.INSTANCE,
"jvm://default/repo1", true);
// Now open a transaction on the session and commit packages and
resources/objects
// Eventually deactivate the JVM connector and/or the JVM connector
---
WRT hibernate mapping on the CDO server:
It's not finished yet! But we plan to use own EntityTuplizers that realize
the mapping of CDORevisions directly. No EClasses needed. The benefits are
better performance and we don't loose the disconnected object graph
characteristics of CDO (CDORevisions don't have java references onto each
other).
Let's see if we manage ;-)
Cheers
/Eike
Thomas wrote:
> HI,
> ok I understand now what I already suspected.
> Following scenario: Its all about the server setup. When I setup my
> server, I have (for now) some groovy scripts that populate the database
> with required initial data. So the server starts up first time hibernate
> initializes the database (create-update), the scripts run and populate
> the database. After that the server starts to accept connections from
> the clients as they need the initial data in the db.
> I think I could have a setup with a "special" setup client that is only
> for initializing the db. so for server initialization one would have to
> run the setup client once. That would be acceptable.
> What I still really wonder about (please tell me about the magic:) is
> how cdo werver maps to hibernate pojos if he doesnt know the model
> classes. I would expect that the teneo mapping is for the emf classes
> but if server doesnt now, to what classes goes the mapping ?
> I will take some time thinking before I start on that.
> I will ask more questions about net4j later, as I do some other things
> than model persistence with my server :)
> So long
> Thomas
> Eike Stepper schrieb:
>> Hi Thomas, Martin,
>>
>> The CDO server is really agnostic about EMF at all. Theoretically it
>> could be used to serve clients with other modeling frameworks as well.
>> This independence of client side frameworks is one reason. Another
>> reason is that the server is much more dynamic if it doesn't require
>> generated models to be deployed at both sides. A third reason is htat a
>> CDO repository is completely self contained, it doesn't have any
>> dependencies from stored model data to deployed model code. This way a
>> repository can't be corrupted by taking away packages from the server
>> installation although there are still instances in the store that refer
>> to these packages.
>>
>> Thomas, I can't understand why you don't like this design. From a client
>> perspective this is completely transparent. Can you elaborate on your
>> use cases where the above behaviour leads to problems?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Thomas,
>>> The emf model is present on the server but it is normally not used by
>>> the CDO-server. The cdopackage has a member which contains the ecore
>>> model as a string. Teneo can be initialized using this ecore-string
>>> (and a separate annotations/property file).
>>>
>>> Eike can give a better answer on why the client passes the model.
>>> From my side I think it could also be possible to initialize the cdo
>>> server based on server side information (like an emf model in a ecore
>>> file).
>>>
>>> gr. Martin
>>>
>>> Thomas wrote:
>>>> Hello Eike & Martin,
>>>>
>>>> I tried to follow, but not everything I read is clear to me.
>>>> If the server doesnt know the EMF model (does he ???) how do you map
>>>> the classes ?
>>>>
>>>> What I dont like about CDO (if I misunderstand correct me) is that
>>>> the model is registered at the server from the client side. Dont
>>>> understand why its done this way. When I set up a server he surely
>>>> can know about the model I have.
>>>>
>>>> Thomas
>>>
>>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111904 is a reply to message #111902] |
Fri, 08 February 2008 11:13 |
Eclipse User |
|
|
|
Originally posted by: tom.eiswind.de
> WRT hibernate mapping on the CDO server:
> It's not finished yet! But we plan to use own EntityTuplizers that
> realize the mapping of CDORevisions directly. No EClasses needed. The
> benefits are better performance and we don't loose the disconnected
> object graph characteristics of CDO (CDORevisions don't have java
> references onto each other).
>
> Let's see if we manage ;-)
HI Eike,
I still dont really understand. I expect that a hibernate mapping goes
for a pojo. I just want to understand whats going on there, but I dont
have a concept of CDORevision. Wheres the magic there ? and how is it
then ehwn I issue a query on hibernate "FROM Value..." how is that
transformed when the server doesnt know Value at all ?
So long & thx for your patience
Thomas
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111907 is a reply to message #111904] |
Fri, 08 February 2008 12:32 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Thomas,
Teneo uses both the pojo mode and the map mode. For more info on map mode see the chapter on Dynamic
models in the hibernate manual. Teneo will automatically decide if it uses pojo or map mode, so if
there is an instance class available for an EClass then it will use pojo mode for that EClass. If
there is no instance class available (like in the cdo-server) then it will use map mode.
The advantage of using pojo mode is that it allows hibernate proxying, the advantage of map mode is
its flexibility in determining at runtime which implementation class to use. For example in map mode
it is perfectly possible to persist a CDORevision in for example a table for customer orders or
products.
To handle a specific implementation class (like CDORevision) there are also some other details (like
hibernate propertyaccessors) which need to be implemented but that's very doable.
Using map mode, it is just possible to do any query as with pojo mode. So on the cdo server the
query from Value would return CDORevision objects which have an eclass (or actually cdoclass) with
the name Value, the CDORevision object contains all attributes (and their values) of a Value type
(as defined in the model).
gr. Martin
Thomas wrote:
> > WRT hibernate mapping on the CDO server:
> > It's not finished yet! But we plan to use own EntityTuplizers that
> > realize the mapping of CDORevisions directly. No EClasses needed. The
> > benefits are better performance and we don't loose the disconnected
> > object graph characteristics of CDO (CDORevisions don't have java
> > references onto each other).
> >
> > Let's see if we manage ;-)
>
> HI Eike,
>
> I still dont really understand. I expect that a hibernate mapping goes
> for a pojo. I just want to understand whats going on there, but I dont
> have a concept of CDORevision. Wheres the magic there ? and how is it
> then ehwn I issue a query on hibernate "FROM Value..." how is that
> transformed when the server doesnt know Value at all ?
>
> So long & thx for your patience
> Thomas
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111908 is a reply to message #111904] |
Fri, 08 February 2008 12:32 |
|
Thomas wrote:
> > WRT hibernate mapping on the CDO server:
> > It's not finished yet! But we plan to use own EntityTuplizers that
> > realize the mapping of CDORevisions directly. No EClasses needed. The
> > benefits are better performance and we don't loose the disconnected
> > object graph characteristics of CDO (CDORevisions don't have java
> > references onto each other).
> >
> > Let's see if we manage ;-)
> HI Eike,
> I still dont really understand. I expect that a hibernate mapping goes
> for a pojo.
Wrong, this seems to be the Hibernate default, but there's for example
also a DynamicMap mode. In general Hibernate can map arbitrary structures
of data by abstracting model access to Tuplizers. The CDO HibernateStore
will implement its own Tuplizers to let Hibernate access CDORevisions.
> I just want to understand whats going on there, but I dont
> have a concept of CDORevision. Wheres the magic there ?
No magic. A CDORevision captures an immutable state of an object at a
specified period. It works similar to a DynamicEObject but without
actually depending on Ecore. The most important difference is that
references to other objects are not encoded through java references but
rather through CDOIDs which can be resolved to target CDORevisions by a
CDORevisionResolver. CDORevision also acts as a sort of an efficient
transfer object. I guess it's best to dive a bit into the code ;-)
> and how is it
> then ehwn I issue a query on hibernate "FROM Value..." how is that
> transformed when the server doesnt know Value at all ?
It's not true that the server doesn't know Value at all. It knoes
everything about Value (and about any other class that has been committed
into a repository) that it needs to persist and load instances of Value.
It's just that this knowledge does not necessarily need to be expressed in
terms of Ecore concepts (types). For various reasons (most of them
explained in a previous answer) a CDO server uses own concepts for this
purpose. This is particularly true for the repository implementation and
for all existing store implementations. It is probably not true for the
new HibernateStore implementation which will recreate the original
EPackage from string data in a CDOPackage just to be able to reuse mapping
creation code that Martin developed in the context of his Teneo project.
The actual mapping of instances will be done by Hibernate without
dependencies on Ecore again.
M;artin, please correct me if I got something wrong ;-)
Cheers
/Eike
> So long & thx for your patience
> Thomas
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #111917 is a reply to message #111908] |
Fri, 08 February 2008 16:14 |
Eclipse User |
|
|
|
Originally posted by: tom.eiswind.de
Thanks Eike & Martin.
I simply didnt know about map mode. I will have a look at this.
Is there any documentation on net4j ? I want to learn more about it :)
Regards Thomas
Eike Stepper schrieb:
> Thomas wrote:
>
>> > WRT hibernate mapping on the CDO server:
>> > It's not finished yet! But we plan to use own EntityTuplizers that
>> > realize the mapping of CDORevisions directly. No EClasses needed. The
>> > benefits are better performance and we don't loose the disconnected
>> > object graph characteristics of CDO (CDORevisions don't have java
>> > references onto each other).
>> >
>> > Let's see if we manage ;-)
>
>> HI Eike,
>
>> I still dont really understand. I expect that a hibernate mapping goes
>> for a pojo.
> Wrong, this seems to be the Hibernate default, but there's for example
> also a DynamicMap mode. In general Hibernate can map arbitrary
> structures of data by abstracting model access to Tuplizers. The CDO
> HibernateStore will implement its own Tuplizers to let Hibernate access
> CDORevisions.
>
>> I just want to understand whats going on there, but I dont have a
>> concept of CDORevision. Wheres the magic there ?
> No magic. A CDORevision captures an immutable state of an object at a
> specified period. It works similar to a DynamicEObject but without
> actually depending on Ecore. The most important difference is that
> references to other objects are not encoded through java references but
> rather through CDOIDs which can be resolved to target CDORevisions by a
> CDORevisionResolver. CDORevision also acts as a sort of an efficient
> transfer object. I guess it's best to dive a bit into the code ;-)
>
>> and how is it then ehwn I issue a query on hibernate "FROM Value..."
>> how is that transformed when the server doesnt know Value at all ?
> It's not true that the server doesn't know Value at all. It knoes
> everything about Value (and about any other class that has been
> committed into a repository) that it needs to persist and load instances
> of Value. It's just that this knowledge does not necessarily need to be
> expressed in terms of Ecore concepts (types). For various reasons (most
> of them explained in a previous answer) a CDO server uses own concepts
> for this purpose. This is particularly true for the repository
> implementation and for all existing store implementations. It is
> probably not true for the new HibernateStore implementation which will
> recreate the original EPackage from string data in a CDOPackage just to
> be able to reuse mapping creation code that Martin developed in the
> context of his Teneo project. The actual mapping of instances will be
> done by Hibernate without dependencies on Ecore again.
>
> M;artin, please correct me if I got something wrong ;-)
>
> Cheers
> /Eike
>
>
>> So long & thx for your patience
>> Thomas
>
>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #112028 is a reply to message #111917] |
Sat, 09 February 2008 08:20 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
This is a multi-part message in MIME format.
--------------090204060805000606000406
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Thomas schrieb:
> Thanks Eike & Martin.
>
> I simply didnt know about map mode. I will have a look at this.
>
> Is there any documentation on net4j ? I want to learn more about it :)
Not much I fear ;-( The bast is to start with the JavaDoc for IConnector.
The basic concepts are IBuffer, IChannel, IProtocol as well as
IConnector and IAcceptor:
- IBuffers (the meaning should be clear) are transmitted through virtual
IChannels and received through IBufferHandlers of the peer channel
instances.
- IConnectors represent the endpoints of a physical connection (for
example sockets) and multiplex arbitrary numbers of IChannels through
this connection. In fact a Connector is an IConnector and an
IChannelMultiplexer.
- IAcceptors accept connections at the server side (of that connection)
and create IConnectors of ConnectorLocation.SERVER.
- IProtocols are basically named IBufferHandlers but make their
association with server-side IChannels much easier through the use of
registered IProtocolFactoies.
Since direct (and asynchronous) handling of buffers is fast but
inconvenient for many application needs there is an important
implementation of IProtocol. A SignalProtocol, together with the Signals
it defines, forms a layer on top of the basic concepts and provides a
framework that you can use to decompose your communication needs into
single Signals, each representing a single manifestation (a
communications case) of the client/server paradigm: request -->
indication --> response --> confirmation
For each such communications case the application has to provide 2
classes that implement the client-side and the server-side respectively:
|*public abstract class *RequestWithConfirmation<RESULT> *extends *SignalActor<RESULT>
{
*protected abstract **void *requesting(ExtendedDataOutputStream out) *throws *IOException;
*protected abstract *RESULT confirming(ExtendedDataInputStream in) *throws *IOException;
}|
|*public abstract class *IndicationWithResponse *extends *SignalReactor
{
*protected abstract **void *indicating(ExtendedDataInputStream in) *throws *IOException;
*protected abstract **void *responding(ExtendedDataOutputStream out) *throws *IOException;
}|
Notice that the implementor of thhese methods can use streams to write
data to and read it from. The SignalProtocol framework takes care of
cutting these streams into sequences of buffers which are multiplexed
through the underlying channel and demultiplexed into streams again at
the peer side. The framework also takes care of signal creation and all
threading issues. The CDO protocol is an example of such a
SignalProtocol. Other examples are the experimental JMS provider and a
simple but extensible collaboration platform (see buddies and chat).
Here are some snippets from the BuddiesServerProtocol:
|*public class *BuddiesServerProtocol *extends *SignalProtocol
{
*public *String getType()
{
*return *ProtocolConstants.PROTOCOL_NAME;
}
@Override
*protected *SignalReactor doCreateSignalReactor(*short *signalID)
{
*switch *(signalID)
{
*case *ProtocolConstants.SIGNAL_OPEN_SESSION:
*return new *OpenSessionIndication();
*case *ProtocolConstants.SIGNAL_BUDDY_STATE:
*return new *ServerBuddyStateIndication();
*case *ProtocolConstants.SIGNAL_INSTALL_FACILITY:
*return new *InstallFacilityIndication();
*case *ProtocolConstants.SIGNAL_INITIATE_COLLABORATION:
*return new *InitiateCollaborationIndication();
*case *ProtocolConstants.SIGNAL_INVITE_BUDDIES:
*return new *InviteBuddiesIndication();
*case *ProtocolConstants.SIGNAL_COLLABORATION_LEFT:
*return new *ServerCollaborationLeftIndication();
*case *ProtocolConstants.SIGNAL_MESSAGE:
*return new *MessageIndication(IBuddyAdmin.INSTANCE);
}
*return null*;
}
}|
|*public class *InstallFacilityIndication *extends *IndicationWithResponse
{
*private **boolean *success;
@Override
*protected **short *getSignalID()
{
*return *ProtocolConstants.SIGNAL_INSTALL_FACILITY;
}
@Override
*protected **void *indicating(ExtendedDataInputStream in) *throws *IOException
{
*long *collaborationID = in.readLong();
String facilityType = in.readString();
*try*
{
String description = String.valueOf(collaborationID);
IFacility facility = (IFacility)IPluginContainer.INSTANCE.getElement(FACILITY_GRO UP, facilityType, description);
Collaboration collaboration = (Collaboration)BuddyAdmin.INSTANCE.getCollaboration(collabor ationID);
*if *(collaboration != *null*)
{
facility.setCollaboration(collaboration);
collaboration.addFacility(facility, *true*);
ISession session = (ISession)getProtocol().getInfraStructure();
IBuddy initiator = session.getSelf();
*for *(IBuddy buddy : collaboration.getBuddies())
{
*if *(buddy != initiator)
{
*try*
{
IChannel channel = buddy.getSession().getChannel();
*new *FacilityInstalledNotification(channel, collaborationID, facilityType).send();
}
*catch *(Exception ex)
{
OM.LOG.error(ex);
}
}
}
success = *true*;
}
}
*catch *(RuntimeException ex)
{
OM.LOG.error(ex);
}
}
@Override
*protected **void *responding(ExtendedDataOutputStream out) *throws *IOException
{
out.writeBoolean(success);
}
}|
I hope this makes it a bit easier to start. Further questions are
welcome, doc/tutorial contributions as well ;-)
Enjoy your weekend
/Eike
>
> Regards Thomas
>
> Eike Stepper schrieb:
>> Thomas wrote:
>>
>>> > WRT hibernate mapping on the CDO server:
>>> > It's not finished yet! But we plan to use own EntityTuplizers that
>>> > realize the mapping of CDORevisions directly. No EClasses needed.
>>> The
>>> > benefits are better performance and we don't loose the disconnected
>>> > object graph characteristics of CDO (CDORevisions don't have java
>>> > references onto each other).
>>> >
>>> > Let's see if we manage ;-)
>>
>>> HI Eike,
>>
>>> I still dont really understand. I expect that a hibernate mapping
>>> goes for a pojo.
>> Wrong, this seems to be the Hibernate default, but there's for
>> example also a DynamicMap mode. In general Hibernate can map
>> arbitrary structures of data by abstracting model access to
>> Tuplizers. The CDO HibernateStore will implement its own Tuplizers to
>> let Hibernate access CDORevisions.
>>
>>> I just want to understand whats going on there, but I dont have a
>>> concept of CDORevision. Wheres the magic there ?
>> No magic. A CDORevision captures an immutable state of an object at a
>> specified period. It works similar to a DynamicEObject but without
>> actually depending on Ecore. The most important difference is that
>> references to other objects are not encoded through java references
>> but rather through CDOIDs which can be resolved to target
>> CDORevisions by a CDORevisionResolver. CDORevision also acts as a
>> sort of an efficient transfer object. I guess it's best to dive a bit
>> into the code ;-)
>>
>>> and how is it then ehwn I issue a query on hibernate "FROM Value..."
>>> how is that transformed when the server doesnt know Value at all ?
>> It's not true that the server doesn't know Value at all. It knoes
>> everything about Value (and about any other class that has been
>> committed into a repository) that it needs to persist and load
>> instances of Value. It's just that this knowledge does not
>> necessarily need to be expressed in terms of Ecore concepts (types).
>> For various reasons (most of them explained in a previous answer) a
>> CDO server uses own concepts for this purpose. This is particularly
>> true for the repository implementation and for all existing store
>> implementations. It is probably not true for the new HibernateStore
>> implementation which will recreate the original EPackage from string
>> data in a CDOPackage just to be able to reuse mapping creation code
>> that Martin developed in the context of his Teneo project. The actual
>> mapping of instances will be done by Hibernate without dependencies
>> on Ecore again.
>>
>> M;artin, please correct me if I got something wrong ;-)
>>
>> Cheers
>> /Eike
>>
>>
>>> So long & thx for your patience
>>> Thomas
>>
>>
--------------090204060805000606000406
Content-Type: multipart/related;
boundary="------------020504000202060005020609"
--------------020504000202060005020609
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Thomas schrieb:
<blockquote cite="mid:fohv5n$5nd$1@build.eclipse.org" type="cite">Thanks
Eike & Martin.
<br>
<br>
I simply didnt know about map mode. I will have a look at this.
<br>
<br>
Is there any documentation on net4j ? I want to learn more about it :)
<br>
</blockquote>
Not much I fear ;-( The bast is to start with the JavaDoc for
IConnector.<br>
<br>
The basic concepts are IBuffer, IChannel, IProtocol as well as
IConnector and IAcceptor:<br>
- IBuffers (the meaning should be clear) are transmitted through
virtual IChannels and received through IBufferHandlers of the peer
channel instances. <br>
- IConnectors represent the endpoints of a physical connection (for
example sockets) and multiplex arbitrary numbers of IChannels through
this connection. In fact a Connector is an IConnector and an
IChannelMultiplexer. <br>
- IAcceptors accept connections at the server side (of that connection)
and create IConnectors of ConnectorLocation.SERVER. <br>
- IProtocols are basically named IBufferHandlers but make their
association with server-side IChannels much easier through the use of
registered IProtocolFactoies.<br>
<br>
<img src="cid:part1.09070102.02060400@sympedia.de" alt=""><br>
<br>
Since direct (and asynchronous) handling of buffers is fast but
inconvenient for many application needs there is an important
implementation of IProtocol. A SignalProtocol, together with the
Signals it defines, forms a layer on top of the basic concepts and
provides a framework that you can use to decompose your communication
needs into single Signals, each representing a single manifestation (a
communications case) of the client/server paradigm: request -->
indication --> response --> confirmation<br>
<br>
<img src="cid:part2.07030202.09070306@sympedia.de" alt=""><br>
<br>
For each such communications case the application has to provide 2
classes that implement the client-side and the server-side respectively:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" bgcolor="#ffffcc"
nowrap="nowrap" valign="top"> <code><font color="#7f0055"><b>public
|
|
| | | | |
Re: Skeleton Implementation [message #614355 is a reply to message #111137] |
Wed, 30 January 2008 22:24 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I checked the project out and the related projects. I must say that you are quick :-). I looked
through the code. A few questions/remarks:
- Can you explain how the version number works in the relational db store you have. I mean
specifically for foreign keys, for example if an object A refers to B and I store a new version of
B, to which version does A then point?
- when is the writepackage method called? The ecore package is stored in the database also in your
view or can this be ignored (for now)?
- The storewriter has a method writeRevision, with hibernate write operations cascade automatically
to refered-to objects, so the writeRevision method will have side effects. This is no problem?
- How does storereader.readResourceID work for the relational store? Is a resource also stored
explicitly?
- I see that each object has a CDOID, which has an internal value of long (correct?), this means
that composite or String primary keys are not supported?
It would not be to difficult to add Teneo here. I can also add the hibernate initialization code. To
get a testcase up and running, can I use the standalone code you specified earlier for this?
I can get the epackage from the cdopackageregistry?
gr. Martin
Eike Stepper wrote:
> Hi Martin,
>
> I've just committed a first version of a plugin to the CVS:
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>
>
> It contains my CDORevisionTuplizer and a skeleton implementation of CDOs
> storage framework.
> I think this is a good point to start from. The obvious places with
> missing code (19x) are marked // TODO Implement me
>
> The 2 main classes to fill with functionality are:
> - HibernateStoreReader
> - HibernateStoreWriter
>
> We can ignore HibernateStoreChunkReader at the beginning.
> I'm sure I can help with the missing functionality, but I have no clue
> how to connect the pieces.
> May be you get an idea when looking at the project...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
> Eike Stepper schrieb:
>> I'd like to start a new thread here which can be used to discuss the
>> given topic.
>>
>> I'll start to write some sub threads, mainly with questions about
>> Hibernate details...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation [message #614357 is a reply to message #111154] |
Wed, 30 January 2008 23:30 |
|
Martin Taal schrieb:
> Hi Eike,
> I checked the project out and the related projects. I must say that
> you are quick :-).
I give my best ;-)
> I looked through the code. A few questions/remarks:
> - Can you explain how the version number works in the relational db
> store you have. I mean specifically for foreign keys, for example if
> an object A refers to B and I store a new version of B, to which
> version does A then point?
The version is never part of reference information.
As you'll have noticed a CDOObject is just a thin wrapper for a
CDORevision, which is identified by CDOID and version. It's the task of
a "view" to associate objects with the correct revision. This depends on
the type of view, CDOView and CDOTransaction deliver always the latest
revision (determined by revised==null) and CDOAudit delivers a revision
where the timeStamp of the view (audit) is between the "created" and
"revised" values of the revision.
All this is not important if we decide to ignore the auditing mode. Then
we (hibernate) would use the version of the revision only for optimistic
locking.
> - when is the writepackage method called? The ecore package is stored
> in the database also in your view or can this be ignored (for now)?
I don't think that we can ignore this.
The method is called by the repository when it receives a
CommitTransactionIndication (a signal over the network after the client
committed a transaction) that contains new packages. If we ignore this
indication the repository would later startup without knowledgeabout
previously used packages.
I also thought about how to store the meta model. The CDO internal meta
model is comparingly simple, it only knows about CDOPackages, CDOClasses
and CDOFeatures. These model elements only carry information that is
necessary for persistence aspects. I see some options:
1) Use Hibernate to create a static model and its mapping to a static
schema. Ideally we could reuse the existing code (CDOPackageImpl,
CDOClassImpl and CDOFeatureImpl). Isn't Hibernate about mapping POJOs?
2) Use the JDBC connection of a Hibernate session (that is used for the
dynamic mapping) and the code from my DBStore.
3) Store the meta model outside of the DB within the file system. This
creates extra configuration and runtime maintenance.
> - The storewriter has a method writeRevision, with hibernate write
> operations cascade automatically to refered-to objects, so the
> writeRevision method will have side effects. This is no problem?
I'm not sure that I understand this. May be I explain the semantics of
the writeRevision() method:
When a client modifies CDOObjects the associated CDOTransaction becomes
dirty. The CDOTransaction remembers all modified objects (in fact it
even temporarily stores their associated, transactional revisions). When
the transaction is committed all the internal state of the transaction
(particularly the transactional revisions of the modified objects) is
transferred to the server where it is deserialized. First added packages
are written to the store via IStoreWriter.writePackages() then each of
the received revisions of the new/modified objects is written to the
store via IStoreWriter.writeRevision(). No matter what kind of
references do exist between the original objects. A CDORevision doesn't
have Java reference handles to other CDORevisions. References between
the original objects are completely represented as CDOIDs (see below).
> - How does storereader.readResourceID work for the relational store?
> Is a resource also stored explicitly?
Yes, a CDOResource implements Resource, Resource.Internal,
InternalCDOObject and InternalEObject. As a consequence it has all the
behaviour of other CDOObjects, i.e. it is persistent. Of course you
can't nest them. See them as a sort of named entry points into the
persistent object wood (multi tree) of a CDO repository. As a CDOObject
a CDOResource also has a CDOID which is used by references from other
objects (eContainer, but could also be normal named xrefs). The "path"
of a CDOResource is only used when creating/loading the resource into a
CDOView. Then IStoreReader.readResourceID(String path) is needed to
determine the real PK of the resource object.
> - I see that each object has a CDOID, which has an internal value of
> long (correct?), this means that composite or String primary keys are
> not supported?
Not at the moment, but I already had discussions with Simon about
possibilities to transfer the responsibility for CDOID creation from the
repository into the store. In fact this has already happened, but the
store is currently not allowed to break the contract of the
CDOID.getValue() API.
>
> It would not be to difficult to add Teneo here. I can also add the
> hibernate initialization code. To get a testcase up and running, can I
> use the standalone code you specified earlier for this?
Yes, that should basically work. I'm already curious ;-)
> I can get the epackage from the cdopackageregistry?
Only if you previously registered it in the same CDOSession or if you
previously registered in in another session and committed it to the
repository (then a CDOPackageDescriptor is automatically registered with
the CDOPackageRegistry of the new session).
I know this is a lot of stuff, but I'm sure that you'll find it logical
if work with it a bit. I think it'd be a good idea to play a bit with
the CDO UI, i.e. the CDO Sessions viewpart and the CDOEditor. Tell me if
you need help with it.
Cheers and good night ;-)
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi Martin,
>>
>> I've just committed a first version of a plugin to the CVS:
>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>>
>>
>> It contains my CDORevisionTuplizer and a skeleton implementation of
>> CDOs storage framework.
>> I think this is a good point to start from. The obvious places with
>> missing code (19x) are marked // TODO Implement me
>>
>> The 2 main classes to fill with functionality are:
>> - HibernateStoreReader
>> - HibernateStoreWriter
>>
>> We can ignore HibernateStoreChunkReader at the beginning.
>> I'm sure I can help with the missing functionality, but I have no
>> clue how to connect the pieces.
>> May be you get an idea when looking at the project...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>> Eike Stepper schrieb:
>>> I'd like to start a new thread here which can be used to discuss the
>>> given topic.
>>>
>>> I'll start to write some sub threads, mainly with questions about
>>> Hibernate details...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation [message #614358 is a reply to message #111170] |
Thu, 31 January 2008 08:25 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my remarks/questions below.
A new question: when the client commits its transaction the objects are sent to the cdo server and
de-serialized to cdoobjects/cdorevisions. These objects are then persisted. After the persist step
are the cdoobjects/cdorevisions discarded or are they kept in-memory (so the server keeps state
between commit transactions)?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> I checked the project out and the related projects. I must say that
>> you are quick :-).
> I give my best ;-)
>
>> I looked through the code. A few questions/remarks:
>> - Can you explain how the version number works in the relational db
>> store you have. I mean specifically for foreign keys, for example if
>> an object A refers to B and I store a new version of B, to which
>> version does A then point?
> The version is never part of reference information.
> As you'll have noticed a CDOObject is just a thin wrapper for a
> CDORevision, which is identified by CDOID and version. It's the task of
> a "view" to associate objects with the correct revision. This depends on
> the type of view, CDOView and CDOTransaction deliver always the latest
> revision (determined by revised==null) and CDOAudit delivers a revision
> where the timeStamp of the view (audit) is between the "created" and
> "revised" values of the revision.
MT>> As it interests me how you did this I'll bug you with some more questions :-): what I
understand is that in audit mode the different versions of one object are stored in the same table.
In the database do the foreign key constraints contain the version also?
Old versions of a deleted object are also present in the db, I assume? How do you prevent queries
from returning old versions of deleted objects (maybe maintain a deleted flag in all versions?)?
Do you keep a flag in the db which keeps track of the last version of each object, so that it is
possible to easily query for the last version?
>
> All this is not important if we decide to ignore the auditing mode. Then
> we (hibernate) would use the version of the revision only for optimistic
> locking.
>
>> - when is the writepackage method called? The ecore package is stored
>> in the database also in your view or can this be ignored (for now)?
> I don't think that we can ignore this.
> The method is called by the repository when it receives a
> CommitTransactionIndication (a signal over the network after the client
> committed a transaction) that contains new packages. If we ignore this
> indication the repository would later startup without knowledgeabout
> previously used packages.
MT>>
With Teneo the epackages are explicitly set by the user when the store initializes. With CDO I
understand now that you can register new epackages on the fly or when the user commits for the first
time, correct?
Is it possible for the user to specify/pass the epackages when the cdo server starts? Is there such
an explicit initialization step?
With Teneo annotations can also be specified in a separate xml file and there is a property file
which allows you to set several options. Is there a possibility to pass this information through CDO
to Teneo. For example using custom cdo properties, does cdo have a property file somewhere for
simple configuration options which can be read when the cdo server starts?
>
> I also thought about how to store the meta model. The CDO internal meta
> model is comparingly simple, it only knows about CDOPackages, CDOClasses
> and CDOFeatures. These model elements only carry information that is
> necessary for persistence aspects. I see some options:
> 1) Use Hibernate to create a static model and its mapping to a static
> schema. Ideally we could reuse the existing code (CDOPackageImpl,
> CDOClassImpl and CDOFeatureImpl). Isn't Hibernate about mapping POJOs?
> 2) Use the JDBC connection of a Hibernate session (that is used for the
> dynamic mapping) and the code from my DBStore.
> 3) Store the meta model outside of the DB within the file system. This
> creates extra configuration and runtime maintenance.
>
>> - The storewriter has a method writeRevision, with hibernate write
>> operations cascade automatically to refered-to objects, so the
>> writeRevision method will have side effects. This is no problem?
> I'm not sure that I understand this. May be I explain the semantics of
> the writeRevision() method:
> When a client modifies CDOObjects the associated CDOTransaction becomes
> dirty. The CDOTransaction remembers all modified objects (in fact it
> even temporarily stores their associated, transactional revisions). When
> the transaction is committed all the internal state of the transaction
> (particularly the transactional revisions of the modified objects) is
> transferred to the server where it is deserialized. First added packages
> are written to the store via IStoreWriter.writePackages() then each of
> the received revisions of the new/modified objects is written to the
> store via IStoreWriter.writeRevision(). No matter what kind of
> references do exist between the original objects. A CDORevision doesn't
> have Java reference handles to other CDORevisions. References between
> the original objects are completely represented as CDOIDs (see below).
MT>> I think to get this working with hibernate the propertyaccessor for a ereference property
should not return the cdoid but the cdorevision identified by the cdoid. Hibernate will then
depending on the cascade options also automatically persist the refered-to objects.
>
>> - How does storereader.readResourceID work for the relational store?
>> Is a resource also stored explicitly?
> Yes, a CDOResource implements Resource, Resource.Internal,
> InternalCDOObject and InternalEObject. As a consequence it has all the
> behaviour of other CDOObjects, i.e. it is persistent. Of course you
> can't nest them. See them as a sort of named entry points into the
> persistent object wood (multi tree) of a CDO repository. As a CDOObject
> a CDOResource also has a CDOID which is used by references from other
> objects (eContainer, but could also be normal named xrefs). The "path"
> of a CDOResource is only used when creating/loading the resource into a
> CDOView. Then IStoreReader.readResourceID(String path) is needed to
> determine the real PK of the resource object.
>
>> - I see that each object has a CDOID, which has an internal value of
>> long (correct?), this means that composite or String primary keys are
>> not supported?
> Not at the moment, but I already had discussions with Simon about
> possibilities to transfer the responsibility for CDOID creation from the
> repository into the store. In fact this has already happened, but the
> store is currently not allowed to break the contract of the
> CDOID.getValue() API.
MT>> if the getValue would return Object then this would already solve it I think. What do you think?
>
>>
>> It would not be to difficult to add Teneo here. I can also add the
>> hibernate initialization code. To get a testcase up and running, can I
>> use the standalone code you specified earlier for this?
> Yes, that should basically work. I'm already curious ;-)
MT>> I have to do a few hours of customer work, after that I can look further into how to integrate
Teneo.
>
>> I can get the epackage from the cdopackageregistry?
> Only if you previously registered it in the same CDOSession or if you
> previously registered in in another session and committed it to the
> repository (then a CDOPackageDescriptor is automatically registered with
> the CDOPackageRegistry of the new session).
>
> I know this is a lot of stuff, but I'm sure that you'll find it logical
> if work with it a bit. I think it'd be a good idea to play a bit with
> the CDO UI, i.e. the CDO Sessions viewpart and the CDOEditor. Tell me if
> you need help with it.
>
> Cheers and good night ;-)
> /Eike
>
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Hi Martin,
>>>
>>> I've just committed a first version of a plugin to the CVS:
>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf.cdo/plugins/org.eclipse.emf.cdo.server.hibernat e/?root=Modeling_Project
>>>
>>>
>>> It contains my CDORevisionTuplizer and a skeleton implementation of
>>> CDOs storage framework.
>>> I think this is a good point to start from. The obvious places with
>>> missing code (19x) are marked // TODO Implement me
>>>
>>> The 2 main classes to fill with functionality are:
>>> - HibernateStoreReader
>>> - HibernateStoreWriter
>>>
>>> We can ignore HibernateStoreChunkReader at the beginning.
>>> I'm sure I can help with the missing functionality, but I have no
>>> clue how to connect the pieces.
>>> May be you get an idea when looking at the project...
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>>>
>>>
>>> Eike Stepper schrieb:
>>>> I'd like to start a new thread here which can be used to discuss the
>>>> given topic.
>>>>
>>>> I'll start to write some sub threads, mainly with questions about
>>>> Hibernate details...
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation (CDOID format) [message #614365 is a reply to message #111170] |
Thu, 31 January 2008 09:17 |
|
This is a multi-part message in MIME format.
--------------030608020900070407090304
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Eike Stepper schrieb:
> Martin Taal schrieb:
>> - I see that each object has a CDOID, which has an internal value of
>> long (correct?), this means that composite or String primary keys are
>> not supported?
> Not at the moment, but I already had discussions with Simon about
> possibilities to transfer the responsibility for CDOID creation from
> the repository into the store. In fact this has already happened, but
> the store is currently not allowed to break the contract of the
> CDOID.getValue() API.
I thought again about how to make the format of the CDOID more flexible.
The main problem I see is a deployment issue. In a client-server setup
deployment usually looks like:
CDO Client:
*org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol --> org.eclipse.net4j
--> org-eclipse.emf.ecore
*
CDO Server:
*org.eclipse.emf.cdo.server --> org.eclipse.emf.cdo.protocol -->
org.eclipse.net4j
*org.eclipse.emf.cdo.server.hibernate --> *org.eclipse.emf.cdo.server
--> org.hibernate
*
org.eclipse.emf.cdo.server.db --> *org.eclipse.emf.cdo.server
--> org.eclipse.net4j.db
** *-->
org.eclipse.net4j.db.derby --> *org.eclipse.net4j.db*
* *-->
org.eclipse.net4j.db.mysql --> *org.eclipse.net4j.db*
* *-->
org.eclipse.net4j.db.hsqldb --> *org.eclipse.net4j.db*
org.eclipse.emf.cdo.server.oodb --> *org.eclipse.emf.cdo.server
--> com.objectivity
*/*bold = mandatory plugins*
non-bold = optional plugins with extensions
/
The org.eclipse.emf.cdo.protocol plugin is the lowest dependency level
in the CDO plugin stack. It has no dependency on Ecore!!! Here the
following basic concepts are defined:
1) [internal part] The name of the *CDO Protocol* and the IDs of the
particular *Net4j Signals* being exchanged between client side and
server side of the protocol. With Net4j signals you can implement an
asymmetrical protocol (like the CDO protocol) by having different
implementations on client side (extends Request or
RequestWithConfirmation) and on server side (extends Indication or
IndicationWithResponse). The implementations of the signals get a
DataOutputStream and/or a DataInputStream passed by the Net4j signalling
framework. The protocol itself is automatically associated with a Net4j
IChannel, which represents a logical connection between client and
server, multiplexed through an IConnector as the physical connection.
The signals are also multiplexed through one IChannel so they can be
transmitted and received at any point in time. Internally Net4j
transport works with DirectByteBuffers and is completely asynchron, this
makes two-level multiplexing fast and reliable. By using the signalling
framework a protocol implementor can nevertheless code the actual
communications use cases (each being implemented as a pair of Signal
classes) against a streaming API and doesn't have tobother with
threading strategies.
|*public interface *CDOProtocolConstants
{
*public static final *String PROTOCOL_NAME = "cdo";
*public static final **short *SIGNAL_OPEN_SESSION = 1;
*public static final **short *SIGNAL_VIEWS_CHANGED = 2;
*public static final **short *SIGNAL_RESOURCE_ID = 3;
*public static final **short *SIGNAL_RESOURCE_PATH = 4;
*public static final **short *SIGNAL_LOAD_PACKAGE = 5;
*public static final **short *SIGNAL_LOAD_REVISION = 6;
*public static final **short *SIGNAL_LOAD_REVISION_BY_TIME = 7;
*public static final **short *SIGNAL_LOAD_REVISION_BY_VERSION = 8;
*public static final **short *SIGNAL_LOAD_CHUNK = 9;
*public static final **short *SIGNAL_VERIFY_REVISION = 10;
*public static final **short *SIGNAL_QUERY_OBJECT_TYPES = 11;
*public static final **short *SIGNAL_COMMIT_TRANSACTION = 12;
*public static final **short *SIGNAL_INVALIDATION = 13;
*public static final **int *ERROR_REPOSITORY_NOT_FOUND = -1;
*public static final **int *ERROR_NO_SESSION = -2;
*public static final **byte *VIEW_TRANSACTION = 1;
*public static final **byte *VIEW_AUDIT = 2;
*public static final **byte *VIEW_READONLY = 3;
*public static final **byte *VIEW_CLOSED = 4;
}|
2) *CDOID *is the interface for persistent object identifiers.
Internally it's represented by a long integer. Important methods are
isTemporary() and isMeta(). Temporary CDOIDs (meta or not) are created
at client side for new objects in a transaction. Meta CDOIDs (temporary
or not) identify the EModelElements contained in the used EPackages. The
four possible combinations of temporary and meta are coded into long
integer value, temporary IDs are negative, non-temporary IDs are
positive, NULL is zero, meta IDs are odd, non-meta IDs are even. This
way all operations, including network transfer, of CDOIDs are possible
and very efficient. There is also the sub interface *CDOIDTyped *which
is only needed for sessions with legacy support. Legacy models are those
models that haven't been generated for CDO and as a consequence must
cope with eager instantiation of EMF proxies. To be able to instantiate
an EMF proxy for an object identified by a CDOID the CDO client
framework must know about the EClass of that object (CDO native models
don't need that, the pure CDOID value is sufficient because no class of
the model is eagerly created). A CDOIDTyped contains the needed type
information in addition to the ID value. Both types have streaming API
so that they can easily being transferred through protocol signals.
|*public interface *CDOID *extends *Comparable<CDOID>
{
*public static final *CDOID NULL = *new *CDOIDNull();
*public **long *getValue();
*public **boolean *isNull();
*public **boolean *isTemporary();
*public **boolean *isMeta();
*public *CDOID getNext();
}|
|*public interface *CDOIDTyped *extends *CDOID
{
*public *CDOClassRef getType();
}|
3) *CDOPackageManager*, *CDOPackage*, *CDOClass* and *CDOFeature *model
and manage a meta model that corresponds to an EPackage on client side.
CDOPackages are identified by packageURI, CDOClasses by classifierID and
CDOFeatures by featureID. These identifiers are the same as their Ecore
pendants and ensure convertability to Ecore EModelElements and vice
versa. All CDOModelElements have streaming API so that they can easily
being transferred through protocol signals. There are the two system
packages CDOCorePackage and CDOResourcePackage which contain the classes
CDOObjectClass and CDOResourceClass.
|*public interface *CDOPackageManager *extends *IContainer<CDOPackage>
{
*public **int *getPackageCount();
*public *CDOPackage[] getPackages();
*public *CDOPackage lookupPackage(String packageURI);
*public *CDOCorePackage getCDOCorePackage();
*public *CDOResourcePackage getCDOResourcePackage();
}|
|*public interface *CDOPackage *extends *CDOModelElement, Comparable<CDOPackage>
{
*public *CDOPackageManager getPackageManager();
*public *String getPackageURI();
*public **int *getClassCount();
*public *CDOClass[] getClasses();
*public *CDOClass[] getConcreteClasses();
*public *CDOClass lookupClass(*int *classifierID);
*public *String getEcore();
*public **boolean *isSystem();
*public **boolean *isDynamic();
*public **boolean *isProxy();
*public **boolean *isPersistent();
*public *CDOIDRange getMetaIDRange();
}|
|*public interface *CDOClass *extends *CDOModelElement, Comparable<CDOClass>
{
*public **int *getClassifierID();
*public **boolean *isAbstract();
*public **boolean *isResource();
*public **boolean *isRoot();
*public **int *getSuperTypeCount();
*public *CDOClass getSuperType(*int *index);
*public *CDOClass[] getSuperTypes();
*public *CDOClass[] getAllSuperTypes();
*public **int *getFeatureCount();
*public *CDOFeature lookupFeature(*int *featureID);
*public *CDOFeature lookupFeature(String name);
*public *CDOFeature[] getFeatures();
*public *CDOFeature[] getAllFeatures();
*public *CDOClassRef createClassRef();
*public *CDOPackage getContainingPackage();
}|
|*public interface *CDOFeature *extends *CDOModelElement
{
*public **int *getFeatureID();
*public **int *getFeatureIndex();
*public *CDOType getType();
*public **boolean *isMany();
*public **boolean *isReference();
*public **boolean *isContainment();
*public *CDOClass getReferenceType();
*public *CDOClass getContainingClass();
*public *CDOPackage getContainingPackage();
}|
4) *CDORevision *and *CDORevisionData *represent an immutable state of
an object during a defined timespan. This timespan is demarkated by
"created", which is the timestamp of the commit-transaction operation
that created the revision, and "revised", which is the timestamp - 1 of
the commit-transaction operation that created the next revision. The
"version" is incremented with each new revision. Each CDORevision also
carries the CDOID of its object and a java reference to the CDOClass of
its object. While the internal information is represented by CDORevision
the actual data of the the object is represented by CDORevisionData
which looks a bit similar to the EStore interface with the object handle
missing from the signatures! A CDORevisionResolver manages/caches
CDORevisions so that the important getRevisionXYZ() methods are
efficient. There are different subclasses on client and on server side,
depending onhow to reload missing revisions into the cache. The client
will request them via Net4j signals from the server and the server will
read them via IStoreReader from its store. There are also
CDORevisionDeltas that can result from client side transactions or the
CDORevision.compare() method. I'll postpone this disccusion ;-)
|*public interface *CDORevisionResolver
{
*public *CDOClass getObjectType(CDOID id);
*public **boolean *containsRevision(CDOID id);
*public **boolean *containsRevisionByTime(CDOID id, *long *timeStamp);
*public *CDORevision getRevision(CDOID id, *int *referenceChunk);
*public *CDORevision getRevisionByTime(CDOID id, *int *referenceChunk, *long *timeStamp);
*public *CDORevision getRevisionByVersion(CDOID id, *int *referenceChunk, *int *version);
*public *List<CDORevision> getRevisions(Collection<CDOID> ids, *int *referenceChunk);
*public *List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, *int *referenceChunk, *long *timeStamp);
*public *CDOID resolveReferenceProxy(CDOReferenceProxy referenceProxy);
*public *List<Integer> analyzeReferenceRanges(List<Object> list);
}|
|*public interface *CDORevision
{
*public static final **long *UNSPECIFIED_DATE = 0;
*public static final **int *UNCHUNKED = -1;
*public *CDORevisionResolver getRevisionResolver();
*public *CDOClass getCDOClass();
*public *CDOID getID();
*public **int *getVersion();
*public **long *getCreated();
*public **long *getRevised();
*public **boolean *isCurrent();
*public **boolean *isValid(*long *timeStamp);
*public **boolean *isTransactional();
*public **boolean *isResource();
*public *CDORevisionData getData();
*public *CDORevisionDelta compare(CDORevision origin);
*public **void *merge(CDORevisionDelta delta);
*public **void *write(ExtendedDataOutput out, CDOIDProvider idProvider, *int *referenceChunk) *throws *IOException;
}|
|*public interface *CDORevisionData
{
*public *CDORevision getRevision();
*public *CDOID getResourceID();
*public *CDOID getContainerID();
*public **int *getContainingFeatureID();
*public *Object get(CDOFeature feature, *int *index);
*public **int *size(CDOFeature feature);
*public **boolean *isEmpty(CDOFeature feature);
*public **boolean *contains(CDOFeature feature, Object value);
*public **int *indexOf(CDOFeature feature, Object value);
*public **int *lastIndexOf(CDOFeature feature, Object value);
*public **boolean *isSet(CDOFeature feature);
*public *<T> T[] toArray(CDOFeature feature, T[] array);
*public *Object[] toArray(CDOFeature feature);
*public **int *hashCode(CDOFeature feature);
}|
Ok, this was lots of information ;-)
Now back to the problem with the store-defined CDOID format.
Currently CDOIDImpl is part of the protocol plugin and thus deployed to
both client and server. If we give the store (only deployed to the
server) the capability to instantiate other implementations of CDOID we
need to deploy that code also to the client. The client should per
definition not be aware of implementation details of the repository! We
could try to make the internal format of a CDOID more flexible (a Map or
an array or whatever) but this flexible implementation should be part of
the protocol plugin.
Cheers
/Eike
--------------030608020900070407090304
Content-Type: multipart/related;
boundary="------------070300060607030406090005"
--------------070300060607030406090005
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Eike Stepper schrieb:
<blockquote cite="mid:fnr1bf$uqk$1@build.eclipse.org" type="cite">Martin
Taal schrieb:
<br>
<blockquote type="cite">- I see that each object has a CDOID, which
has an internal value of long (correct?), this means that composite or
String primary keys are not supported?
<br>
</blockquote>
Not at the moment, but I already had discussions with Simon about
possibilities to transfer the responsibility for CDOID creation from
the repository into the store. In fact this has already happened, but
the store is currently not allowed to break the contract of the
CDOID.getValue() API.
<br>
</blockquote>
I thought again about how to make the format of the CDOID more
flexible. The main problem I see is a deployment issue. In a
client-server setup deployment usually looks like:<br>
<br>
CDO Client:<br>
<b>org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol -->
org.eclipse.net4j<br>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation (CDOID format) [message #614373 is a reply to message #111235] |
Thu, 31 January 2008 10:17 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Indeed a fair amount of info :-).
Btw, when an object is read from the server to the client, then how do you keep track of the cdoid
on the client? I mean how do you know that the object I persist back to the server had a certain
cdoid? If the cdoid is based on a field in the model, how do you tag this field as being the id?
(many questionmarks but I think it is all one question :-).
Hibernate only requires the id-object to be serializable. For hibernate the id is known to the
client/user of the model, I mean it is the code field in a product or the order number in an order.
In case of a composite id, the id is modelled using a class (containing the id-fields), also this
class is known to the user.
Would the requirement that the id-object is serializable help to get from the client to the server
(the client-server layer does not need to know the actual implementation)?
I understand that you code extra info in the id (making it negative or odd/even), would it be
possible to code this in a separate field?
Another possibility is to store a server side map of cdoid to hibernate id mappings. But I am not
sure how to accomplish that because this map will grow indefinitely and is difficult to prune (you
don't know which objects are still used at the client).
gr. Martin
Eike Stepper wrote:
> Eike Stepper schrieb:
>> Martin Taal schrieb:
>>> - I see that each object has a CDOID, which has an internal value of
>>> long (correct?), this means that composite or String primary keys are
>>> not supported?
>> Not at the moment, but I already had discussions with Simon about
>> possibilities to transfer the responsibility for CDOID creation from
>> the repository into the store. In fact this has already happened, but
>> the store is currently not allowed to break the contract of the
>> CDOID.getValue() API.
> I thought again about how to make the format of the CDOID more flexible.
> The main problem I see is a deployment issue. In a client-server setup
> deployment usually looks like:
>
> CDO Client:
> *org.eclipse.emf.cdo --> org.eclipse.emf.cdo.protocol --> org.eclipse.net4j
> --> org-eclipse.emf.ecore
> *
> CDO Server:
> *org.eclipse.emf.cdo.server --> org.eclipse.emf.cdo.protocol -->
> org.eclipse.net4j
>
> *org.eclipse.emf.cdo.server.hibernate --> *org.eclipse.emf.cdo.server
> --> org.hibernate
> *
> org.eclipse.emf.cdo.server.db --> *org.eclipse.emf.cdo.server
> --> org.eclipse.net4j.db
> ** *-->
> org.eclipse.net4j.db.derby --> *org.eclipse.net4j.db*
> * *-->
> org.eclipse.net4j.db.mysql --> *org.eclipse.net4j.db*
> * *-->
> org.eclipse.net4j.db.hsqldb --> *org.eclipse.net4j.db*
>
> org.eclipse.emf.cdo.server.oodb --> *org.eclipse.emf.cdo.server
> --> com.objectivity
>
> */*bold = mandatory plugins*
> non-bold = optional plugins with extensions
> /
> The org.eclipse.emf.cdo.protocol plugin is the lowest dependency level
> in the CDO plugin stack. It has no dependency on Ecore!!! Here the
> following basic concepts are defined:
>
>
>
> 1) [internal part] The name of the *CDO Protocol* and the IDs of the
> particular *Net4j Signals* being exchanged between client side and
> server side of the protocol. With Net4j signals you can implement an
> asymmetrical protocol (like the CDO protocol) by having different
> implementations on client side (extends Request or
> RequestWithConfirmation) and on server side (extends Indication or
> IndicationWithResponse). The implementations of the signals get a
> DataOutputStream and/or a DataInputStream passed by the Net4j signalling
> framework. The protocol itself is automatically associated with a Net4j
> IChannel, which represents a logical connection between client and
> server, multiplexed through an IConnector as the physical connection.
> The signals are also multiplexed through one IChannel so they can be
> transmitted and received at any point in time. Internally Net4j
> transport works with DirectByteBuffers and is completely asynchron, this
> makes two-level multiplexing fast and reliable. By using the signalling
> framework a protocol implementor can nevertheless code the actual
> communications use cases (each being implemented as a pair of Signal
> classes) against a streaming API and doesn't have tobother with
> threading strategies.
>
> |*public interface *CDOProtocolConstants
> {
> *public static final *String PROTOCOL_NAME = "cdo";
>
> *public static final **short *SIGNAL_OPEN_SESSION = 1;
>
> *public static final **short *SIGNAL_VIEWS_CHANGED = 2;
>
> *public static final **short *SIGNAL_RESOURCE_ID = 3;
>
> *public static final **short *SIGNAL_RESOURCE_PATH = 4;
>
> *public static final **short *SIGNAL_LOAD_PACKAGE = 5;
>
> *public static final **short *SIGNAL_LOAD_REVISION = 6;
>
> *public static final **short *SIGNAL_LOAD_REVISION_BY_TIME = 7;
>
> *public static final **short *SIGNAL_LOAD_REVISION_BY_VERSION = 8;
>
> *public static final **short *SIGNAL_LOAD_CHUNK = 9;
>
> *public static final **short *SIGNAL_VERIFY_REVISION = 10;
>
> *public static final **short *SIGNAL_QUERY_OBJECT_TYPES = 11;
>
> *public static final **short *SIGNAL_COMMIT_TRANSACTION = 12;
>
> *public static final **short *SIGNAL_INVALIDATION = 13;
>
> *public static final **int *ERROR_REPOSITORY_NOT_FOUND = -1;
>
> *public static final **int *ERROR_NO_SESSION = -2;
>
> *public static final **byte *VIEW_TRANSACTION = 1;
>
> *public static final **byte *VIEW_AUDIT = 2;
>
> *public static final **byte *VIEW_READONLY = 3;
>
> *public static final **byte *VIEW_CLOSED = 4;
> }|
>
>
> 2) *CDOID *is the interface for persistent object identifiers.
> Internally it's represented by a long integer. Important methods are
> isTemporary() and isMeta(). Temporary CDOIDs (meta or not) are created
> at client side for new objects in a transaction. Meta CDOIDs (temporary
> or not) identify the EModelElements contained in the used EPackages. The
> four possible combinations of temporary and meta are coded into long
> integer value, temporary IDs are negative, non-temporary IDs are
> positive, NULL is zero, meta IDs are odd, non-meta IDs are even. This
> way all operations, including network transfer, of CDOIDs are possible
> and very efficient. There is also the sub interface *CDOIDTyped *which
> is only needed for sessions with legacy support. Legacy models are those
> models that haven't been generated for CDO and as a consequence must
> cope with eager instantiation of EMF proxies. To be able to instantiate
> an EMF proxy for an object identified by a CDOID the CDO client
> framework must know about the EClass of that object (CDO native models
> don't need that, the pure CDOID value is sufficient because no class of
> the model is eagerly created). A CDOIDTyped contains the needed type
> information in addition to the ID value. Both types have streaming API
> so that they can easily being transferred through protocol signals.
>
> |*public interface *CDOID *extends *Comparable<CDOID>
> {
> *public static final *CDOID NULL = *new *CDOIDNull();
>
> *public **long *getValue();
>
> *public **boolean *isNull();
>
> *public **boolean *isTemporary();
>
> *public **boolean *isMeta();
>
> *public *CDOID getNext();
> }|
>
>
> |*public interface *CDOIDTyped *extends *CDOID
> {
> *public *CDOClassRef getType();
> }|
>
>
> 3) *CDOPackageManager*, *CDOPackage*, *CDOClass* and *CDOFeature *model
> and manage a meta model that corresponds to an EPackage on client side.
> CDOPackages are identified by packageURI, CDOClasses by classifierID and
> CDOFeatures by featureID. These identifiers are the same as their Ecore
> pendants and ensure convertability to Ecore EModelElements and vice
> versa. All CDOModelElements have streaming API so that they can easily
> being transferred through protocol signals. There are the two system
> packages CDOCorePackage and CDOResourcePackage which contain the classes
> CDOObjectClass and CDOResourceClass.
>
> |*public interface *CDOPackageManager *extends *IContainer<CDOPackage>
> {
> *public **int *getPackageCount();
>
> *public *CDOPackage[] getPackages();
>
> *public *CDOPackage lookupPackage(String packageURI);
>
> *public *CDOCorePackage getCDOCorePackage();
>
> *public *CDOResourcePackage getCDOResourcePackage();
> }|
>
>
> |*public interface *CDOPackage *extends *CDOModelElement, Comparable<CDOPackage>
> {
> *public *CDOPackageManager getPackageManager();
>
> *public *String getPackageURI();
>
> *public **int *getClassCount();
>
> *public *CDOClass[] getClasses();
>
> *public *CDOClass[] getConcreteClasses();
>
> *public *CDOClass lookupClass(*int *classifierID);
>
> *public *String getEcore();
>
> *public **boolean *isSystem();
>
> *public **boolean *isDynamic();
>
> *public **boolean *isProxy();
>
> *public **boolean *isPersistent();
>
> *public *CDOIDRange getMetaIDRange();
> }|
>
>
> |*public interface *CDOClass *extends *CDOModelElement, Comparable<CDOClass>
> {
> *public **int *getClassifierID();
>
> *public **boolean *isAbstract();
>
> *public **boolean *isResource();
>
> *public **boolean *isRoot();
>
> *public **int *getSuperTypeCount();
>
> *public *CDOClass getSuperType(*int *index);
>
> *public *CDOClass[] getSuperTypes();
>
> *public *CDOClass[] getAllSuperTypes();
>
> *public **int *getFeatureCount();
>
> *public *CDOFeature lookupFeature(*int *featureID);
>
> *public *CDOFeature lookupFeature(String name);
>
> *public *CDOFeature[] getFeatures();
>
> *public *CDOFeature[] getAllFeatures();
>
> *public *CDOClassRef createClassRef();
>
> *public *CDOPackage getContainingPackage();
> }|
>
>
> |*public interface *CDOFeature *extends *CDOModelElement
> {
> *public **int *getFeatureID();
>
> *public **int *getFeatureIndex();
>
> *public *CDOType getType();
>
> *public **boolean *isMany();
>
> *public **boolean *isReference();
>
> *public **boolean *isContainment();
>
> *public *CDOClass getReferenceType();
>
> *public *CDOClass getContainingClass();
>
> *public *CDOPackage getContainingPackage();
> }|
>
>
> 4) *CDORevision *and *CDORevisionData *represent an immutable state of
> an object during a defined timespan. This timespan is demarkated by
> "created", which is the timestamp of the commit-transaction operation
> that created the revision, and "revised", which is the timestamp - 1 of
> the commit-transaction operation that created the next revision. The
> "version" is incremented with each new revision. Each CDORevision also
> carries the CDOID of its object and a java reference to the CDOClass of
> its object. While the internal information is represented by CDORevision
> the actual data of the the object is represented by CDORevisionData
> which looks a bit similar to the EStore interface with the object handle
> missing from the signatures! A CDORevisionResolver manages/caches
> CDORevisions so that the important getRevisionXYZ() methods are
> efficient. There are different subclasses on client and on server side,
> depending onhow to reload missing revisions into the cache. The client
> will request them via Net4j signals from the server and the server will
> read them via IStoreReader from its store. There are also
> CDORevisionDeltas that can result from client side transactions or the
> CDORevision.compare() method. I'll postpone this disccusion ;-)
>
> |*public interface *CDORevisionResolver
> {
> *public *CDOClass getObjectType(CDOID id);
>
> *public **boolean *containsRevision(CDOID id);
>
> *public **boolean *containsRevisionByTime(CDOID id, *long *timeStamp);
>
> *public *CDORevision getRevision(CDOID id, *int *referenceChunk);
>
> *public *CDORevision getRevisionByTime(CDOID id, *int *referenceChunk, *long *timeStamp);
>
> *public *CDORevision getRevisionByVersion(CDOID id, *int *referenceChunk, *int *version);
>
> *public *List<CDORevision> getRevisions(Collection<CDOID> ids, *int *referenceChunk);
>
> *public *List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, *int *referenceChunk, *long *timeStamp);
>
> *public *CDOID resolveReferenceProxy(CDOReferenceProxy referenceProxy);
>
> *public *List<Integer> analyzeReferenceRanges(List<Object> list);
> }|
>
>
> |*public interface *CDORevision
> {
> *public static final **long *UNSPECIFIED_DATE = 0;
>
> *public static final **int *UNCHUNKED = -1;
>
> *public *CDORevisionResolver getRevisionResolver();
>
> *public *CDOClass getCDOClass();
>
> *public *CDOID getID();
>
> *public **int *getVersion();
>
> *public **long *getCreated();
>
> *public **long *getRevised();
>
> *public **boolean *isCurrent();
>
> *public **boolean *isValid(*long *timeStamp);
>
> *public **boolean *isTransactional();
>
> *public **boolean *isResource();
>
> *public *CDORevisionData getData();
>
> *public *CDORevisionDelta compare(CDORevision origin);
>
> *public **void *merge(CDORevisionDelta delta);
>
> *public **void *write(ExtendedDataOutput out, CDOIDProvider idProvider, *int *referenceChunk) *throws *IOException;
> }|
>
>
> |*public interface *CDORevisionData
> {
> *public *CDORevision getRevision();
>
> *public *CDOID getResourceID();
>
> *public *CDOID getContainerID();
>
> *public **int *getContainingFeatureID();
>
> *public *Object get(CDOFeature feature, *int *index);
>
> *public **int *size(CDOFeature feature);
>
> *public **boolean *isEmpty(CDOFeature feature);
>
> *public **boolean *contains(CDOFeature feature, Object value);
>
> *public **int *indexOf(CDOFeature feature, Object value);
>
> *public **int *lastIndexOf(CDOFeature feature, Object value);
>
> *public **boolean *isSet(CDOFeature feature);
>
> *public *<T> T[] toArray(CDOFeature feature, T[] array);
>
> *public *Object[] toArray(CDOFeature feature);
>
> *public **int *hashCode(CDOFeature feature);
> }|
>
>
>
>
> Ok, this was lots of information ;-)
> Now back to the problem with the store-defined CDOID format.
>
> Currently CDOIDImpl is part of the protocol plugin and thus deployed to
> both client and server. If we give the store (only deployed to the
> server) the capability to instantiate other implementations of CDOID we
> need to deploy that code also to the client. The client should per
> definition not be aware of implementation details of the repository! We
> could try to make the internal format of a CDOID more flexible (a Map or
> an array or whatever) but this flexible implementation should be part of
> the protocol plugin.
>
> Cheers
> /Eike
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation [message #615344 is a reply to message #111180] |
Thu, 31 January 2008 10:25 |
|
This is a multi-part message in MIME format.
--------------060102040105060602010609
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> See my remarks/questions below.
>
> A new question: when the client commits its transaction the objects
> are sent to the cdo server and de-serialized to
> cdoobjects/cdorevisions. These objects are then persisted. After the
> persist step are the cdoobjects/cdorevisions discarded or are they
> kept in-memory (so the server keeps state between commit transactions)?
CDOObjects are EMF-dependent and only known to the client. Each
CDOObject has an association to a CDORevision which is EMF-independent
an can be transferred over the network to the server. The server
(repository) passes the revisions to the store to persist them and is
also allowed to cache them. IRepository is like a thin facade for
different manager facilities. The IRevisionManager is responsible for
all the revision handling in the server. The default implementation has
a configurable fixed size cache built in.
So, yes and no. The stored revisions can remain in memory but need not.
In general I'd expect written revisions to remain in memory for a
certain period in time. But as the server load grows...
>> The version is never part of reference information.
>> As you'll have noticed a CDOObject is just a thin wrapper for a
>> CDORevision, which is identified by CDOID and version. It's the task
>> of a "view" to associate objects with the correct revision. This
>> depends on the type of view, CDOView and CDOTransaction deliver
>> always the latest revision (determined by revised==null) and CDOAudit
>> delivers a revision where the timeStamp of the view (audit) is
>> between the "created" and "revised" values of the revision.
> MT>> As it interests me how you did this I'll bug you with some more
> questions :-): what I understand is that in audit mode the different
> versions of one object are stored in the same table. In the database
> do the foreign key constraints contain the version also?
In fact the DBStore doesn't add real foreign key constraints to the
tables but manages them implicitely. For simplicity reasons we can
assume there were real constraints. Then these constraints would not
contain the version column! If they did instead, all referers of a
modified object (new revision with ++version) would have to be notified
and theeir table rows updated accordingly, which would clearly not scale
so well ;-)
> Old versions of a deleted object are also present in the db, I assume?
Basically depends on the auditing mode of the repository/store. When
auditing is switched off (which is currently not possible with the
DBStore) there is no need to store old revisions. If auditing is
switched on they are there.
> How do you prevent queries from returning old versions of deleted
> objects (maybe maintain a deleted flag in all versions?)?
Depends on what you mean by "queries" ;-)
The client side API currently doesn't support querying in the sense of
HQL, OCL, SQL, etc.
The only queries implemented by the framework (IStores) are
| *public *CDORevision getRevision(*CDOID id*, *int *referenceChunk);
*public *CDORevision getRevisionByTime(*CDOID id*, *int *referenceChunk, *long timeStamp*);
*public *CDORevision getRevisionByVersion(*CDOID id*, *int *referenceChunk, *int version*);|
If an object is deleted (removed from the CDOView/ResourceSet) the
DBStore writes the timestamp of the commit-operation into the "revised"
column of the latest revision (the only one with a null value in the
revised column previously). This way the object is excluded from all
read-only views and transactional views. Only auditing views could catch
that revision (if the audit timestamp is between the "created" and
"revised" value of the revision) and thus deliver an object for it.
> Do you keep a flag in the db which keeps track of the last version of
> each object, so that it is possible to easily query for the last version?
Latest (undeleted) revision of an object has a null value in the revised
column.
>> All this is not important if we decide to ignore the auditing mode.
>> Then we (hibernate) would use the version of the revision only for
>> optimistic locking.
>>
>>> - when is the writepackage method called? The ecore package is
>>> stored in the database also in your view or can this be ignored (for
>>> now)?
>> I don't think that we can ignore this.
>> The method is called by the repository when it receives a
>> CommitTransactionIndication (a signal over the network after the
>> client committed a transaction) that contains new packages. If we
>> ignore this indication the repository would later startup without
>> knowledgeabout previously used packages.
>
> MT>>
> With Teneo the epackages are explicitly set by the user when the store
> initializes. With CDO I understand now that you can register new
> epackages on the fly or when the user commits for the first time,
> correct?
Exactly. A CDO Model Repository manages/stores the meta models along
with the depending models. No need for the client to anticipate which
packages have to be registered before lazy loading can be attempted.
> Is it possible for the user to specify/pass the epackages when the cdo
> server starts? Is there such an explicit initialization step?
I never tried it but the IRepository facade has a CDOPackageManager
associated which could be used to register packages via CDO API.
Basically my opinion is that this is an admin task (I guess you meant
that with "user") and the easiest way (EPackage-based instead of
CDOPackage-based) is to open a normal CDOSession (could be embedded in
the server) and start a transaction to commit the packages.
> With Teneo annotations can also be specified in a separate xml file
> and there is a property file which allows you to set several options.
> Is there a possibility to pass this information through CDO to Teneo.
> For example using custom cdo properties, does cdo have a property file
> somewhere for simple configuration options which can be read when the
> cdo server starts?
I knew this would become a semantical challenge ;-)
Technically there's the possibility to query the whole serialized XML
string of the EPackage definition, including EAnnotations. If we make
the org.eclipse.emf.cdo.server.hibernate plugin dependent on Ecore we
could easily process this information in IStoreWriter.writePackages().
Do you think this is sufficient?
>>> - The storewriter has a method writeRevision, with hibernate write
>>> operations cascade automatically to refered-to objects, so the
>>> writeRevision method will have side effects. This is no problem?
>> I'm not sure that I understand this. May be I explain the semantics
>> of the writeRevision() method:
>> When a client modifies CDOObjects the associated CDOTransaction
>> becomes dirty. The CDOTransaction remembers all modified objects (in
>> fact it even temporarily stores their associated, transactional
>> revisions). When the transaction is committed all the internal state
>> of the transaction (particularly the transactional revisions of the
>> modified objects) is transferred to the server where it is
>> deserialized. First added packages are written to the store via
>> IStoreWriter.writePackages() then each of the received revisions of
>> the new/modified objects is written to the store via
>> IStoreWriter.writeRevision(). No matter what kind of references do
>> exist between the original objects. A CDORevision doesn't have Java
>> reference handles to other CDORevisions. References between the
>> original objects are completely represented as CDOIDs (see below).
>
> MT>> I think to get this working with hibernate the propertyaccessor
> for a ereference property should not return the cdoid but the
> cdorevision identified by the cdoid. Hibernate will then depending on
> the cascade options also automatically persist the refered-to objects.
I think this cascading thing is also done by the CDO client and it would
be best to disable this feature of Hibernate. Is that possible?
Although I'm absolutely not sure what exactly Hibernate assumes a
"proxy" to be, I thought we could use the CDOID of the target object
(which we simply have in the source revision) as a kind of pseudo proxy
and let it resolve through the IRevisionManager if needed. Thoughts?
>>> - I see that each object has a CDOID, which has an internal value of
>>> long (correct?), this means that composite or String primary keys
>>> are not supported?
>> Not at the moment, but I already had discussions with Simon about
>> possibilities to transfer the responsibility for CDOID creation from
>> the repository into the store. In fact this has already happened, but
>> the store is currently not allowed to break the contract of the
>> CDOID.getValue() API.
>
> MT>> if the getValue would return Object then this would already solve
> it I think. What do you think?
See my other (long) posting ;-)
Cheers
/Eike
--------------060102040105060602010609
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
See my remarks/questions below.
<br>
<br>
A new question: when the client commits its transaction the objects are
sent to the cdo server and de-serialized to cdoobjects/cdorevisions.
These objects are then persisted. After the persist step are the
cdoobjects/cdorevisions discarded or are they kept in-memory (so the
server keeps state between commit transactions)?
<br>
</blockquote>
CDOObjects are EMF-dependent and only known to the client. Each
CDOObject has an association to a CDORevision which is EMF-independent
an can be transferred over the network to the server. The server
(repository) passes the revisions to the store to persist them and is
also allowed to cache them. IRepository is like a thin facade for
different manager facilities. The IRevisionManager is responsible for
all the revision handling in the server. The default implementation has
a configurable fixed size cache built in.<br>
<br>
So, yes and no. The stored revisions can remain in memory but need not.
In general I'd expect written revisions to remain in memory for a
certain period in time. But as the server load grows...<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">
<blockquote type="cite">The version is never part of reference
information.
<br>
As you'll have noticed a CDOObject is just a thin wrapper for a
CDORevision, which is identified by CDOID and version. It's the task of
a "view" to associate objects with the correct revision. This depends
on the type of view, CDOView and CDOTransaction deliver always the
latest revision (determined by revised==null) and CDOAudit delivers a
revision where the timeStamp of the view (audit) is between the
"created" and "revised" values of the revision.
<br>
</blockquote>
MT>> As it interests me how you did this I'll bug you with some
more questions :-): what I understand is that in audit mode the
different versions of one object are stored in the same table. In the
database do the foreign key constraints contain the version also?
<br>
</blockquote>
In fact the DBStore doesn't add real foreign key constraints to the
tables but manages them implicitely. For simplicity reasons we can
assume there were real constraints. Then these constraints would not
contain the version column! If they did instead, all referers of a
modified object (new revision with ++version) would have to be notified
and theeir table rows updated accordingly, which would clearly not
scale so well ;-)<br>
<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">Old
versions of a deleted object are also present in the db, I assume? </blockquote>
Basically depends on the auditing mode of the repository/store. When
auditing is switched off (which is currently not possible with the
DBStore) there is no need to store old revisions. If auditing is
switched on they are there.<br>
<br>
<blockquote cite="mid:fns0me$dcj$1@build.eclipse.org" type="cite">How
do you prevent queries from returning old versions of deleted objects
(maybe maintain a deleted flag in all versions?)?
<br>
</blockquote>
Depends on what you mean by "queries" ;-)<br>
The client side API currently doesn't support querying in the sense of
HQL, OCL, SQL, etc.<br>
The only queries implemented by the framework (IStores) are <br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#ffffff">
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation (CDOID format) [message #615346 is a reply to message #111280] |
Thu, 31 January 2008 10:40 |
|
This is a multi-part message in MIME format.
--------------010507060809090300030603
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Indeed a fair amount of info :-).
> Btw, when an object is read from the server to the client, then how do
> you keep track of the cdoid on the client? I mean how do you know that
> the object I persist back to the server had a certain cdoid? If the
> cdoid is based on a field in the model, how do you tag this field as
> being the id?
> (many questionmarks but I think it is all one question :-).
Hehe, but there's a wrong assumption: The CDOID is not part of the model
because it is a technical information. Nevertheless it is stored in each
CDOObjectImpl:
|*public class *CDOObjectImpl *extends *EStoreEObjectImpl *implements *InternalCDOObject
{
*private static final *ContextTracer TRACER = *new *ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.*class*);
*_private CDOID id;
_*
*private *CDOState state;
*private *CDOResourceImpl resource;
*private *InternalCDORevision revision;
*public *CDOObjectImpl()
{
state = CDOState.TRANSIENT;
eContainer = *null*;
}
// ...|
If the genmodel contains "Root Extends Interface =
org.eclipse.emf.cdo.CDOObject", which is the default, then the user can
query it via the generated public API:
|*public interface *CDOObject *extends *EObject
{
*public *CDOClass cdoClass();
*_public CDOID cdoID();_*
*public *CDOState cdoState();
*public *CDOView cdoView();
*public *CDOResource cdoResource();
*public *CDORevision cdoRevision();
*public **void *cdoReload();
}|
> Hibernate only requires the id-object to be serializable. For
> hibernate the id is known to the client/user of the model, I mean it
> is the code field in a product or the order number in an order. In
> case of a composite id, the id is modelled using a class (containing
> the id-fields), also this class is known to the user.
It's easy to make CDOID serializable. Should we (I) start with that?
> Would the requirement that the id-object is serializable help to get
> from the client to the server (the client-server layer does not need
> to know the actual implementation)?
Wouldn't that require the client to have the actual .class file(s) of
the implementation deployed and accessible?
That's the real problem because a client doesn't know in general about
the store implementation of a repository.
May be we could transfer the needed .class files from the server to the
client with the OpenSessionResponse...
>
> I understand that you code extra info in the id (making it negative or
> odd/even), would it be possible to code this in a separate field?
Absolutely! This is just an optimization that a store would be free to
apply or not - if we move the responsibility for the CDOID format to the
store.
> Another possibility is to store a server side map of cdoid to
> hibernate id mappings. But I am not sure how to accomplish that
> because this map will grow indefinitely and is difficult to prune (you
> don't know which objects are still used at the client).
I already had this mechanism once and removed it again due to user
complaints ;-)
We should avoid this extra mapping.
Cheers
/Eike
--------------010507060809090300030603
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fns77o$7mu$1@build.eclipse.org" type="cite">Indeed
a fair amount of info :-).
<br>
Btw, when an object is read from the server to the client, then how do
you keep track of the cdoid on the client? I mean how do you know that
the object I persist back to the server had a certain cdoid? If the
cdoid is based on a field in the model, how do you tag this field as
being the id?
<br>
(many questionmarks but I think it is all one question :-).
<br>
</blockquote>
Hehe, but there's a wrong assumption: The CDOID is not part of the
model because it is a technical information. Nevertheless it is stored
in each CDOObjectImpl:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation (CDOID format) [message #615348 is a reply to message #111323] |
Thu, 31 January 2008 10:58 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
So we can assume that all model objects inherit from CDOObject and have a cdoid member?
Related to your remark that the client should know the class of the id. Afaics this is no problem as
in case of hibernate the id is often (let's say always :-) an explicit field in the model (even if
it is a composite id). So the client always knows about it anyway. Hibernate has the concept of
synthetic id's (as I remember) but these map to the current cdoid anyway.
As far as I can see the following changes (please correct me here) should make it all very mappable
to hibernate (with explicit primary keys):
- change the type of the value in the cdoid to serializable
- move the extra information coded in the value field in cdoid to a separate field
The cdoid can then be constructed from the hibernate id object and vice versa.
What do you think?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Indeed a fair amount of info :-).
>> Btw, when an object is read from the server to the client, then how do
>> you keep track of the cdoid on the client? I mean how do you know that
>> the object I persist back to the server had a certain cdoid? If the
>> cdoid is based on a field in the model, how do you tag this field as
>> being the id?
>> (many questionmarks but I think it is all one question :-).
> Hehe, but there's a wrong assumption: The CDOID is not part of the model
> because it is a technical information. Nevertheless it is stored in each
> CDOObjectImpl:
>
> |*public class *CDOObjectImpl *extends *EStoreEObjectImpl *implements *InternalCDOObject
> {
> *private static final *ContextTracer TRACER = *new *ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.*class*);
>
> *_private CDOID id;
> _*
> *private *CDOState state;
>
> *private *CDOResourceImpl resource;
>
> *private *InternalCDORevision revision;
>
> *public *CDOObjectImpl()
> {
> state = CDOState.TRANSIENT;
> eContainer = *null*;
> }
>
> // ...|
>
>
> If the genmodel contains "Root Extends Interface =
> org.eclipse.emf.cdo.CDOObject", which is the default, then the user can
> query it via the generated public API:
>
> |*public interface *CDOObject *extends *EObject
> {
> *public *CDOClass cdoClass();
>
> *_public CDOID cdoID();_*
>
> *public *CDOState cdoState();
>
> *public *CDOView cdoView();
>
> *public *CDOResource cdoResource();
>
> *public *CDORevision cdoRevision();
>
> *public **void *cdoReload();
> }|
>
>
>> Hibernate only requires the id-object to be serializable. For
>> hibernate the id is known to the client/user of the model, I mean it
>> is the code field in a product or the order number in an order. In
>> case of a composite id, the id is modelled using a class (containing
>> the id-fields), also this class is known to the user.
> It's easy to make CDOID serializable. Should we (I) start with that?
>
>> Would the requirement that the id-object is serializable help to get
>> from the client to the server (the client-server layer does not need
>> to know the actual implementation)?
> Wouldn't that require the client to have the actual .class file(s) of
> the implementation deployed and accessible?
> That's the real problem because a client doesn't know in general about
> the store implementation of a repository.
> May be we could transfer the needed .class files from the server to the
> client with the OpenSessionResponse...
>
>>
>> I understand that you code extra info in the id (making it negative or
>> odd/even), would it be possible to code this in a separate field?
> Absolutely! This is just an optimization that a store would be free to
> apply or not - if we move the responsibility for the CDOID format to the
> store.
>
>> Another possibility is to store a server side map of cdoid to
>> hibernate id mappings. But I am not sure how to accomplish that
>> because this map will grow indefinitely and is difficult to prune (you
>> don't know which objects are still used at the client).
> I already had this mechanism once and removed it again due to user
> complaints ;-)
> We should avoid this extra mapping.
>
> Cheers
> /Eike
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Skeleton Implementation (CDOID format) [message #615349 is a reply to message #111350] |
Thu, 31 January 2008 11:46 |
|
Martin Taal schrieb:
> Hi Eike,
> So we can assume that all model objects inherit from CDOObject and
> have a cdoid member?
Yes. If not (because the genmodel didn't specify "Root Extends Interface
= org.eclipse.emf.cdo.CDOObject") we can "downcast" the EObject to
InternalCDOObject. The recommended way to do the downcast is
InternalCDOObject cdoObject = FSMUtil.adapt(Object pojo, CDOView view);
This also considers the legacy objects (EObjects that don't extend
CDOObjectImpl). We can do this everywhere in the client. But not in the
server!
> Related to your remark that the client should know the class of the
> id. Afaics this is no problem as in case of hibernate the id is often
> (let's say always :-) an explicit field in the model (even if it is a
> composite id). So the client always knows about it anyway.
Hmm, I have the feeling that here is a misunderstanding. The fields in
the model (EAttributes/EReferences) are *only* known to the client and
not to the server! The server operates on java.lang.Object values which
in reality are of a subset of String, primitive wrappers and List (i.e.
IMoveableList).
I think we should first clarify which of the following two, completely
different, integration strategies we want to follow in the server:
1) Let Hibernate operate directly on the CDORevisions
2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
string value and use Teneo/Hibernate to map EObjects
While 2) would probably be easier to implement it seems a bit of a brute
force solution to me ;-) This would not only duplicate the footprint of
meta model and model in the server but, even worse, introduce cache
eviction issues (if ot unsolveable problems). I clearly tend to 1) until
we get the impression that we're not able to do it with Hibernate.
> Hibernate has the concept of synthetic id's (as I remember) but these
> map to the current cdoid anyway.
>
> As far as I can see the following changes (please correct me here)
> should make it all very mappable to hibernate (with explicit primary
> keys):
> - change the type of the value in the cdoid to serializable
That's easy.
> - move the extra information coded in the value field in cdoid to a
> separate field
That'd be easy although I'm a bit reluctant to force all stores touse
this new implementation. I'm still thinking about copletely
store-defined CDOID implementations...
>
> The cdoid can then be constructed from the hibernate id object and
> vice versa.
You mean there's an explicit mapping somewhere between IRepository and
IStore? Both of these entities won't like to do that because of the
scalability issues ;-(
Cheers
/Eike
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | |
Re: Skeleton Implementation (CDOID format) [message #615352 is a reply to message #111362] |
Thu, 31 January 2008 12:09 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my comments below.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> So we can assume that all model objects inherit from CDOObject and
>> have a cdoid member?
> Yes. If not (because the genmodel didn't specify "Root Extends Interface
> = org.eclipse.emf.cdo.CDOObject") we can "downcast" the EObject to
> InternalCDOObject. The recommended way to do the downcast is
> InternalCDOObject cdoObject = FSMUtil.adapt(Object pojo, CDOView view);
>
> This also considers the legacy objects (EObjects that don't extend
> CDOObjectImpl). We can do this everywhere in the client. But not in the
> server!
>
>> Related to your remark that the client should know the class of the
>> id. Afaics this is no problem as in case of hibernate the id is often
>> (let's say always :-) an explicit field in the model (even if it is a
>> composite id). So the client always knows about it anyway.
> Hmm, I have the feeling that here is a misunderstanding. The fields in
> the model (EAttributes/EReferences) are *only* known to the client and
> not to the server! The server operates on java.lang.Object values which
> in reality are of a subset of String, primitive wrappers and List (i.e.
> IMoveableList).
>
> I think we should first clarify which of the following two, completely
> different, integration strategies we want to follow in the server:
> 1) Let Hibernate operate directly on the CDORevisions
> 2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
> string value and use Teneo/Hibernate to map EObjects
MT>> I am targeting 1 also, teneo can generate a native hibernate mapping (without teneo
dependencies) in the beginning (initialization time, or at compile time) but after that (during the
real runtime) hibernate can/should work directly on the cdorevision.
Teneo should not be present after the mapping has been done. CDO should have its own hibernate
runtime layer which does not depend on teneo. For the mapping cdo can use a mapping component which
generates a hibernate mapping. The mapping component is then a pluggable component which implements
a generic interface (something like: String getMapping(EPackage[] epackages)), teneo can then supply
an implementation of such a mapping component.
Another mapping component can read a mapping from a file somewhere (as an example).
>
> While 2) would probably be easier to implement it seems a bit of a brute
> force solution to me ;-) This would not only duplicate the footprint of
> meta model and model in the server but, even worse, introduce cache
> eviction issues (if ot unsolveable problems). I clearly tend to 1) until
> we get the impression that we're not able to do it with Hibernate.
MT>> Same for me,
>
>> Hibernate has the concept of synthetic id's (as I remember) but these
>> map to the current cdoid anyway.
>>
>> As far as I can see the following changes (please correct me here)
>> should make it all very mappable to hibernate (with explicit primary
>> keys):
>> - change the type of the value in the cdoid to serializable
> That's easy.
>> - move the extra information coded in the value field in cdoid to a
>> separate field
> That'd be easy although I'm a bit reluctant to force all stores touse
> this new implementation. I'm still thinking about copletely
> store-defined CDOID implementations...
MT>> yes, the cdoid can have different implementations which decide themselves how this info is encoded.
>>
>> The cdoid can then be constructed from the hibernate id object and
>> vice versa.
> You mean there's an explicit mapping somewhere between IRepository and
> IStore? Both of these entities won't like to do that because of the
> scalability issues ;-(
MT>> What's an IRepository (newbie question :-)?
When an object is read from the db through hibernate it is possible to intercept that and ask
hibernate for the id and construct a cdoid object which is set in the object. So the cdoid is not
stored explicitly in the db but is constructed when the object is read from the db, this should be
very similar as it is now already (the value in the cdoid is the value of the identity column in the
db I assume).
The same for when an object is persisted for the first time, after the persist action hibernate can
be queried for the id and a cdoid object can be created.
So the mapping from data in the object to the id is present in hibernate and using the hibernate
mapping information the cdo-hibernate store can create cdoid objects. At least that's how I think it
can work...
Or maybe I do not understand what you mean...?
>
> Cheers
> /Eike
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
| |
Re: Skeleton Implementation (CDOID format) [message #615354 is a reply to message #111395] |
Thu, 31 January 2008 13:04 |
|
This is a multi-part message in MIME format.
--------------040904050104090604090501
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
>> I think we should first clarify which of the following two,
>> completely different, integration strategies we want to follow in the
>> server:
>> 1) Let Hibernate operate directly on the CDORevisions
>> 2) Reconstruct the original Ecore model from the
>> CDOPackage.getEcore() string value and use Teneo/Hibernate to map
>> EObjects
> MT>> I am targeting 1 also, teneo can generate a native hibernate
> mapping (without teneo dependencies) in the beginning (initialization
> time, or at compile time) but after that (during the real runtime)
> hibernate can/should work directly on the cdorevision.
> Teneo should not be present after the mapping has been done. CDO
> should have its own hibernate runtime layer which does not depend on
> teneo. For the mapping cdo can use a mapping component which generates
> a hibernate mapping. The mapping component is then a pluggable
> component which implements a generic interface (something like: String
> getMapping(EPackage[] epackages)), teneo can then supply an
> implementation of such a mapping component.
> Another mapping component can read a mapping from a file somewhere (as
> an example).
That sounds very good!
>>> - move the extra information coded in the value field in cdoid to a
>>> separate field
>> That'd be easy although I'm a bit reluctant to force all stores touse
>> this new implementation. I'm still thinking about copletely
>> store-defined CDOID implementations...
> MT>> yes, the cdoid can have different implementations which decide
> themselves how this info is encoded.
I'm just applying a refactoring to make the CDOIDs internally
session-aware...
>>> The cdoid can then be constructed from the hibernate id object and
>>> vice versa.
>> You mean there's an explicit mapping somewhere between IRepository
>> and IStore? Both of these entities won't like to do that because of
>> the scalability issues ;-(
> MT>> What's an IRepository (newbie question :-)?
A repository on the server side. There can be multiple repositories
configured for a single server node. IRepository represents such a
repository in the form of a thin facade which delegates most
responsibilities to various managers:
|*public interface *IRepository *extends *IContainer<IRepositoryElement>
{
*public *String getName();
*public *IStore getStore();
*public *Map<String, String> getProperties();
*public *String getUUID();
*public **boolean *isSupportingAudits();
*public **boolean *isVerifyingRevisions();
_*public IPackageManager getPackageManager();
public ISessionManager getSessionManager();
public IResourceManager getResourceManager();
public IRevisionManager getRevisionManager();*_
}|
After a client opened a CDOSession with an IRepository the following is
valid:
session.getRepositoryName() equals repository.getName()
And the managers of the IRepository logically correspond to the managers
of the CDOSession (if applicable):
|*public interface *CDOSession *extends *IContainer<CDOView>
{
*public *String getRepositoryName();
*public *String getRepositoryUUID();
_* public CDOSessionPackageManager getPackageManager();
public CDORevisionManager getRevisionManager();*_ |
> When an object is read from the db through hibernate it is possible to
> intercept that and ask hibernate for the id and construct a cdoid
> object which is set in the object. So the cdoid is not stored
> explicitly in the db but is constructed when the object is read from
> the db, this should be very similar as it is now already (the value in
> the cdoid is the value of the identity column in the db I assume).
Yes, but how could Hibernate (or our interceptor) construct a flat CDOID
from PK columns without extra persistent information?
> The same for when an object is persisted for the first time, after the
> persist action hibernate can be queried for the id and a cdoid object
> can be created.
> So the mapping from data in the object to the id is present in
> hibernate and using the hibernate mapping information the
> cdo-hibernate store can create cdoid objects. At least that's how I
> think it can work...
>
> Or maybe I do not understand what you mean...?
I guess, although I'm not sure ;-)
Basically I'd like to avoid mapping from PKs to CDOIDs, regardless of
where this mapping info comes from (additional column in mapped tables,
additional table in the db, external hashing, etc.)
The solution I have in mind is the following:
There are two places in CDO where (new) CDOIDs are logically created.
These are the client-side CDOTransaction where new temporary CDOIDs are
created for new objects/resources and the server-side transaction
(currently in CommitTransactionIndication) where the temporary CDOIDs
are mapped to persistent ones. This CDOID mapping result is transferred
back to the client so that all the source and target IDs of the client
objects can be adjusted accordingly. All other places where CDOIDs are
physically created the value of an existing ID is kept unchanged. This
happens for example during deserialization or copy().
When the client must create new temporary CDOIDs I could use a special
CDOIDTemporaryImpl. A 32-bit integer would even be sufficient to
identify it. Both client and server would have to have access to this
class. Easy, since it can be final and would live in the protocol plugin.
The real challenge is to make the persistent CDOIDs that are currently
created by the IRepository completely independent of their
implementation, so that they can:
a) be created by the IStore in any internal format that might be
appropriate, including arbitrary structures for model-dependent values
or composite PKs.
b) copied, compared, hashed within one VM (easy)
c) transferred over the net to the client, stored there and sent back.
This step includes the problem that the implementation class file will
be contained in the plugin that implements the store (our new hibernate
plugin) and this plugin is not present on the client! Even factoring
this class out of the store plugin (if possible at all) is not a good
idea because the new id plugin would have to be deployed to the client
than and this would break the basic requirement that the client doesn't
need to know how the repository is implemented/configured.
Possible solution to c)
Before the first persistent CDOID is transferred from the server to the
client the needed class files are transferred to the client so that they
can be used when deserializing (and all the other operations later on).
Since the store implementation of a repository must not change after
after the initial startup (where store-specific initialization occurs) I
can even cache the transferred class files on the client keyed by
repositoryUUID.
For our HibernateStore this would mean that we could implement CDOID
with whatever Hibernate likes as a PK mapping.
Does that sound reasonable?
Cheers
/Eike
--------------040904050104090604090501
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">I think we should first clarify which of the
following two, completely different, integration strategies we want to
follow in the server:
<br>
1) Let Hibernate operate directly on the CDORevisions
<br>
2) Reconstruct the original Ecore model from the CDOPackage.getEcore()
string value and use Teneo/Hibernate to map EObjects
<br>
</blockquote>
MT>> I am targeting 1 also, teneo can generate a native hibernate
mapping (without teneo dependencies) in the beginning (initialization
time, or at compile time) but after that (during the real runtime)
hibernate can/should work directly on the cdorevision.
<br>
Teneo should not be present after the mapping has been done. CDO should
have its own hibernate runtime layer which does not depend on teneo.
For the mapping cdo can use a mapping component which generates a
hibernate mapping. The mapping component is then a pluggable component
which implements a generic interface (something like: String
getMapping(EPackage[] epackages)), teneo can then supply an
implementation of such a mapping component.
<br>
Another mapping component can read a mapping from a file somewhere (as
an example).
<br>
</blockquote>
That sounds very good!<br>
<br>
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">
<blockquote type="cite">- move the extra information coded in the
value field in cdoid to a separate field
<br>
</blockquote>
That'd be easy although I'm a bit reluctant to force all stores touse
this new implementation. I'm still thinking about copletely
store-defined CDOID implementations...
<br>
</blockquote>
MT>> yes, the cdoid can have different implementations which
decide themselves how this info is encoded.
<br>
</blockquote>
I'm just applying a refactoring to make the CDOIDs internally
session-aware...<br>
<br>
<blockquote cite="mid:fnsdp9$ltn$1@build.eclipse.org" type="cite">
<blockquote type="cite">
<blockquote type="cite">The cdoid can then be constructed from the
hibernate id object and vice versa.
<br>
</blockquote>
You mean there's an explicit mapping somewhere between IRepository and
IStore? Both of these entities won't like to do that because of the
scalability issues ;-(
<br>
</blockquote>
MT>> What's an IRepository (newbie question :-)?
<br>
</blockquote>
A repository on the server side. There can be multiple repositories
configured for a single server node. IRepository represents such a
repository in the form of a thin facade which delegates most
responsibilities to various managers:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation (CDOID format) [message #615355 is a reply to message #111409] |
Thu, 31 January 2008 13:13 |
|
Martin Taal schrieb:
> I also learned something here :-).
>
> What I mean is that the classes of the values which together make up
> the id are (by definition) also known client side, otherwise the
> client can not work with the objects anyway (as the id is constructed
> from values in the object itself).
>
> For example, a type customerorder has an order number field and this
> field is tagged as the id. The client knows how to handle the class of
> the order number field (otherwise the client can not handle the
> customer order at all), the class of the order number will be present
> in the generated code on the client. So if the client can handle the
> order number field then the client can also handle the id object
> (which by definition is the same as the value in the order number field).
>
> Or do you mean something else?
Heaven, this is complicated!!! I'm still not sure if we both have the
same picture and if not, which one is better ;-)
If I got the above right I see a problem: The assumption that the
classes of the model values that a user deals with are identical with
the classes of the corresponding model values that the server deals with
is not generally correct. Primitive types have the same class on both
sides of the network, Strings too. The differences may start with
multi-valued features and with user-defined EDataTypes (which arrive as
Strings at the server-side).
Let's wait if my other answer (with the possible solution) takes us a
step further...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Skeleton Implementation (CDOID format) [message #615356 is a reply to message #111442] |
Thu, 31 January 2008 13:25 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
I should wait for your answer...
Actually it is kind of the other way around than I thought you ment. The client knows all the
implementation classes of the model (as the client has the generated code). However the server side
does not know all the implementation classes as the server side is generic. To overcome this issue
cdo currently maps the custom client side object types to strings.
Is this a fair description?
Btw, it can all be a bit theoritical (except for composite id's) as most (=all) field values will be
primitive types. And for composite id's we can think of a different solution (maybe use a specific
cdo composite class which is always used in the hibernate mapping for composite id's).
Would it be an idea to ignore this issue for now and assume that an id is always a primitive type
(long or string basically)? Then we can later think about how to solve composite id's.
The same for the other field values they are always primitive types (which is really most common).
One specific is enumeration, you have a cdo specific enumeration type which can be used to transfer
enum values back and forth? Or do you use the string/int value of an enum?
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> I also learned something here :-).
>>
>> What I mean is that the classes of the values which together make up
>> the id are (by definition) also known client side, otherwise the
>> client can not work with the objects anyway (as the id is constructed
>> from values in the object itself).
>>
>> For example, a type customerorder has an order number field and this
>> field is tagged as the id. The client knows how to handle the class of
>> the order number field (otherwise the client can not handle the
>> customer order at all), the class of the order number will be present
>> in the generated code on the client. So if the client can handle the
>> order number field then the client can also handle the id object
>> (which by definition is the same as the value in the order number field).
>>
>> Or do you mean something else?
> Heaven, this is complicated!!! I'm still not sure if we both have the
> same picture and if not, which one is better ;-)
>
> If I got the above right I see a problem: The assumption that the
> classes of the model values that a user deals with are identical with
> the classes of the corresponding model values that the server deals with
> is not generally correct. Primitive types have the same class on both
> sides of the network, Strings too. The differences may start with
> multi-valued features and with user-defined EDataTypes (which arrive as
> Strings at the server-side).
>
> Let's wait if my other answer (with the possible solution) takes us a
> step further...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
| |
Re: [CDO] Teneo/Hibernate integration [message #615365 is a reply to message #110204] |
Fri, 01 February 2008 19:36 |
|
This is a multi-part message in MIME format.
--------------000900060703040905050607
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Hi Martin,
CDOID format can now be defined by the IStore:
|*public interface *CDOID *extends *Serializable
{
*public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
*public *Type getType();
*public **boolean *isNull();
*public **boolean *isObject();
*public **boolean *isLegacy();
*public **boolean *isMeta();
*public **boolean *isTemporary();
*public **void *read(ExtendedDataInput in) *throws *IOException;
*public **void *write(ExtendedDataOutput out) *throws *IOException;
/**
* @author Eike Stepper
*/
*public enum *Type
{
NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
}
}|
There are 6 CDOID types but we are only occupied with OBJECT and
LEGACY_OBJECT (currently broken).
Each IStore implementation must deliver a CDOIDObjectFactory:
|*public interface *CDOIDObjectFactory
{
*public *Class<?>[] getCDOIDObjectClasses();
*public *CDOIDObject createCDOIDObject();
}|
The Class[] array is used to transafer the needed classes to the client.
This is all handled by the framework. Currently there is no caching in
the client.
The DBStore (look there for an example) passes all test cases but it
uses a CDOID implementation that is located as a default in the
underlying protocol plugin. If we want to implement things like CDOIDs
for composite PKs I guess that class loading won't work at once. But
it's too late now. I'll investigate that later...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
--------------000900060703040905050607
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Martin,<br>
<br>
CDOID format can now be defined by the IStore:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615366 is a reply to message #111573] |
Fri, 01 February 2008 20:00 |
Simon Mc Duff Messages: 596 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
------=_NextPart_000_089D_01C864E3.27A68F40
Content-Type: text/plain;
charset="ISO-8859-15"
Content-Transfer-Encoding: quoted-printable
Does it have an overhead compare to before if we are using CDOID with =
long ? (default behavior)
In this case, I assume you will not transfer .class ?
"Eike Stepper" <stepper@sympedia.de> wrote in message =
news:fnvscr$gbr$1@build.eclipse.org...
Hi Martin,
CDOID format can now be defined by the IStore:
public interface CDOID extends Serializable
{
public static final CDOID NULL =3D =
org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
public Type getType();
public boolean isNull();
public boolean isObject();
public boolean isLegacy();
public boolean isMeta();
public boolean isTemporary();
public void read(ExtendedDataInput in) throws IOException;
public void write(ExtendedDataOutput out) throws IOException;
/**
* @author Eike Stepper
*/
public enum Type
{
NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
}
} =20
There are 6 CDOID types but we are only occupied with OBJECT and =
LEGACY_OBJECT (currently broken).
Each IStore implementation must deliver a CDOIDObjectFactory:
public interface CDOIDObjectFactory
{
public Class<?>[] getCDOIDObjectClasses();
public CDOIDObject createCDOIDObject();
} =20
The Class[] array is used to transafer the needed classes to the =
client. This is all handled by the framework. Currently there is no =
caching in the client.
The DBStore (look there for an example) passes all test cases but it =
uses a CDOID implementation that is located as a default in the =
underlying protocol plugin. If we want to implement things like CDOIDs =
for composite PKs I guess that class loading won't work at once. But =
it's too late now. I'll investigate that later...
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
------=_NextPart_000_089D_01C864E3.27A68F40
Content-Type: text/html;
charset="ISO-8859-15"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=3DContent-Type =
content=3Dtext/html;charset=3DISO-8859-15>
<META content=3D"MSHTML 6.00.2900.3199" name=3DGENERATOR></HEAD>
<BODY text=3D#000000 bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Does it have an overhead compare to =
before if we=20
are using CDOID with long ? (default behavior)</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>In this case, I assume you will not =
transfer .class=20
?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>"Eike Stepper" <<A=20
href=3D"mailto:stepper@sympedia.de">stepper@sympedia.de</A>> wrote in =
message=20
<A=20
href=3D"news:fnvscr$gbr$1@build.eclipse.org">news:fnvscr$gbr$1@build.ecli=
pse.org</A>...</DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">Hi=20
Martin,<BR><BR>CDOID format can now be defined by the IStore:<BR><BR>
<STYLE type=3Dtext/css>CODE {
FONT-SIZE: 10pt; MARGIN: 0px; FONT-FAMILY: Courier New, Courier
}
</STYLE>
<!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><!-- =3D Java Sourcecode to HTML automatically =
converted code =3D --><!-- =3D Java2Html Converter 5.0 [2006-02-26] by =
Markus Gebhard markus@jave.de =3D --><!-- =3D Further =
information: http://www.java2html.de =3D -->
<DIV class=3Djava align=3Dleft>
<TABLE cellSpacing=3D0 cellPadding=3D3 bgColor=3D#ffffff border=3D0>
<TBODY>
<TR><!-- start source code -->
<TD vAlign=3Dtop noWrap align=3Dleft><CODE><FONT=20
color=3D#7f0055><B>public interface </B ></FONT><FONT=20
color=3D#000000>CDOID </FONT><FONT=20
color=3D#7f0055><B>extends </B></FONT><FONT=20
color=3D#000000>Serializable</FONT><BR><FONT=20
color=3D#000000>{</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
=
color=3D#7f0055><B>public static final </B></FONT><FONT=20
=
color=3D#000000> CDOID NULL =3D org.eclipse.emf.cd o.interna=
l.protocol.id.CDOIDNullImpl.INSTANCE;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>Type getType</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isNull</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isObject</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isLegacy</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isMeta</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>boolean </B></FONT><FONT=20
color=3D#000000>isTemporary</FONT><FONT =
color=3D#000000>()</FONT><FONT=20
color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>void </B></FONT><FONT=20
color=3D#000000>read</FONT><FONT color=3D#000000>(</FONT><FONT=20
color=3D#000000>ExtendedDataInput in</FONT><FONT=20
color=3D#000000>) </FONT><FONT=20
color=3D#7f0055><B>throws </B></FONT><FONT=20
color=3D#000000>IOException;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#7f0055><B>void </B></FONT><FONT=20
color=3D#000000>write</FONT><FONT color=3D#000000>(</FONT><FONT=20
color=3D#000000>ExtendedDataOutput out</FONT><FONT=20
color=3D#000000>) </FONT><FONT=20
color=3D#7f0055><B>throws </B></FONT><FONT=20
color=3D#000000>IOException;</FONT><BR><FONT=20
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>/**</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>* </FONT><FONT=20
color=3D#7f9fbf>@author </FONT><FONT=20
color=3D#3f5fbf>Eike Stepper</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT=20
color=3D#3f5fbf>*/</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public enum </B></FONT ><FONT=20
color=3D#000000>Type</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT =
color=3D#000000>{</FONT><BR><FONT=20
color=3D#ffffff> </FONT ><FONT=20
=
color=3D#000000> NULL, OBJECT, LEGACY_OBJECT, TEMP _OBJECT,&=
nbsp;META, TEMP_META</FONT><BR><FONT=20
color=3D#ffffff> </FONT><FONT =
color=3D#000000>}</FONT><BR><FONT=20
color=3D#000000>}</FONT></CODE>=20
</TD><!-- end source code --></TR></TBODY></TABLE></DIV><!-- =3D =
END of automatically generated HTML code =3D --><!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><BR>There=20
are 6 CDOID types but we are only occupied with OBJECT and =
LEGACY_OBJECT=20
(currently broken).<BR><BR>Each IStore implementation must deliver a=20
CDOIDObjectFactory:<BR><BR>
<STYLE type=3Dtext/css>
<!--code { font-family: Courier New, Courier; font-size: 10pt; =
margin: 0px; }-->
</STYLE>
<!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><!-- =3D Java Sourcecode to HTML automatically =
converted code =3D --><!-- =3D Java2Html Converter 5.0 [2006-02-26] by =
Markus Gebhard markus@jave.de =3D --><!-- =3D Further =
information: http://www.java2html.de =3D -->
<DIV class=3Djava align=3Dleft>
<TABLE cellSpacing=3D0 cellPadding=3D3 bgColor=3D#ffffff border=3D0>
<TBODY>
<TR><!-- start source code -->
<TD vAlign=3Dtop noWrap align=3Dleft><CODE><FONT=20
color=3D#7f0055><B>public interface </B ></FONT><FONT=20
color=3D#000000>CDOIDObjectFactory</FONT><BR><FONT=20
color=3D#000000>{</FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>Class<?></FONT><FONT=20
color=3D#000000>[] </FONT><FONT=20
color=3D#000000>getCDOIDObjectClasses</FONT><FONT=20
color=3D#000000>()</FONT><FONT color=3D#000000>;</FONT><BR><FONT =
color=3D#ffffff></FONT><BR><FONT =
color=3D#ffffff> </FONT><FONT=20
color=3D#7f0055><B>public </B></FONT><FONT=20
color=3D#000000>CDOIDObject createCDOIDObject</FONT ><FONT=20
color=3D#000000>()</FONT><FONT color=3D#000000>;</FONT><BR><FONT =
color=3D#000000>}</FONT></CODE>=20
</TD><!-- end source code --></TR></TBODY></TABLE></DIV><!-- =3D =
END of automatically generated HTML code =3D --><!-- =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D --><BR>The=20
Class[] array is used to transafer the needed classes to the client. =
This is=20
all handled by the framework. Currently there is no caching in the=20
client.<BR><BR>The DBStore (look there for an example) passes all test =
cases=20
but it uses a CDOID implementation that is located as a default in the =
underlying protocol plugin. If we want to implement things like CDOIDs =
for=20
composite PKs I guess that class loading won't work at once. But it's =
too late=20
now. I'll investigate that later...<BR><BR>Regards,<BR>Eike=20
Stepper<BR>----<BR><A class=3Dmoz-txt-link-freetext=20
=
href=3D"http://wiki.eclipse.org/CDO">http://wiki.eclipse.org/CDO</A><BR><=
A=20
class=3Dmoz-txt-link-freetext=20
=
href=3D"http://wiki.eclipse.org/Net4j">http://wiki.eclipse.org/Net4j</A><=
BR><BR><BR><BR><BR></BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_089D_01C864E3.27A68F40--
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615367 is a reply to message #111583] |
Fri, 01 February 2008 20:10 |
|
This is a multi-part message in MIME format.
--------------080302060008010403080906
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Simon McDuff schrieb:
>
> Does it have an overhead compare to before if we are using CDOID with
> long ? (default behavior)
> In this case, I assume you will not transfer .class ?
Currently I do because I just wanted to test if that works ;-)
Later it won't be necessary anymore.
The overhead is minimal. The 3 classes are only transferred with (each)
OpenSessionIndication.responding().
A CDOID value has at least 1 byte, the ID type. Depending on that type
there are many cases now where fewer bytes are transferred. CDOID.NULL,
for instance, has only 1 byte total. All temporary IDs (TEMP_OBJECT and
TEMP_META) have an additional 32 bit integer. The OBJECT and
LEGACY_OBJECT ids are now store-dependent and the DBStore uses ids with
an additional 8-byte integer.
Cheers
/Eike
>
>
> "Eike Stepper" <stepper@sympedia.de <mailto:stepper@sympedia.de>>
> wrote in message news:fnvscr$gbr$1@build.eclipse.org...
>
> Hi Martin,
>
> CDOID format can now be defined by the IStore:
>
> |*public interface *CDOID *extends *Serializable
> {
> *public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>
> *public *Type getType();
>
> *public **boolean *isNull();
>
> *public **boolean *isObject();
>
> *public **boolean *isLegacy();
>
> *public **boolean *isMeta();
>
> *public **boolean *isTemporary();
>
> *public **void *read(ExtendedDataInput in) *throws *IOException;
>
> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>
> /**
> * @author Eike Stepper
> */
> *public enum *Type
> {
> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
> }
> }|
>
>
> There are 6 CDOID types but we are only occupied with OBJECT and
> LEGACY_OBJECT (currently broken).
>
> Each IStore implementation must deliver a CDOIDObjectFactory:
>
> |*public interface *CDOIDObjectFactory
> {
> *public *Class<?>[] getCDOIDObjectClasses();
>
> *public *CDOIDObject createCDOIDObject();
> }|
>
>
> The Class[] array is used to transafer the needed classes to the
> client. This is all handled by the framework. Currently there is
> no caching in the client.
>
> The DBStore (look there for an example) passes all test cases but
> it uses a CDOID implementation that is located as a default in the
> underlying protocol plugin. If we want to implement things like
> CDOIDs for composite PKs I guess that class loading won't work at
> once. But it's too late now. I'll investigate that later...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
>
--------------080302060008010403080906
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Simon McDuff schrieb:
<blockquote cite="mid:fnvtog$mo7$1@build.eclipse.org" type="cite">
<title></title>
<meta http-equiv="Content-Type"
content="text/html;charset=ISO-8859-15">
<meta content="MSHTML 6.00.2900.3199" name="GENERATOR">
<div>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615370 is a reply to message #111573] |
Fri, 01 February 2008 21:17 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I did not have time today (too much customer work) :-(.
Related to the cdoidfactory, what I am not sure about is how to create a cdoid object without access
to the underlying database id object or the object itself. I mean when I look at the api of
cdoidfactory it seems that it assumes that id's are autogenerated?
Btw, I am looking through the cdo code to see how cdoid is used, what does ResourceIDRequest do?
gr. Martin
Eike Stepper wrote:
> Hi Martin,
>
> CDOID format can now be defined by the IStore:
>
> |*public interface *CDOID *extends *Serializable
> {
> *public static final *CDOID NULL = org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>
> *public *Type getType();
>
> *public **boolean *isNull();
>
> *public **boolean *isObject();
>
> *public **boolean *isLegacy();
>
> *public **boolean *isMeta();
>
> *public **boolean *isTemporary();
>
> *public **void *read(ExtendedDataInput in) *throws *IOException;
>
> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>
> /**
> * @author Eike Stepper
> */
> *public enum *Type
> {
> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
> }
> }|
>
>
> There are 6 CDOID types but we are only occupied with OBJECT and
> LEGACY_OBJECT (currently broken).
>
> Each IStore implementation must deliver a CDOIDObjectFactory:
>
> |*public interface *CDOIDObjectFactory
> {
> *public *Class<?>[] getCDOIDObjectClasses();
>
> *public *CDOIDObject createCDOIDObject();
> }|
>
>
> The Class[] array is used to transafer the needed classes to the client.
> This is all handled by the framework. Currently there is no caching in
> the client.
>
> The DBStore (look there for an example) passes all test cases but it
> uses a CDOID implementation that is located as a default in the
> underlying protocol plugin. If we want to implement things like CDOIDs
> for composite PKs I guess that class loading won't work at once. But
> it's too late now. I'll investigate that later...
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
>
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615372 is a reply to message #111618] |
Sat, 02 February 2008 07:05 |
|
This is a multi-part message in MIME format.
--------------020005010506040504080003
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> I did not have time today (too much customer work) :-(.
That will start next wee for me again, too ;-)
>
> Related to the cdoidfactory, what I am not sure about is how to create
> a cdoid object without access to the underlying database id object or
> the object itself. I mean when I look at the api of cdoidfactory it
> seems that it assumes that id's are autogenerated?
I also thought about that and I guess there's still refactoring to be
done. I'm thinking about a 2-split factory:
|*public interface *CDOIDObjectFactory
{
*public *Class<?>[] getCDOIDObjectClasses();
*public *CDOIDObject createCDOIDObject(CDORevision revision);
*public *CDOIDObject readCDOIDObject(ExtendedDataInput in);
}|
>
> Btw, I am looking through the cdo code to see how cdoid is used, what
> does ResourceIDRequest do?
When a client calls one of ResourceSet.getResource(URI uri) or
CDOView.getResource(String path), which are equivalent if uri ==
"cdo:path", the ResourceIDRequest asks the server to deliver the CDOID
that belongs to the named resource. The server will do so in the class
ResourceIDIndication.
The reverse mapping CDOID --> resourcePath can be queried with
ResourcePathRequest/Indication.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
--------------020005010506040504080003
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fo028n$7el$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
I did not have time today (too much customer work) :-(.
<br>
</blockquote>
That will start next wee for me again, too ;-)<br>
<br>
<blockquote cite="mid:fo028n$7el$1@build.eclipse.org" type="cite"><br>
Related to the cdoidfactory, what I am not sure about is how to create
a cdoid object without access to the underlying database id object or
the object itself. I mean when I look at the api of cdoidfactory it
seems that it assumes that id's are autogenerated?
<br>
</blockquote>
I also thought about that and I guess there's still refactoring to be
done. I'm thinking about a 2-split factory:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" nowrap="nowrap"
valign="top"> <code><font color="#7f0055"><b>public
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Hibernate Configuration/SessionFactory/Session/Transaction [message #615373 is a reply to message #110231] |
Sat, 02 February 2008 07:59 |
|
I'm thinking about how to map these Hibernate concepts to the IStore
concepts. I learned about the following facts (please correct me or add
comments):
a) A Transaction instance is needed when data is to be written. A
Transaction can/must be obtained from a Session. Can there be multiple
concurrent transactions on a single session?
b) A Session instance is needed when data is to be read or a Transaction
is to be started. It can/must be obtained from a SessionFactory. Each
thread must use its own Session instance (cheap creation).
c) A SessionFactory can be built out of a Configuration and can't be
altered after that. Can there be multiple concurrent factories built out
of a single configuration?
d) A Configuration instance is used to add/remove mappings and to create
SessionFactories for these mappings. Can this be done if
SessionFactories have already been built? An empty Configuration
instance is created via default ctor.
My idea is the following:
1) HibernateStore has a Configuration to manage the mappings
2) In addition it builds and keeps a SessionFactory which must be
rebuilt after each modification of the Configuration
3) If an IStoreReader is requested by the framework, HibernateStore
creates a new HibernateStoreReader which uses the current SessionFactory
to open a new Session
4) If an IStoreWriter is requested by the framework, HibernateStore
creates a new HibernateStoreWriter (extends the reader and thus already
has a Session) which uses the Session to begin a new Transaction
5) There are 2 different events that can cause the Configuration to be
changed:
5.1) A client commits a *new* package. This leads to
IStoreWriter.writePackages() being called. The HibernateStoreWriter
implementation will persist the packages (so that they can be retrieved
after restarts, see 5.2) and pass them to HibernateStore (see 1 + 2)
5.2) A client loads an object with a class that is in an *existing*
package (which hasn't been loaded before). This leads to
IStoreReader.readPackage() being called. The HibernateStoreReader will
read/return the persisted package and also pass it to HibernateStore (se
1 + 2)
Open questions:
- How must 1) + 2) be protected /synchronized in a concurrent server
environment, i.e. can a new SessionFactory be built/used while "old"
SessionFactories (based on previous Configuration states) are still in
use? Or do we have to use proper ReadWriteLocks, which would cause all
repository access to halt on each change of mappings?
- How should the actual JDBC Connection/DataSource be managed? Is this
part of the Hibernate Configuration/SessionFactory/Session? Should we
pass a DataSource into the HibernateStore which a HibernateStoreReader
can use to obtain a Connection when it must create its Hibernate Session?
- Where do the mappings come from? In 5.1 and 5.2 we have access to a
CDOPackage which can deliver the XML string of the corresponding
EPackage. Is this the place where Teneo comes into game?
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615374 is a reply to message #111618] |
Sat, 02 February 2008 08:13 |
|
Martin Taal schrieb:
> Hi Eike,
> I did not have time today (too much customer work) :-(.
>
> Related to the cdoidfactory, what I am not sure about is how to create
> a cdoid object without access to the underlying database id object or
> the object itself. I mean when I look at the api of cdoidfactory it
> seems that it assumes that id's are autogenerated?
Ignore my previous answer to this particular question!!! I was confused ;-)
The factory is only used to recreate existing CDOIDs from a stream. The
factory must create/return a "naked" instance which is subsequently used
by the framework to read() the actual state. For this purpose the CDOID
implementation class will usually have a default ctor. May be I could
make this more obvious by adding the stream parameter to the create()
method of the factory, which also has the advantage that the factory can
read from the stream before deciding about the actual implementation class.
To create new CDOID values we can just call additional ctors on our
implementation class!
Cheers
/Eike
>
> Btw, I am looking through the cdo code to see how cdoid is used, what
> does ResourceIDRequest do?
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi Martin,
>>
>> CDOID format can now be defined by the IStore:
>>
>> |*public interface *CDOID *extends *Serializable
>> {
>> *public static final *CDOID NULL =
>> org.eclipse.emf.cdo.internal.protocol.id.CDOIDNullImpl.INSTA NCE;
>>
>> *public *Type getType();
>>
>> *public **boolean *isNull();
>>
>> *public **boolean *isObject();
>>
>> *public **boolean *isLegacy();
>>
>> *public **boolean *isMeta();
>>
>> *public **boolean *isTemporary();
>>
>> *public **void *read(ExtendedDataInput in) *throws *IOException;
>>
>> *public **void *write(ExtendedDataOutput out) *throws *IOException;
>>
>> /**
>> * @author Eike Stepper
>> */
>> *public enum *Type
>> {
>> NULL, OBJECT, LEGACY_OBJECT, TEMP_OBJECT, META, TEMP_META
>> }
>> }|
>>
>>
>> There are 6 CDOID types but we are only occupied with OBJECT and
>> LEGACY_OBJECT (currently broken).
>>
>> Each IStore implementation must deliver a CDOIDObjectFactory:
>>
>> |*public interface *CDOIDObjectFactory
>> {
>> *public *Class<?>[] getCDOIDObjectClasses();
>>
>> *public *CDOIDObject createCDOIDObject();
>> }|
>>
>>
>> The Class[] array is used to transafer the needed classes to the
>> client. This is all handled by the framework. Currently there is no
>> caching in the client.
>>
>> The DBStore (look there for an example) passes all test cases but it
>> uses a CDOID implementation that is located as a default in the
>> underlying protocol plugin. If we want to implement things like
>> CDOIDs for composite PKs I guess that class loading won't work at
>> once. But it's too late now. I'll investigate that later...
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>>
>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Mapping the Meta Model [message #615375 is a reply to message #110231] |
Sat, 02 February 2008 09:19 |
|
To persist/load the meta model I'd like to use Hibernate.
The following classes must be mapped:
1) CDOPackageImpl
2) CDOClassImpl
3) CDOFeatureImpl
There are also some subclasses of these classes that represent the
system packages CDOCorePackage and CDOResourcePackage. Their instances
need not be persisted.
Questions:
- Do the three classes need to be Serializable and derived properties
marked transient?
- Does the usage of JPA annotations require ejb3-persistence.jar to be
present on the classpath of the protocol plugin (where the three classes
are located)?
- To go without the ejb3-persistence.jar could/should I use XML files
directly in the org.eclipse.emf.cdo.server.hibernate plugin?
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Mapping the Meta Model [message #615376 is a reply to message #111652] |
Sat, 02 February 2008 09:23 |
|
Eike Stepper schrieb:
> To persist/load the meta model I'd like to use Hibernate.
> The following classes must be mapped:
> 1) CDOPackageImpl
> 2) CDOClassImpl
> 3) CDOFeatureImpl
>
> There are also some subclasses of these classes that represent the
> system packages CDOCorePackage and CDOResourcePackage. Their instances
> need not be persisted.
>
> Questions:
> - Do the three classes need to be Serializable and derived properties
> marked transient?
> - Does the usage of JPA annotations require ejb3-persistence.jar to be
> present on the classpath of the protocol plugin (where the three
> classes are located)?
If yes, another solution could be to specify an optional dependency on a
plugin with hibernate-annotations.jar and ejb3-persistence.jar.
Then we could use the annotations in the protocol plugin. Any idea what
happens with the annotated classes if the optional dependency is not
satisfied at runtime???
> - To go without the ejb3-persistence.jar could/should I use XML files
> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Mapping the Meta Model [message #615377 is a reply to message #111652] |
Sat, 02 February 2008 11:18 |
|
This is a multi-part message in MIME format.
--------------030808090306080600040104
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
I've started with an initial version of a hbm.xml file in
/org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.eclipse.emf.cdo.internal.protocol.model"
default-access="field">
<class name="CDOPackageImpl" table="cdo_packages">
<property name="packageURI"
column-name="uri"
type="string"
not-null="true"
length="255"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="ecore"
type="java.sql.Clob"
not-null="false"
lazy="true"/>
<property name="dynamic"
type="boolean"
not-null="true"/>
</class>
<class name="CDOClassImpl" table="cdo_classes">
<property name="classifierID"
column-name="classifier"
type="int"
not-null="true"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="isAbstract"
column-name="abstract"
type="boolean"
not-null="true"/>
</class>
<class name="CDOFeatureImpl" table="cdo_features">
<property name="featureID"
column-name="feature"
type="int"
not-null="true"/>
<property name="name"
type="string"
not-null="true"
length="255"/>
<property name="type"
type="int"
not-null="true"/>
<property name="referenceType"
column-name="reftype"
type="string"
not-null="false"/>
<property name="many"
type="boolean"
not-null="true"/>
<property name="containment"
type="boolean"
not-null="false"/>
</class>
</hibernate-mapping>
Open Questions:
- The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
which is internally a structure of a long integer (lower bound meta
CDOID) and a normal int (size of the range). I'd like to persist it as
two long values (lower bound and upper bound, both have getters in
CDOIDMetaRange). How is this possible?
- The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
which is internally a structure of a String (package URI) and an int
(classifierID). How should we map this?
- The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
which works similar to the aforementioned referenceType.
- The three classes have bidi containment associations
(CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't know
how to map them.
Regards,
Eike Stepper
----
http://wiki.eclipse.org/CDO
http://wiki.eclipse.org/Net4j
Eike Stepper schrieb:
> To persist/load the meta model I'd like to use Hibernate.
> The following classes must be mapped:
> 1) CDOPackageImpl
> 2) CDOClassImpl
> 3) CDOFeatureImpl
>
> There are also some subclasses of these classes that represent the
> system packages CDOCorePackage and CDOResourcePackage. Their instances
> need not be persisted.
>
> Questions:
> - Do the three classes need to be Serializable and derived properties
> marked transient?
> - Does the usage of JPA annotations require ejb3-persistence.jar to be
> present on the classpath of the protocol plugin (where the three
> classes are located)?
> - To go without the ejb3-persistence.jar could/should I use XML files
> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--------------030808090306080600040104
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body alink="#ee0000" bgcolor="#ffffff" link="#0000ee" text="#000000"
vlink="#551a8b">
I've started with an initial version of a hbm.xml file in
/org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml: <br>
<br>
<table bgcolor="#ffffcc" border="0" cellpadding="2" cellspacing="2"
width="100%">
<tbody>
<tr>
<td valign="top"><?xml version="1.0"?><br>
<!DOCTYPE hibernate-mapping SYSTEM
<a class="moz-txt-link-rfc2396E" href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"</a>><br>
<br>
<hibernate-mapping
package="org.eclipse.emf.cdo.internal.protocol.model"
default-access="field"><br>
<br>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Mapping the Meta Model [message #615378 is a reply to message #111664] |
Sat, 02 February 2008 14:34 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
A simple way of storing it, is to store the model as a char blob in a epackage table. This ofcourse
only works if you don't need database access to the individual model elements, as you read most
information in-memory anyway this seems pretty workable.
If you have an ecore model for the mapping then I can generate a mapping for you.
To answer your questions:
I am not sure are CDOIDMetaRange independent classes which are also referenced from other classes?
Same question for CDOClassProxy?
If they are embedded types then they can be mapped like this:
<component name="referenceType" class="full_class_name_to_CDOClassProxy">
<property name="package URI" lazy="false" insert="true" update="true" not-null="true"
unique="false" type="java.lang.String"/>
<property name="classifierID" lazy="false" insert="true" update="true" not-null="false"
unique="false" type="int"/>
</component>
A single reference to another type which is also used by other classes:
<many-to-one name="referenceType" class="CDOClassProxy"/>
Here is an example of how a bidirectional list is mapped for the library example, note that on the
many side the insert and update attributes both are false. Also because possibly the package-class
relation is containment you should use a cascade of all, delete-orphan in the list. Instead of using
the entity-name you can also use the class attribute (with the classname);
<list name="books" lazy="true" cascade="merge,persist,save-update,lock,refresh">
<cache usage="read-write"/>
<key update="true">
<column name="`book_author_e_id`" not-null="false" unique="false"/>
</key>
<list-index column="`writer_books_idx`"/>
<one-to-many entity-name="Book"/>
</list>
<many-to-one name="author" entity-name="Writer" cascade="merge,persist,save-update,lock,refresh"
foreign-key="book_author" lazy="false" insert="false" update="false" not-null="false">
<column not-null="false" unique="false" name="`book_author_e_id`"/>
</many-to-one>
gr. Martin
Eike Stepper wrote:
> I've started with an initial version of a hbm.xml file in
> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>
> <?xml version="1.0"?>
> <!DOCTYPE hibernate-mapping SYSTEM
> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>
> <hibernate-mapping package="org.eclipse.emf.cdo.internal.protocol.model"
> default-access="field">
>
> <class name="CDOPackageImpl" table="cdo_packages">
> <property name="packageURI"
> column-name="uri"
> type="string"
> not-null="true"
> length="255"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="ecore"
> type="java.sql.Clob"
> not-null="false"
> lazy="true"/>
> <property name="dynamic"
> type="boolean"
> not-null="true"/>
> </class>
>
> <class name="CDOClassImpl" table="cdo_classes">
> <property name="classifierID"
> column-name="classifier"
> type="int"
> not-null="true"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="isAbstract"
> column-name="abstract"
> type="boolean"
> not-null="true"/>
> </class>
>
> <class name="CDOFeatureImpl" table="cdo_features">
> <property name="featureID"
> column-name="feature"
> type="int"
> not-null="true"/>
> <property name="name"
> type="string"
> not-null="true"
> length="255"/>
> <property name="type"
> type="int"
> not-null="true"/>
> <property name="referenceType"
> column-name="reftype"
> type="string"
> not-null="false"/>
> <property name="many"
> type="boolean"
> not-null="true"/>
> <property name="containment"
> type="boolean"
> not-null="false"/>
> </class>
>
> </hibernate-mapping>
>
>
> Open Questions:
> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
> which is internally a structure of a long integer (lower bound meta
> CDOID) and a normal int (size of the range). I'd like to persist it as
> two long values (lower bound and upper bound, both have getters in
> CDOIDMetaRange). How is this possible?
> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
> which is internally a structure of a String (package URI) and an int
> (classifierID). How should we map this?
> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
> which works similar to the aforementioned referenceType.
> - The three classes have bidi containment associations
> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't know
> how to map them.
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
>
> Eike Stepper schrieb:
>> To persist/load the meta model I'd like to use Hibernate.
>> The following classes must be mapped:
>> 1) CDOPackageImpl
>> 2) CDOClassImpl
>> 3) CDOFeatureImpl
>>
>> There are also some subclasses of these classes that represent the
>> system packages CDOCorePackage and CDOResourcePackage. Their instances
>> need not be persisted.
>>
>> Questions:
>> - Do the three classes need to be Serializable and derived properties
>> marked transient?
>> - Does the usage of JPA annotations require ejb3-persistence.jar to be
>> present on the classpath of the protocol plugin (where the three
>> classes are located)?
>> - To go without the ejb3-persistence.jar could/should I use XML files
>> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Mapping the Meta Model [message #615379 is a reply to message #111671] |
Sun, 03 February 2008 09:48 |
|
This is a multi-part message in MIME format.
--------------040109000904050209000902
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Martin Taal schrieb:
> Hi Eike,
> A simple way of storing it, is to store the model as a char blob in a
> epackage table. This ofcourse only works if you don't need database
> access to the individual model elements, as you read most information
> in-memory anyway this seems pretty workable.
I also thought about this option and it would be really easy. But the
current solution also has 2 advantages: The user/admin can better
interpret the meta information (including usage for queries) and I can
better learn about Hibernate ;-)
> If you have an ecore model for the mapping then I can generate a
> mapping for you.
>
> To answer your questions:
> I am not sure are CDOIDMetaRange independent classes which are also
> referenced from other classes? Same question for CDOClassProxy?
> If they are embedded types then they can be mapped like this:
> <component name="referenceType" class="full_class_name_to_CDOClassProxy">
> <property name="package URI" lazy="false" insert="true"
> update="true" not-null="true" unique="false" type="java.lang.String"/>
> <property name="classifierID" lazy="false" insert="true"
> update="true" not-null="false" unique="false" type="int"/>
> </component>
>
> A single reference to another type which is also used by other classes:
> <many-to-one name="referenceType" class="CDOClassProxy"/>
>
> Here is an example of how a bidirectional list is mapped for the
> library example, note that on the many side the insert and update
> attributes both are false. Also because possibly the package-class
> relation is containment you should use a cascade of all, delete-orphan
> in the list. Instead of using the entity-name you can also use the
> class attribute (with the classname);
> <list name="books" lazy="true"
> cascade="merge,persist,save-update,lock,refresh">
> <cache usage="read-write"/>
> <key update="true">
> <column name="`book_author_e_id`" not-null="false"
> unique="false"/>
> </key>
> <list-index column="`writer_books_idx`"/>
> <one-to-many entity-name="Book"/>
> </list>
>
> <many-to-one name="author" entity-name="Writer"
> cascade="merge,persist,save-update,lock,refresh"
> foreign-key="book_author" lazy="false" insert="false" update="false"
> not-null="false">
> <column not-null="false" unique="false"
> name="`book_author_e_id`"/>
> </many-to-one>
Thanks for the hints. I'll try them ASAP.
In CVS there is now a test class that does all the setup of a standalone
client/server with Mysql. It commits a simple model to the repository.
It seems to work pretty well until it runs into the first
UnsupportedOperationExceptions of the new HibernateStore. Now we can
implement one method after the other:
|*public class *HibernateTest
{
*private static final *String REPOSITORY_NAME = "repo1";
*public static **void *main(String[] args) *throws *Exception
{
IManagedContainer container = initContainer();
// Start the transport and create a repository
JVMUtil.getAcceptor(container, "default"); // Start the JVM transport
CDOServerUtil.addRepository(container, createRepository()); // Start a CDO respository
// Establish a communications connection and open a session with the repository
IConnector connector = JVMUtil.getConnector(container, "default"); // Open a JVM connection
CDOSession session = CDOUtil.openSession(connector, REPOSITORY_NAME, *true*);// Open a CDO session
session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);// Not needed after first commit!!!
// Open a transaction, and create a new resource
CDOTransaction transaction = session.openTransaction();
Resource resource = transaction.createResource("/my/big/resource");
resource.getContents().add(getInputModel());
transaction.commit();
// Cleanup
session.close();
connector.disconnect();
}
*private static *IManagedContainer initContainer()
{
// Turn on tracing
OMPlatform.INSTANCE.setDebugging(*true*);
OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
// Prepare the standalone infra structure (not needed when running inside Eclipse)
IManagedContainer container = ContainerUtil.createContainer(); // Create a wiring container
Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
JVMUtil.prepareContainer(container); // Prepare the JVM transport
CDOServerUtil.prepareContainer(container); // Prepare the CDO server
CDOUtil.prepareContainer(container, *false*); // Prepare the CDO client
*return *container;
}
*private static *IRepository createRepository() *throws *Exception
{
Map<String, String> props = *new *HashMap<String, String>();
props.put(Props.PROP_SUPPORTING_AUDITS, "false");
props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
props.put(Props.PROP_VERIFYING_REVISIONS, "false");
props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
*return *CDOServerUtil.createRepository(REPOSITORY_NAME, createStore(), props);
}
*private static *IStore createStore() *throws *Exception
{
DriverManager.setLogWriter(*new *PrintWriter(System.out));
Driver driver = *new *com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
String driverName = driver.getClass().getName();
String dialectName = MySQLDialect.*class*.getName();
Configuration configuration = *new *Configuration();
configuration.setProperty(Environment.DRIVER, driverName);
configuration.setProperty(Environment.URL, "jdbc:mysql://localhost/cdohibernate");
configuration.setProperty(Environment.USER, "root");
configuration.setProperty(Environment.DIALECT, dialectName);
configuration.setProperty(Environment.SHOW_SQL, "true");
*return new *HibernateStore(configuration);
}
*private static *EObject getInputModel()
{
Category cat1 = Model1Factory.eINSTANCE.createCategory();
cat1.setName("CAT1");
Category cat2 = Model1Factory.eINSTANCE.createCategory();
cat2.setName("CAT2");
cat1.getCategories().add(cat2);
Product p1 = Model1Factory.eINSTANCE.createProduct();
p1.setName("P1");
cat1.getProducts().add(p1);
Product p2 = Model1Factory.eINSTANCE.createProduct();
p2.setName("P2");
cat1.getProducts().add(p2);
Product p3 = Model1Factory.eINSTANCE.createProduct();
p3.setName("P3");
cat2.getProducts().add(p3);
*return *cat1;
}
}|
BTW do you know if you're able/allowed to commit into the CDO CVS??
From tomorrow on I'll be working in Switzerland. That could have a
slightly negative impact on my responsiveness. I hope the hotel I chose
has a good WLAN at least for the evening hours ;-)
Cheers
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> I've started with an initial version of a hbm.xml file in
>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>
>> <?xml version="1.0"?>
>> <!DOCTYPE hibernate-mapping SYSTEM
>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>
>> <hibernate-mapping
>> package="org.eclipse.emf.cdo.internal.protocol.model"
>> default-access="field">
>>
>> <class name="CDOPackageImpl" table="cdo_packages">
>> <property name="packageURI"
>> column-name="uri"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="ecore"
>> type="java.sql.Clob"
>> not-null="false"
>> lazy="true"/>
>> <property name="dynamic"
>> type="boolean"
>> not-null="true"/>
>> </class>
>>
>> <class name="CDOClassImpl" table="cdo_classes">
>> <property name="classifierID"
>> column-name="classifier"
>> type="int"
>> not-null="true"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="isAbstract"
>> column-name="abstract"
>> type="boolean"
>> not-null="true"/>
>> </class>
>>
>> <class name="CDOFeatureImpl" table="cdo_features">
>> <property name="featureID"
>> column-name="feature"
>> type="int"
>> not-null="true"/>
>> <property name="name"
>> type="string"
>> not-null="true"
>> length="255"/>
>> <property name="type"
>> type="int"
>> not-null="true"/>
>> <property name="referenceType"
>> column-name="reftype"
>> type="string"
>> not-null="false"/>
>> <property name="many"
>> type="boolean"
>> not-null="true"/>
>> <property name="containment"
>> type="boolean"
>> not-null="false"/>
>> </class>
>>
>> </hibernate-mapping>
>>
>>
>> Open Questions:
>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>> which is internally a structure of a long integer (lower bound meta
>> CDOID) and a normal int (size of the range). I'd like to persist it
>> as two long values (lower bound and upper bound, both have getters in
>> CDOIDMetaRange). How is this possible?
>> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
>> which is internally a structure of a String (package URI) and an int
>> (classifierID). How should we map this?
>> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
>> which works similar to the aforementioned referenceType.
>> - The three classes have bidi containment associations
>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>> know how to map them.
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>>
>> Eike Stepper schrieb:
>>> To persist/load the meta model I'd like to use Hibernate.
>>> The following classes must be mapped:
>>> 1) CDOPackageImpl
>>> 2) CDOClassImpl
>>> 3) CDOFeatureImpl
>>>
>>> There are also some subclasses of these classes that represent the
>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>> instances need not be persisted.
>>>
>>> Questions:
>>> - Do the three classes need to be Serializable and derived
>>> properties marked transient?
>>> - Does the usage of JPA annotations require ejb3-persistence.jar to
>>> be present on the classpath of the protocol plugin (where the three
>>> classes are located)?
>>> - To go without the ejb3-persistence.jar could/should I use XML
>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>
>
--------------040109000904050209000902
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Martin Taal schrieb:
<blockquote cite="mid:fo1v12$n1f$1@build.eclipse.org" type="cite">Hi
Eike,
<br>
A simple way of storing it, is to store the model as a char blob in a
epackage table. This ofcourse only works if you don't need database
access to the individual model elements, as you read most information
in-memory anyway this seems pretty workable.
<br>
</blockquote>
I also thought about this option and it would be really easy. But the
current solution also has 2 advantages: The user/admin can better
interpret the meta information (including usage for queries) and I can
better learn about Hibernate ;-)<br>
<br>
<blockquote cite="mid:fo1v12$n1f$1@build.eclipse.org" type="cite">If
you have an ecore model for the mapping then I can generate a mapping
for you.
<br>
<br>
To answer your questions:
<br>
I am not sure are CDOIDMetaRange independent classes which are also
referenced from other classes? Same question for CDOClassProxy?
<br>
If they are embedded types then they can be mapped like this:
<br>
<component name="referenceType"
class="full_class_name_to_CDOClassProxy">
<br>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Mapping the Meta Model [message #615380 is a reply to message #111679] |
Sun, 03 February 2008 10:11 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
Thanks for the example I will try this out. I just tried but I don't have commit rights. It would
help a bit if I can get commit rights to the cdo-hibernate project. I would not be surpised if we
would require a specific cdo-teneo plugin to override some default teneo mapping behavior. For
example Teneo adds its own types for handling xsddate and enumeration in the mapping file, for cdo
this would be cdo specific classes.
I will answer your other news post shortly.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> A simple way of storing it, is to store the model as a char blob in a
>> epackage table. This ofcourse only works if you don't need database
>> access to the individual model elements, as you read most information
>> in-memory anyway this seems pretty workable.
> I also thought about this option and it would be really easy. But the
> current solution also has 2 advantages: The user/admin can better
> interpret the meta information (including usage for queries) and I can
> better learn about Hibernate ;-)
>
>> If you have an ecore model for the mapping then I can generate a
>> mapping for you.
>>
>> To answer your questions:
>> I am not sure are CDOIDMetaRange independent classes which are also
>> referenced from other classes? Same question for CDOClassProxy?
>> If they are embedded types then they can be mapped like this:
>> <component name="referenceType" class="full_class_name_to_CDOClassProxy">
>> <property name="package URI" lazy="false" insert="true"
>> update="true" not-null="true" unique="false" type="java.lang.String"/>
>> <property name="classifierID" lazy="false" insert="true"
>> update="true" not-null="false" unique="false" type="int"/>
>> </component>
>>
>> A single reference to another type which is also used by other classes:
>> <many-to-one name="referenceType" class="CDOClassProxy"/>
>>
>> Here is an example of how a bidirectional list is mapped for the
>> library example, note that on the many side the insert and update
>> attributes both are false. Also because possibly the package-class
>> relation is containment you should use a cascade of all, delete-orphan
>> in the list. Instead of using the entity-name you can also use the
>> class attribute (with the classname);
>> <list name="books" lazy="true"
>> cascade="merge,persist,save-update,lock,refresh">
>> <cache usage="read-write"/>
>> <key update="true">
>> <column name="`book_author_e_id`" not-null="false"
>> unique="false"/>
>> </key>
>> <list-index column="`writer_books_idx`"/>
>> <one-to-many entity-name="Book"/>
>> </list>
>>
>> <many-to-one name="author" entity-name="Writer"
>> cascade="merge,persist,save-update,lock,refresh"
>> foreign-key="book_author" lazy="false" insert="false" update="false"
>> not-null="false">
>> <column not-null="false" unique="false"
>> name="`book_author_e_id`"/>
>> </many-to-one>
> Thanks for the hints. I'll try them ASAP.
> In CVS there is now a test class that does all the setup of a standalone
> client/server with Mysql. It commits a simple model to the repository.
> It seems to work pretty well until it runs into the first
> UnsupportedOperationExceptions of the new HibernateStore. Now we can
> implement one method after the other:
>
> |*public class *HibernateTest
> {
> *private static final *String REPOSITORY_NAME = "repo1";
>
> *public static **void *main(String[] args) *throws *Exception
> {
> IManagedContainer container = initContainer();
>
> // Start the transport and create a repository
> JVMUtil.getAcceptor(container, "default"); // Start the JVM transport
> CDOServerUtil.addRepository(container, createRepository()); // Start a CDO respository
>
> // Establish a communications connection and open a session with the repository
> IConnector connector = JVMUtil.getConnector(container, "default"); // Open a JVM connection
> CDOSession session = CDOUtil.openSession(connector, REPOSITORY_NAME, *true*);// Open a CDO session
> session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);// Not needed after first commit!!!
>
> // Open a transaction, and create a new resource
> CDOTransaction transaction = session.openTransaction();
> Resource resource = transaction.createResource("/my/big/resource");
> resource.getContents().add(getInputModel());
> transaction.commit();
>
> // Cleanup
> session.close();
> connector.disconnect();
> }
>
> *private static *IManagedContainer initContainer()
> {
> // Turn on tracing
> OMPlatform.INSTANCE.setDebugging(*true*);
> OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
> OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
>
> // Prepare the standalone infra structure (not needed when running inside Eclipse)
> IManagedContainer container = ContainerUtil.createContainer(); // Create a wiring container
> Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
> JVMUtil.prepareContainer(container); // Prepare the JVM transport
> CDOServerUtil.prepareContainer(container); // Prepare the CDO server
> CDOUtil.prepareContainer(container, *false*); // Prepare the CDO client
> *return *container;
> }
>
> *private static *IRepository createRepository() *throws *Exception
> {
> Map<String, String> props = *new *HashMap<String, String>();
> props.put(Props.PROP_SUPPORTING_AUDITS, "false");
> props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
> props.put(Props.PROP_VERIFYING_REVISIONS, "false");
> props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
> props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
> *return *CDOServerUtil.createRepository(REPOSITORY_NAME, createStore(), props);
> }
>
> *private static *IStore createStore() *throws *Exception
> {
> DriverManager.setLogWriter(*new *PrintWriter(System.out));
> Driver driver = *new *com.mysql.jdbc.Driver();
> DriverManager.registerDriver(driver);
> String driverName = driver.getClass().getName();
> String dialectName = MySQLDialect.*class*.getName();
>
> Configuration configuration = *new *Configuration();
> configuration.setProperty(Environment.DRIVER, driverName);
> configuration.setProperty(Environment.URL, "jdbc:mysql://localhost/cdohibernate");
> configuration.setProperty(Environment.USER, "root");
> configuration.setProperty(Environment.DIALECT, dialectName);
> configuration.setProperty(Environment.SHOW_SQL, "true");
> *return new *HibernateStore(configuration);
> }
>
> *private static *EObject getInputModel()
> {
> Category cat1 = Model1Factory.eINSTANCE.createCategory();
> cat1.setName("CAT1");
> Category cat2 = Model1Factory.eINSTANCE.createCategory();
> cat2.setName("CAT2");
> cat1.getCategories().add(cat2);
> Product p1 = Model1Factory.eINSTANCE.createProduct();
> p1.setName("P1");
> cat1.getProducts().add(p1);
> Product p2 = Model1Factory.eINSTANCE.createProduct();
> p2.setName("P2");
> cat1.getProducts().add(p2);
> Product p3 = Model1Factory.eINSTANCE.createProduct();
> p3.setName("P3");
> cat2.getProducts().add(p3);
> *return *cat1;
> }
> }|
>
>
> BTW do you know if you're able/allowed to commit into the CDO CVS??
> From tomorrow on I'll be working in Switzerland. That could have a
> slightly negative impact on my responsiveness. I hope the hotel I chose
> has a good WLAN at least for the evening hours ;-)
>
> Cheers
> /Eike
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> I've started with an initial version of a hbm.xml file in
>>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>>
>>> <?xml version="1.0"?>
>>> <!DOCTYPE hibernate-mapping SYSTEM
>>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>>
>>> <hibernate-mapping
>>> package="org.eclipse.emf.cdo.internal.protocol.model"
>>> default-access="field">
>>>
>>> <class name="CDOPackageImpl" table="cdo_packages">
>>> <property name="packageURI"
>>> column-name="uri"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="ecore"
>>> type="java.sql.Clob"
>>> not-null="false"
>>> lazy="true"/>
>>> <property name="dynamic"
>>> type="boolean"
>>> not-null="true"/>
>>> </class>
>>>
>>> <class name="CDOClassImpl" table="cdo_classes">
>>> <property name="classifierID"
>>> column-name="classifier"
>>> type="int"
>>> not-null="true"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="isAbstract"
>>> column-name="abstract"
>>> type="boolean"
>>> not-null="true"/>
>>> </class>
>>>
>>> <class name="CDOFeatureImpl" table="cdo_features">
>>> <property name="featureID"
>>> column-name="feature"
>>> type="int"
>>> not-null="true"/>
>>> <property name="name"
>>> type="string"
>>> not-null="true"
>>> length="255"/>
>>> <property name="type"
>>> type="int"
>>> not-null="true"/>
>>> <property name="referenceType"
>>> column-name="reftype"
>>> type="string"
>>> not-null="false"/>
>>> <property name="many"
>>> type="boolean"
>>> not-null="true"/>
>>> <property name="containment"
>>> type="boolean"
>>> not-null="false"/>
>>> </class>
>>>
>>> </hibernate-mapping>
>>>
>>>
>>> Open Questions:
>>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>>> which is internally a structure of a long integer (lower bound meta
>>> CDOID) and a normal int (size of the range). I'd like to persist it
>>> as two long values (lower bound and upper bound, both have getters in
>>> CDOIDMetaRange). How is this possible?
>>> - The field CDOFeatureImpl.referenceType has a type of CDOClassProxy
>>> which is internally a structure of a String (package URI) and an int
>>> (classifierID). How should we map this?
>>> - The field CDOClassImpl.superTypes has a type of List<CDOClassProxy>
>>> which works similar to the aforementioned referenceType.
>>> - The three classes have bidi containment associations
>>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>>> know how to map them.
>>>
>>> Regards,
>>> Eike Stepper
>>> ----
>>> http://wiki.eclipse.org/CDO
>>> http://wiki.eclipse.org/Net4j
>>>
>>>
>>> Eike Stepper schrieb:
>>>> To persist/load the meta model I'd like to use Hibernate.
>>>> The following classes must be mapped:
>>>> 1) CDOPackageImpl
>>>> 2) CDOClassImpl
>>>> 3) CDOFeatureImpl
>>>>
>>>> There are also some subclasses of these classes that represent the
>>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>>> instances need not be persisted.
>>>>
>>>> Questions:
>>>> - Do the three classes need to be Serializable and derived
>>>> properties marked transient?
>>>> - Does the usage of JPA annotations require ejb3-persistence.jar to
>>>> be present on the classpath of the protocol plugin (where the three
>>>> classes are located)?
>>>> - To go without the ejb3-persistence.jar could/should I use XML
>>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>
>>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Mapping the Meta Model [message #615381 is a reply to message #111688] |
Sun, 03 February 2008 10:18 |
|
Hi Martin,
I've bcc'ed Nick.
Nick, can we give Martin commit rights for the
/cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugin s/org.eclipse.emf.cdo.server.hibernate
tree?
Have a nice sunday ;-)
/Eike
Martin Taal schrieb:
> Hi Eike,
> Thanks for the example I will try this out. I just tried but I don't
> have commit rights. It would help a bit if I can get commit rights to
> the cdo-hibernate project. I would not be surpised if we would require
> a specific cdo-teneo plugin to override some default teneo mapping
> behavior. For example Teneo adds its own types for handling xsddate
> and enumeration in the mapping file, for cdo this would be cdo
> specific classes.
>
> I will answer your other news post shortly.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal schrieb:
>>> Hi Eike,
>>> A simple way of storing it, is to store the model as a char blob in
>>> a epackage table. This ofcourse only works if you don't need
>>> database access to the individual model elements, as you read most
>>> information in-memory anyway this seems pretty workable.
>> I also thought about this option and it would be really easy. But the
>> current solution also has 2 advantages: The user/admin can better
>> interpret the meta information (including usage for queries) and I
>> can better learn about Hibernate ;-)
>>
>>> If you have an ecore model for the mapping then I can generate a
>>> mapping for you.
>>>
>>> To answer your questions:
>>> I am not sure are CDOIDMetaRange independent classes which are also
>>> referenced from other classes? Same question for CDOClassProxy?
>>> If they are embedded types then they can be mapped like this:
>>> <component name="referenceType"
>>> class="full_class_name_to_CDOClassProxy">
>>> <property name="package URI" lazy="false" insert="true"
>>> update="true" not-null="true" unique="false" type="java.lang.String"/>
>>> <property name="classifierID" lazy="false" insert="true"
>>> update="true" not-null="false" unique="false" type="int"/>
>>> </component>
>>>
>>> A single reference to another type which is also used by other classes:
>>> <many-to-one name="referenceType" class="CDOClassProxy"/>
>>>
>>> Here is an example of how a bidirectional list is mapped for the
>>> library example, note that on the many side the insert and update
>>> attributes both are false. Also because possibly the package-class
>>> relation is containment you should use a cascade of all,
>>> delete-orphan in the list. Instead of using the entity-name you can
>>> also use the class attribute (with the classname);
>>> <list name="books" lazy="true"
>>> cascade="merge,persist,save-update,lock,refresh">
>>> <cache usage="read-write"/>
>>> <key update="true">
>>> <column name="`book_author_e_id`" not-null="false"
>>> unique="false"/>
>>> </key>
>>> <list-index column="`writer_books_idx`"/>
>>> <one-to-many entity-name="Book"/>
>>> </list>
>>>
>>> <many-to-one name="author" entity-name="Writer"
>>> cascade="merge,persist,save-update,lock,refresh"
>>> foreign-key="book_author" lazy="false" insert="false" update="false"
>>> not-null="false">
>>> <column not-null="false" unique="false"
>>> name="`book_author_e_id`"/>
>>> </many-to-one>
>> Thanks for the hints. I'll try them ASAP.
>> In CVS there is now a test class that does all the setup of a
>> standalone client/server with Mysql. It commits a simple model to the
>> repository. It seems to work pretty well until it runs into the first
>> UnsupportedOperationExceptions of the new HibernateStore. Now we can
>> implement one method after the other:
>>
>> |*public class *HibernateTest
>> {
>> *private static final *String REPOSITORY_NAME = "repo1";
>>
>> *public static **void *main(String[] args) *throws *Exception
>> {
>> IManagedContainer container = initContainer();
>>
>> // Start the transport and create a repository
>> JVMUtil.getAcceptor(container, "default"); // Start the JVM
>> transport
>> CDOServerUtil.addRepository(container, createRepository()); //
>> Start a CDO respository
>>
>> // Establish a communications connection and open a session with
>> the repository
>> IConnector connector = JVMUtil.getConnector(container,
>> "default"); // Open a JVM connection
>> CDOSession session = CDOUtil.openSession(connector,
>> REPOSITORY_NAME, *true*);// Open a CDO session
>>
>> session.getPackageRegistry().putEPackage(Model1Package.eINST ANCE);//
>> Not needed after first commit!!!
>>
>> // Open a transaction, and create a new resource
>> CDOTransaction transaction = session.openTransaction();
>> Resource resource = transaction.createResource("/my/big/resource");
>> resource.getContents().add(getInputModel());
>> transaction.commit();
>>
>> // Cleanup
>> session.close();
>> connector.disconnect();
>> }
>>
>> *private static *IManagedContainer initContainer()
>> {
>> // Turn on tracing
>> OMPlatform.INSTANCE.setDebugging(*true*);
>> OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOL E);
>> OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
>>
>> // Prepare the standalone infra structure (not needed when
>> running inside Eclipse)
>> IManagedContainer container = ContainerUtil.createContainer(); //
>> Create a wiring container
>> Net4jUtil.prepareContainer(container); // Prepare the Net4j kernel
>> JVMUtil.prepareContainer(container); // Prepare the JVM transport
>> CDOServerUtil.prepareContainer(container); // Prepare the CDO server
>> CDOUtil.prepareContainer(container, *false*); // Prepare the CDO
>> client
>> *return *container;
>> }
>>
>> *private static *IRepository createRepository() *throws *Exception
>> {
>> Map<String, String> props = *new *HashMap<String, String>();
>> props.put(Props.PROP_SUPPORTING_AUDITS, "false");
>> props.put(Props.PROP_SUPPORTING_REVISION_DELTAS, "true");
>> props.put(Props.PROP_VERIFYING_REVISIONS, "false");
>> props.put(Props.PROP_CURRENT_LRU_CAPACITY, "10000");
>> props.put(Props.PROP_REVISED_LRU_CAPACITY, "10000");
>> *return *CDOServerUtil.createRepository(REPOSITORY_NAME,
>> createStore(), props);
>> }
>>
>> *private static *IStore createStore() *throws *Exception
>> {
>> DriverManager.setLogWriter(*new *PrintWriter(System.out));
>> Driver driver = *new *com.mysql.jdbc.Driver();
>> DriverManager.registerDriver(driver);
>> String driverName = driver.getClass().getName();
>> String dialectName = MySQLDialect.*class*.getName();
>>
>> Configuration configuration = *new *Configuration();
>> configuration.setProperty(Environment.DRIVER, driverName);
>> configuration.setProperty(Environment.URL,
>> "jdbc:mysql://localhost/cdohibernate");
>> configuration.setProperty(Environment.USER, "root");
>> configuration.setProperty(Environment.DIALECT, dialectName);
>> configuration.setProperty(Environment.SHOW_SQL, "true");
>> *return new *HibernateStore(configuration);
>> }
>>
>> *private static *EObject getInputModel()
>> {
>> Category cat1 = Model1Factory.eINSTANCE.createCategory();
>> cat1.setName("CAT1");
>> Category cat2 = Model1Factory.eINSTANCE.createCategory();
>> cat2.setName("CAT2");
>> cat1.getCategories().add(cat2);
>> Product p1 = Model1Factory.eINSTANCE.createProduct();
>> p1.setName("P1");
>> cat1.getProducts().add(p1);
>> Product p2 = Model1Factory.eINSTANCE.createProduct();
>> p2.setName("P2");
>> cat1.getProducts().add(p2);
>> Product p3 = Model1Factory.eINSTANCE.createProduct();
>> p3.setName("P3");
>> cat2.getProducts().add(p3);
>> *return *cat1;
>> }
>> }|
>>
>>
>> BTW do you know if you're able/allowed to commit into the CDO CVS??
>> From tomorrow on I'll be working in Switzerland. That could have a
>> slightly negative impact on my responsiveness. I hope the hotel I
>> chose has a good WLAN at least for the evening hours ;-)
>>
>> Cheers
>> /Eike
>>
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> I've started with an initial version of a hbm.xml file in
>>>> /org.eclipse.emf.cdo.server.hibernate/mappings/meta.hbm.xml:
>>>>
>>>> <?xml version="1.0"?>
>>>> <!DOCTYPE hibernate-mapping SYSTEM
>>>> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
>>>>
>>>> <hibernate-mapping
>>>> package="org.eclipse.emf.cdo.internal.protocol.model"
>>>> default-access="field">
>>>>
>>>> <class name="CDOPackageImpl" table="cdo_packages">
>>>> <property name="packageURI"
>>>> column-name="uri"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="ecore"
>>>> type="java.sql.Clob"
>>>> not-null="false"
>>>> lazy="true"/>
>>>> <property name="dynamic"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> </class>
>>>>
>>>> <class name="CDOClassImpl" table="cdo_classes">
>>>> <property name="classifierID"
>>>> column-name="classifier"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="isAbstract"
>>>> column-name="abstract"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> </class>
>>>>
>>>> <class name="CDOFeatureImpl" table="cdo_features">
>>>> <property name="featureID"
>>>> column-name="feature"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="name"
>>>> type="string"
>>>> not-null="true"
>>>> length="255"/>
>>>> <property name="type"
>>>> type="int"
>>>> not-null="true"/>
>>>> <property name="referenceType"
>>>> column-name="reftype"
>>>> type="string"
>>>> not-null="false"/>
>>>> <property name="many"
>>>> type="boolean"
>>>> not-null="true"/>
>>>> <property name="containment"
>>>> type="boolean"
>>>> not-null="false"/>
>>>> </class>
>>>>
>>>> </hibernate-mapping>
>>>>
>>>>
>>>> Open Questions:
>>>> - The field CDOPackageImpl.metaIDRange has a type of CDOIDMetaRange
>>>> which is internally a structure of a long integer (lower bound meta
>>>> CDOID) and a normal int (size of the range). I'd like to persist it
>>>> as two long values (lower bound and upper bound, both have getters
>>>> in CDOIDMetaRange). How is this possible?
>>>> - The field CDOFeatureImpl.referenceType has a type of
>>>> CDOClassProxy which is internally a structure of a String (package
>>>> URI) and an int (classifierID). How should we map this?
>>>> - The field CDOClassImpl.superTypes has a type of
>>>> List<CDOClassProxy> which works similar to the aforementioned
>>>> referenceType.
>>>> - The three classes have bidi containment associations
>>>> (CDOPackageImpl.classes <--> CDOClassImpl.containingPackage and
>>>> CDOClassImpl.features <--> CDOFeatureImpl.containingClass). I don't
>>>> know how to map them.
>>>>
>>>> Regards,
>>>> Eike Stepper
>>>> ----
>>>> http://wiki.eclipse.org/CDO
>>>> http://wiki.eclipse.org/Net4j
>>>>
>>>>
>>>> Eike Stepper schrieb:
>>>>> To persist/load the meta model I'd like to use Hibernate.
>>>>> The following classes must be mapped:
>>>>> 1) CDOPackageImpl
>>>>> 2) CDOClassImpl
>>>>> 3) CDOFeatureImpl
>>>>>
>>>>> There are also some subclasses of these classes that represent the
>>>>> system packages CDOCorePackage and CDOResourcePackage. Their
>>>>> instances need not be persisted.
>>>>>
>>>>> Questions:
>>>>> - Do the three classes need to be Serializable and derived
>>>>> properties marked transient?
>>>>> - Does the usage of JPA annotations require ejb3-persistence.jar
>>>>> to be present on the classpath of the protocol plugin (where the
>>>>> three classes are located)?
>>>>> - To go without the ejb3-persistence.jar could/should I use XML
>>>>> files directly in the org.eclipse.emf.cdo.server.hibernate plugin?
>>>>>
>>>>> Regards,
>>>>> Eike Stepper
>>>>> ----
>>>>> http://wiki.eclipse.org/CDO
>>>>> http://wiki.eclipse.org/Net4j
>>>>>
>>>
>>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: Hibernate Configuration/SessionFactory/Session/Transaction [message #615383 is a reply to message #111638] |
Sun, 03 February 2008 10:33 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See my comments below.
I will try to spend time this evening on running a first testcase and integrating the teneo mapping
logic.
gr. Martin
Eike Stepper wrote:
> I'm thinking about how to map these Hibernate concepts to the IStore
> concepts. I learned about the following facts (please correct me or add
> comments):
>
> a) A Transaction instance is needed when data is to be written. A
> Transaction can/must be obtained from a Session. Can there be multiple
> concurrent transactions on a single session?
MT>> As far I know this is not possible as at transaction commit the session will be flushed.
Although session flushing can be controlled.
> b) A Session instance is needed when data is to be read or a Transaction
> is to be started. It can/must be obtained from a SessionFactory. Each
> thread must use its own Session instance (cheap creation).
MT>> correct, session is not threadsafe
MT>> I have worked a lot with JBoss Seam lately and there the approach is to have one session per
conversation (which can be multiple requests) and use one transactions per request (actually there
are two one for update and for re-rendering the view).
> c) A SessionFactory can be built out of a Configuration and can't be
> altered after that. Can there be multiple concurrent factories built out
> of a single configuration?
MT>> See answer below
> d) A Configuration instance is used to add/remove mappings and to create
> SessionFactories for these mappings. Can this be done if
> SessionFactories have already been built? An empty Configuration
> instance is created via default ctor.
MT>> One configuration can create multiple sessionfactories. Looking at the hibernate code this
should be possible but the sessionfactory (or its schemaupdate object) has references back to the
configuration. The schemaupdate class is used to update the db schema which is normally done at the
beginning. So as far as I can see one configuration can be used for multiple sf's and it can be
changed in between. However it is neither very difficult to create new configurations.
>
> My idea is the following:
>
> 1) HibernateStore has a Configuration to manage the mappings
> 2) In addition it builds and keeps a SessionFactory which must be
> rebuilt after each modification of the Configuration
MT>> Yes this is also how my example for dynamic emf works, after adding eclasses dynamically the
sessionfactory is rebuild (resulting in a db-schema update)
> 3) If an IStoreReader is requested by the framework, HibernateStore
> creates a new HibernateStoreReader which uses the current SessionFactory
> to open a new Session
MT>> Ok, clear
> 4) If an IStoreWriter is requested by the framework, HibernateStore
> creates a new HibernateStoreWriter (extends the reader and thus already
> has a Session) which uses the Session to begin a new Transaction
MT>> Is this the same session as used by the reader for that client? It is possible to keep a
session open between requests while still opening and closing transactions. This has some advantages
when doing lazy loading but has as disadvantage that the memory-usage grows.
> 5) There are 2 different events that can cause the Configuration to be
> changed:
> 5.1) A client commits a *new* package. This leads to
> IStoreWriter.writePackages() being called. The HibernateStoreWriter
> implementation will persist the packages (so that they can be retrieved
> after restarts, see 5.2) and pass them to HibernateStore (see 1 + 2)
MT>> My experience with relations db's is that schema changes can result in database locks.
Depending on the use case this can be a problem or not ofcourse.
Question: so we can assume that a client always commits a new package before sending instances for
this new epackage over the wire?
> 5.2) A client loads an object with a class that is in an *existing*
> package (which hasn't been loaded before). This leads to
> IStoreReader.readPackage() being called. The HibernateStoreReader will
> read/return the persisted package and also pass it to HibernateStore (se
> 1 + 2)
MT>> Where does the client load the class from?
>
> Open questions:
> - How must 1) + 2) be protected /synchronized in a concurrent server
> environment, i.e. can a new SessionFactory be built/used while "old"
> SessionFactories (based on previous Configuration states) are still in
> use? Or do we have to use proper ReadWriteLocks, which would cause all
> repository access to halt on each change of mappings?
MT>> I would halt further access to the repository.
The update of the db schema can be done separately (before) creating a new sessionfactory. However,
when updating the database schema there are two issues:
1) update of db schema can lead to database locks in the database, or the other way around the
system can't get a database lock and the update fails. This depends on the database I assume.
2) when the database schema is updated and old sessionfactories are still present then they work on
a new schema with an old mapping. This can be a problem.
Would the following scenario be possible:
- when a writepackage is done the cdo server changes to a so-called 'update-schema' mode which means
that no new client requests are accepted.
- the writepackage waits until all current client requests have been completed.
- the writepackage then does its thing and release the cdo server for further connections
> - How should the actual JDBC Connection/DataSource be managed? Is this .
> part of the Hibernate Configuration/SessionFactory/Session? Should we
> pass a DataSource into the HibernateStore which a HibernateStoreReader
> can use to obtain a Connection when it must create its Hibernate Session?
MT>> Yes hibernate does this.
The easiest way is to pass a set of properties to hibernate. These properties can either contain
jdbc parameters or a datasource name.
> - Where do the mappings come from? In 5.1 and 5.2 we have access to a
> CDOPackage which can deliver the XML string of the corresponding
> EPackage. Is this the place where Teneo comes into game?
MT>> Yes that would work fine, as I can use an ecoreresource impl to read those, right?
>
> Regards,
> Eike Stepper
> ----
> http://wiki.eclipse.org/CDO
> http://wiki.eclipse.org/Net4j
>
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: Hibernate Configuration/SessionFactory/Session/Transaction [message #615393 is a reply to message #111707] |
Mon, 04 February 2008 20:32 |
|
Hi Martin,
only short comments below because I'm forced to release the line ;-(
Martin Taal schrieb:
> Hi Eike,
> See my comments below.
>
> I will try to spend time this evening on running a first testcase and
> integrating the teneo mapping logic.
>
> gr. Martin
>
> Eike Stepper wrote:
>> I'm thinking about how to map these Hibernate concepts to the IStore
>> concepts. I learned about the following facts (please correct me or
>> add comments):
>>
>> a) A Transaction instance is needed when data is to be written. A
>> Transaction can/must be obtained from a Session. Can there be multiple
>> concurrent transactions on a single session?
> MT>> As far I know this is not possible as at transaction commit the
> session will be flushed. Although session flushing can be controlled.
that's ok.
>
>> b) A Session instance is needed when data is to be read or a
>> Transaction is to be started. It can/must be obtained from a
>> SessionFactory. Each thread must use its own Session instance (cheap
>> creation).
> MT>> correct, session is not threadsafe
> MT>> I have worked a lot with JBoss Seam lately and there the approach
> is to have one session per conversation (which can be multiple requests)
> and use one transactions per request (actually there are two one for
> update and for re-rendering the view).
>
>> c) A SessionFactory can be built out of a Configuration and can't be
>> altered after that. Can there be multiple concurrent factories built
>> out of a single configuration?
> MT>> See answer below
>> d) A Configuration instance is used to add/remove mappings and to
>> create SessionFactories for these mappings. Can this be done if
>> SessionFactories have already been built? An empty Configuration
>> instance is created via default ctor.
> MT>> One configuration can create multiple sessionfactories. Looking at
> the hibernate code this should be possible but the sessionfactory (or
> its schemaupdate object) has references back to the configuration. The
> schemaupdate class is used to update the db schema which is normally
> done at the beginning. So as far as I can see one configuration can be
> used for multiple sf's and it can be changed in between. However it is
> neither very difficult to create new configurations.
>
>>
>> My idea is the following:
>>
>> 1) HibernateStore has a Configuration to manage the mappings
>> 2) In addition it builds and keeps a SessionFactory which must be
>> rebuilt after each modification of the Configuration
> MT>> Yes this is also how my example for dynamic emf works, after adding
> eclasses dynamically the sessionfactory is rebuild (resulting in a
> db-schema update)
good ;-)
>
>> 3) If an IStoreReader is requested by the framework, HibernateStore
>> creates a new HibernateStoreReader which uses the current
>> SessionFactory to open a new Session
> MT>> Ok, clear
>
>> 4) If an IStoreWriter is requested by the framework, HibernateStore
>> creates a new HibernateStoreWriter (extends the reader and thus
>> already has a Session) which uses the Session to begin a new Transaction
> MT>> Is this the same session as used by the reader for that client?
yes.
> It
> is possible to keep a session open between requests while still opening
> and closing transactions. This has some advantages when doing lazy
> loading but has as disadvantage that the memory-usage grows.
there's another bugzilla pending asking for pooling of IStoreAccessors.
Let's postpone such optimizations until we got a whole commit-disconnect-connect-load cycle working.
>
>> 5) There are 2 different events that can cause the Configuration to be
>> changed:
>> 5.1) A client commits a *new* package. This leads to
>> IStoreWriter.writePackages() being called. The HibernateStoreWriter
>> implementation will persist the packages (so that they can be
>> retrieved after restarts, see 5.2) and pass them to HibernateStore
>> (see 1 + 2)
> MT>> My experience with relations db's is that schema changes can result
> in database locks. Depending on the use case this can be a problem or
> not ofcourse.
>
> Question: so we can assume that a client always commits a new package
> before sending instances for this new epackage over the wire?
yes, the client detects usage of "new" packages and commits them before new instances (see the new protocol between ITransaction and IStoreWriter -> CommitContext).
>
>> 5.2) A client loads an object with a class that is in an *existing*
>> package (which hasn't been loaded before). This leads to
>> IStoreReader.readPackage() being called. The HibernateStoreReader will
>> read/return the persisted package and also pass it to HibernateStore
>> (se 1 + 2)
> MT>> Where does the client load the class from?
The actual java.lang.class (EClass) must be already deployed on the client. If not, a dynamic package is created from the Ecore XML string.
>
>>
>> Open questions:
>> - How must 1) + 2) be protected /synchronized in a concurrent server
>> environment, i.e. can a new SessionFactory be built/used while "old"
>> SessionFactories (based on previous Configuration states) are still in
>> use? Or do we have to use proper ReadWriteLocks, which would cause all
>> repository access to halt on each change of mappings?
> MT>> I would halt further access to the repository.
ok, i'll work on a read/write lock.
>
> The update of the db schema can be done separately (before) creating a
> new sessionfactory. However, when updating the database schema there are
> two issues:
> 1) update of db schema can lead to database locks in the database, or
> the other way around the system can't get a database lock and the update
> fails. This depends on the database I assume.
> 2) when the database schema is updated and old sessionfactories are
> still present then they work on a new schema with an old mapping. This
> can be a problem.
both are arguments for an IStore internal r/w locking.
>
> Would the following scenario be possible:
> - when a writepackage is done the cdo server changes to a so-called
> 'update-schema' mode which means that no new client requests are accepted.
> - the writepackage waits until all current client requests have been
> completed.
> - the writepackage then does its thing and release the cdo server for
> further connections
that's what i'd like to achieve with the r/w lock ;-)
>
>> - How should the actual JDBC Connection/DataSource be managed? Is this .
>> part of the Hibernate Configuration/SessionFactory/Session? Should we
>> pass a DataSource into the HibernateStore which a HibernateStoreReader
>> can use to obtain a Connection when it must create its Hibernate Session?
> MT>> Yes hibernate does this.
> The easiest way is to pass a set of properties to hibernate. These
> properties can either contain jdbc parameters or a datasource name.
yep, the test program already does do this. pleaase feel free to comment on that implementation ;-)
>
>> - Where do the mappings come from? In 5.1 and 5.2 we have access to a
>> CDOPackage which can deliver the XML string of the corresponding
>> EPackage. Is this the place where Teneo comes into game?
> MT>> Yes that would work fine, as I can use an ecoreresource impl to
> read those, right?
i guess. i'll be working on an example...
Cheers
/Eike
>
>
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: Mapping the Meta Model [message #615394 is a reply to message #111702] |
Mon, 04 February 2008 20:36 |
|
Martin Taal schrieb:
> Hi Eike,
> I missed your three questions below. See below.
>
> gr. Martin
>
> Eike Stepper wrote:
>> To persist/load the meta model I'd like to use Hibernate.
>> The following classes must be mapped:
>> 1) CDOPackageImpl
>> 2) CDOClassImpl
>> 3) CDOFeatureImpl
>>
>> There are also some subclasses of these classes that represent the
>> system packages CDOCorePackage and CDOResourcePackage. Their instances
>> need not be persisted.
>>
>> Questions:
>> - Do the three classes need to be Serializable and derived properties
>> marked transient?
> MT>> only the properties present in the mapping will be persisted, so
> denoting transient won't be required.
ok.
>> - Does the usage of JPA annotations require ejb3-persistence.jar to be
>> present on the classpath of the protocol plugin (where the three
>> classes are located)?
> MT>> not jpa annotations as teneo uses it, these annotations are placed
> in the model or in a separate xml file there is no binary dependency
> with the ejb3-persistence.jar
>> - To go without the ejb3-persistence.jar could/should I use XML files
>> directly in the org.eclipse.emf.cdo.server.hibernate plugin?
> MT>> yes, when using the hibernate mapping you don't need the
> ejb3-persistence.jar or hibernate-annotations or hibernate-entitymanager.
> The hbm mapping logic has more possibilities than the jpa annotations
> and as far as I can see Hibernate will continue to support the hbm
> approach. The hibernate jpa/entitymanager is in many ways a smaller
> layer over the current hibernate product.
i think the current approach with a separate hbm.xml file in the cdo.server.hibernate plugin is good. let's stay with that one. i'm still hoping that you will try to complete these mappings ;-) if you need help/explanation about the used types - i'm here.
Cheers
/Eike
>
>>
>> Regards,
>> Eike Stepper
>> ----
>> http://wiki.eclipse.org/CDO
>> http://wiki.eclipse.org/Net4j
>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | |
Re: [CDO] Teneo/Hibernate integration [message #615446 is a reply to message #111894] |
Thu, 07 February 2008 19:25 |
|
Hi Thomas, Martin,
The CDO server is really agnostic about EMF at all. Theoretically it could be used to serve clients with other modeling frameworks as well. This independence of client side frameworks is one reason. Another reason is that the server is much more dynamic if it doesn't require generated models to be deployed at both sides. A third reason is htat a CDO repository is completely self contained, it doesn't have any dependencies from stored model data to deployed model code. This way a repository can't be corrupted by taking away packages from the server installation although there are still instances in the store that refer to these packages.
Thomas, I can't understand why you don't like this design. From a client perspective this is completely transparent. Can you elaborate on your use cases where the above behaviour leads to problems?
Cheers
/Eike
Martin Taal schrieb:
> Hi Thomas,
> The emf model is present on the server but it is normally not used by
> the CDO-server. The cdopackage has a member which contains the ecore
> model as a string. Teneo can be initialized using this ecore-string (and
> a separate annotations/property file).
>
> Eike can give a better answer on why the client passes the model.
> From my side I think it could also be possible to initialize the cdo
> server based on server side information (like an emf model in a ecore
> file).
>
> gr. Martin
>
> Thomas wrote:
>> Hello Eike & Martin,
>>
>> I tried to follow, but not everything I read is clear to me.
>> If the server doesnt know the EMF model (does he ???) how do you map
>> the classes ?
>>
>> What I dont like about CDO (if I misunderstand correct me) is that the
>> model is registered at the server from the client side. Dont
>> understand why its done this way. When I set up a server he surely can
>> know about the model I have.
>>
>> Thomas
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615450 is a reply to message #111896] |
Fri, 08 February 2008 09:29 |
Thomas Messages: 151 Registered: July 2009 |
Senior Member |
|
|
HI,
ok I understand now what I already suspected.
Following scenario: Its all about the server setup. When I setup my
server, I have (for now) some groovy scripts that populate the database
with required initial data. So the server starts up first time hibernate
initializes the database (create-update), the scripts run and populate
the database. After that the server starts to accept connections from
the clients as they need the initial data in the db.
I think I could have a setup with a "special" setup client that is only
for initializing the db. so for server initialization one would have to
run the setup client once. That would be acceptable.
What I still really wonder about (please tell me about the magic:) is
how cdo werver maps to hibernate pojos if he doesnt know the model
classes. I would expect that the teneo mapping is for the emf classes
but if server doesnt now, to what classes goes the mapping ?
I will take some time thinking before I start on that.
I will ask more questions about net4j later, as I do some other things
than model persistence with my server :)
So long
Thomas
Eike Stepper schrieb:
> Hi Thomas, Martin,
>
> The CDO server is really agnostic about EMF at all. Theoretically it
> could be used to serve clients with other modeling frameworks as well.
> This independence of client side frameworks is one reason. Another
> reason is that the server is much more dynamic if it doesn't require
> generated models to be deployed at both sides. A third reason is htat a
> CDO repository is completely self contained, it doesn't have any
> dependencies from stored model data to deployed model code. This way a
> repository can't be corrupted by taking away packages from the server
> installation although there are still instances in the store that refer
> to these packages.
>
> Thomas, I can't understand why you don't like this design. From a client
> perspective this is completely transparent. Can you elaborate on your
> use cases where the above behaviour leads to problems?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Thomas,
>> The emf model is present on the server but it is normally not used by
>> the CDO-server. The cdopackage has a member which contains the ecore
>> model as a string. Teneo can be initialized using this ecore-string
>> (and a separate annotations/property file).
>>
>> Eike can give a better answer on why the client passes the model.
>> From my side I think it could also be possible to initialize the cdo
>> server based on server side information (like an emf model in a ecore
>> file).
>>
>> gr. Martin
>>
>> Thomas wrote:
>>> Hello Eike & Martin,
>>>
>>> I tried to follow, but not everything I read is clear to me.
>>> If the server doesnt know the EMF model (does he ???) how do you map
>>> the classes ?
>>>
>>> What I dont like about CDO (if I misunderstand correct me) is that
>>> the model is registered at the server from the client side. Dont
>>> understand why its done this way. When I set up a server he surely
>>> can know about the model I have.
>>>
>>> Thomas
>>
>>
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615452 is a reply to message #111900] |
Fri, 08 February 2008 10:26 |
|
Hi Thomas,
Yes, I think you got it ;-)
If you need initial population of a repository I'd suggest that you deploy
the CDO client plugins to the server as well (without UI) and the Net4j
JVM transport plugins.
Then you can write code as the following (not tested since I've got no
installation here):
// Start a JVM acceptor
IPluginContainer.INSTANCE.getElement("org.eclipse.net4j.acceptors ", "jvm",
"default");
// Open a CDO session via a JVM connector
CDOSession session = CDOUtil.openSession(IPluginContainer.INSTANCE,
"jvm://default/repo1", true);
// Now open a transaction on the session and commit packages and
resources/objects
// Eventually deactivate the JVM connector and/or the JVM connector
---
WRT hibernate mapping on the CDO server:
It's not finished yet! But we plan to use own EntityTuplizers that realize
the mapping of CDORevisions directly. No EClasses needed. The benefits are
better performance and we don't loose the disconnected object graph
characteristics of CDO (CDORevisions don't have java references onto each
other).
Let's see if we manage ;-)
Cheers
/Eike
Thomas wrote:
> HI,
> ok I understand now what I already suspected.
> Following scenario: Its all about the server setup. When I setup my
> server, I have (for now) some groovy scripts that populate the database
> with required initial data. So the server starts up first time hibernate
> initializes the database (create-update), the scripts run and populate
> the database. After that the server starts to accept connections from
> the clients as they need the initial data in the db.
> I think I could have a setup with a "special" setup client that is only
> for initializing the db. so for server initialization one would have to
> run the setup client once. That would be acceptable.
> What I still really wonder about (please tell me about the magic:) is
> how cdo werver maps to hibernate pojos if he doesnt know the model
> classes. I would expect that the teneo mapping is for the emf classes
> but if server doesnt now, to what classes goes the mapping ?
> I will take some time thinking before I start on that.
> I will ask more questions about net4j later, as I do some other things
> than model persistence with my server :)
> So long
> Thomas
> Eike Stepper schrieb:
>> Hi Thomas, Martin,
>>
>> The CDO server is really agnostic about EMF at all. Theoretically it
>> could be used to serve clients with other modeling frameworks as well.
>> This independence of client side frameworks is one reason. Another
>> reason is that the server is much more dynamic if it doesn't require
>> generated models to be deployed at both sides. A third reason is htat a
>> CDO repository is completely self contained, it doesn't have any
>> dependencies from stored model data to deployed model code. This way a
>> repository can't be corrupted by taking away packages from the server
>> installation although there are still instances in the store that refer
>> to these packages.
>>
>> Thomas, I can't understand why you don't like this design. From a client
>> perspective this is completely transparent. Can you elaborate on your
>> use cases where the above behaviour leads to problems?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Thomas,
>>> The emf model is present on the server but it is normally not used by
>>> the CDO-server. The cdopackage has a member which contains the ecore
>>> model as a string. Teneo can be initialized using this ecore-string
>>> (and a separate annotations/property file).
>>>
>>> Eike can give a better answer on why the client passes the model.
>>> From my side I think it could also be possible to initialize the cdo
>>> server based on server side information (like an emf model in a ecore
>>> file).
>>>
>>> gr. Martin
>>>
>>> Thomas wrote:
>>>> Hello Eike & Martin,
>>>>
>>>> I tried to follow, but not everything I read is clear to me.
>>>> If the server doesnt know the EMF model (does he ???) how do you map
>>>> the classes ?
>>>>
>>>> What I dont like about CDO (if I misunderstand correct me) is that
>>>> the model is registered at the server from the client side. Dont
>>>> understand why its done this way. When I set up a server he surely
>>>> can know about the model I have.
>>>>
>>>> Thomas
>>>
>>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [CDO] Teneo/Hibernate integration [message #615457 is a reply to message #111904] |
Fri, 08 February 2008 12:32 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Thomas,
Teneo uses both the pojo mode and the map mode. For more info on map mode see the chapter on Dynamic
models in the hibernate manual. Teneo will automatically decide if it uses pojo or map mode, so if
there is an instance class available for an EClass then it will use pojo mode for that EClass. If
there is no instance class available (like in the cdo-server) then it will use map mode.
The advantage of using pojo mode is that it allows hibernate proxying, the advantage of map mode is
its flexibility in determining at runtime which implementation class to use. For example in map mode
it is perfectly possible to persist a CDORevision in for example a table for customer orders or
products.
To handle a specific implementation class (like CDORevision) there are also some other details (like
hibernate propertyaccessors) which need to be implemented but that's very doable.
Using map mode, it is just possible to do any query as with pojo mode. So on the cdo server the
query from Value would return CDORevision objects which have an eclass (or actually cdoclass) with
the name Value, the CDORevision object contains all attributes (and their values) of a Value type
(as defined in the model).
gr. Martin
Thomas wrote:
> > WRT hibernate mapping on the CDO server:
> > It's not finished yet! But we plan to use own EntityTuplizers that
> > realize the mapping of CDORevisions directly. No EClasses needed. The
> > benefits are better performance and we don't loose the disconnected
> > object graph characteristics of CDO (CDORevisions don't have java
> > references onto each other).
> >
> > Let's see if we manage ;-)
>
> HI Eike,
>
> I still dont really understand. I expect that a hibernate mapping goes
> for a pojo. I just want to understand whats going on there, but I dont
> have a concept of CDORevision. Wheres the magic there ? and how is it
> then ehwn I issue a query on hibernate "FROM Value..." how is that
> transformed when the server doesnt know Value at all ?
>
> So long & thx for your patience
> Thomas
--
With Regards, Martin Taal
Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
|
|
|
Re: [CDO] Teneo/Hibernate integration [message #615458 is a reply to message #111904] |
Fri, 08 February 2008 12:32 |
|
Thomas wrote:
> > WRT hibernate mapping on the CDO server:
> > It's not finished yet! But we plan to use own EntityTuplizers that
> > realize the mapping of CDORevisions directly. No EClasses needed. The
> > benefits are better performance and we don't loose the disconnected
> > object graph characteristics of CDO (CDORevisions don't have java
> > references onto each other).
> >
> > Let's see if we manage ;-)
> HI Eike,
> I still dont really understand. I expect that a hibernate mapping goes
> for a pojo.
Wrong, this seems to be the Hibernate default, but there's for example
also a DynamicMap mode. In general Hibernate can map arbitrary structures
of data by abstracting model access to Tuplizers. The CDO HibernateStore
will implement its own Tuplizers to let Hibernate access CDORevisions.
> I just want to understand whats going on there, but I dont
> have a concept of CDORevision. Wheres the magic there ?
No magic. A CDORevision captures an immutable state of an object at a
specified period. It works similar to a DynamicEObject but without
actually depending on Ecore. The most important difference is that
references to other objects are not encoded through java references but
rather through CDOIDs which can be resolved to target CDORevisions by a
CDORevisionResolver. CDORevision also acts as a sort of an efficient
transfer object. I guess it's best to dive a bit into the code ;-)
> and how is it
> then ehwn I issue a query on hibernate "FROM Value..." how is that
> transformed when the server doesnt know Value at all ?
It's not true that the server doesn't know Value at all. It knoes
everything about Value (and about any other class that has been committed
into a repository) that it needs to persist and load instances of Value.
It's just that this knowledge does not necessarily need to be expressed in
terms of Ecore concepts (types). For various reasons (most of them
explained in a previous answer) a CDO server uses own concepts for this
purpose. This is particularly true for the repository implementation and
for all existing store implementations. It is probably not true for the
new HibernateStore implementation which will recreate the original
EPackage from string data in a CDOPackage just to be able to reuse mapping
creation code that Martin developed in the context of his Teneo project.
The actual mapping of instances will be done by Hibernate without
dependencies on Ecore again.
M;artin, please correct me if I got something wrong ;-)
Cheers
/Eike
> So long & thx for your patience
> Thomas
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [CDO] Teneo/Hibernate integration [message #615473 is a reply to message #111917] |
Sat, 09 February 2008 08:20 |
|
This is a multi-part message in MIME format.
--------------090204060805000606000406
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Thomas schrieb:
> Thanks Eike & Martin.
>
> I simply didnt know about map mode. I will have a look at this.
>
> Is there any documentation on net4j ? I want to learn more about it :)
Not much I fear ;-( The bast is to start with the JavaDoc for IConnector.
The basic concepts are IBuffer, IChannel, IProtocol as well as
IConnector and IAcceptor:
- IBuffers (the meaning should be clear) are transmitted through virtual
IChannels and received through IBufferHandlers of the peer channel
instances.
- IConnectors represent the endpoints of a physical connection (for
example sockets) and multiplex arbitrary numbers of IChannels through
this connection. In fact a Connector is an IConnector and an
IChannelMultiplexer.
- IAcceptors accept connections at the server side (of that connection)
and create IConnectors of ConnectorLocation.SERVER.
- IProtocols are basically named IBufferHandlers but make their
association with server-side IChannels much easier through the use of
registered IProtocolFactoies.
Since direct (and asynchronous) handling of buffers is fast but
inconvenient for many application needs there is an important
implementation of IProtocol. A SignalProtocol, together with the Signals
it defines, forms a layer on top of the basic concepts and provides a
framework that you can use to decompose your communication needs into
single Signals, each representing a single manifestation (a
communications case) of the client/server paradigm: request -->
indication --> response --> confirmation
For each such communications case the application has to provide 2
classes that implement the client-side and the server-side respectively:
|*public abstract class *RequestWithConfirmation<RESULT> *extends *SignalActor<RESULT>
{
*protected abstract **void *requesting(ExtendedDataOutputStream out) *throws *IOException;
*protected abstract *RESULT confirming(ExtendedDataInputStream in) *throws *IOException;
}|
|*public abstract class *IndicationWithResponse *extends *SignalReactor
{
*protected abstract **void *indicating(ExtendedDataInputStream in) *throws *IOException;
*protected abstract **void *responding(ExtendedDataOutputStream out) *throws *IOException;
}|
Notice that the implementor of thhese methods can use streams to write
data to and read it from. The SignalProtocol framework takes care of
cutting these streams into sequences of buffers which are multiplexed
through the underlying channel and demultiplexed into streams again at
the peer side. The framework also takes care of signal creation and all
threading issues. The CDO protocol is an example of such a
SignalProtocol. Other examples are the experimental JMS provider and a
simple but extensible collaboration platform (see buddies and chat).
Here are some snippets from the BuddiesServerProtocol:
|*public class *BuddiesServerProtocol *extends *SignalProtocol
{
*public *String getType()
{
*return *ProtocolConstants.PROTOCOL_NAME;
}
@Override
*protected *SignalReactor doCreateSignalReactor(*short *signalID)
{
*switch *(signalID)
{
*case *ProtocolConstants.SIGNAL_OPEN_SESSION:
*return new *OpenSessionIndication();
*case *ProtocolConstants.SIGNAL_BUDDY_STATE:
*return new *ServerBuddyStateIndication();
*case *ProtocolConstants.SIGNAL_INSTALL_FACILITY:
*return new *InstallFacilityIndication();
*case *ProtocolConstants.SIGNAL_INITIATE_COLLABORATION:
*return new *InitiateCollaborationIndication();
*case *ProtocolConstants.SIGNAL_INVITE_BUDDIES:
*return new *InviteBuddiesIndication();
*case *ProtocolConstants.SIGNAL_COLLABORATION_LEFT:
*return new *ServerCollaborationLeftIndication();
*case *ProtocolConstants.SIGNAL_MESSAGE:
*return new *MessageIndication(IBuddyAdmin.INSTANCE);
}
*return null*;
}
}|
|*public class *InstallFacilityIndication *extends *IndicationWithResponse
{
*private **boolean *success;
@Override
*protected **short *getSignalID()
{
*return *ProtocolConstants.SIGNAL_INSTALL_FACILITY;
}
@Override
*protected **void *indicating(ExtendedDataInputStream in) *throws *IOException
{
*long *collaborationID = in.readLong();
String facilityType = in.readString();
*try*
{
String description = String.valueOf(collaborationID);
IFacility facility = (IFacility)IPluginContainer.INSTANCE.getElement(FACILITY_GRO UP, facilityType, description);
Collaboration collaboration = (Collaboration)BuddyAdmin.INSTANCE.getCollaboration(collabor ationID);
*if *(collaboration != *null*)
{
facility.setCollaboration(collaboration);
collaboration.addFacility(facility, *true*);
ISession session = (ISession)getProtocol().getInfraStructure();
IBuddy initiator = session.getSelf();
*for *(IBuddy buddy : collaboration.getBuddies())
{
*if *(buddy != initiator)
{
*try*
{
IChannel channel = buddy.getSession().getChannel();
*new *FacilityInstalledNotification(channel, collaborationID, facilityType).send();
}
*catch *(Exception ex)
{
OM.LOG.error(ex);
}
}
}
success = *true*;
}
}
*catch *(RuntimeException ex)
{
OM.LOG.error(ex);
}
}
@Override
*protected **void *responding(ExtendedDataOutputStream out) *throws *IOException
{
out.writeBoolean(success);
}
}|
I hope this makes it a bit easier to start. Further questions are
welcome, doc/tutorial contributions as well ;-)
Enjoy your weekend
/Eike
>
> Regards Thomas
>
> Eike Stepper schrieb:
>> Thomas wrote:
>>
>>> > WRT hibernate mapping on the CDO server:
>>> > It's not finished yet! But we plan to use own EntityTuplizers that
>>> > realize the mapping of CDORevisions directly. No EClasses needed.
>>> The
>>> > benefits are better performance and we don't loose the disconnected
>>> > object graph characteristics of CDO (CDORevisions don't have java
>>> > references onto each other).
>>> >
>>> > Let's see if we manage ;-)
>>
>>> HI Eike,
>>
>>> I still dont really understand. I expect that a hibernate mapping
>>> goes for a pojo.
>> Wrong, this seems to be the Hibernate default, but there's for
>> example also a DynamicMap mode. In general Hibernate can map
>> arbitrary structures of data by abstracting model access to
>> Tuplizers. The CDO HibernateStore will implement its own Tuplizers to
>> let Hibernate access CDORevisions.
>>
>>> I just want to understand whats going on there, but I dont have a
>>> concept of CDORevision. Wheres the magic there ?
>> No magic. A CDORevision captures an immutable state of an object at a
>> specified period. It works similar to a DynamicEObject but without
>> actually depending on Ecore. The most important difference is that
>> references to other objects are not encoded through java references
>> but rather through CDOIDs which can be resolved to target
>> CDORevisions by a CDORevisionResolver. CDORevision also acts as a
>> sort of an efficient transfer object. I guess it's best to dive a bit
>> into the code ;-)
>>
>>> and how is it then ehwn I issue a query on hibernate "FROM Value..."
>>> how is that transformed when the server doesnt know Value at all ?
>> It's not true that the server doesn't know Value at all. It knoes
>> everything about Value (and about any other class that has been
>> committed into a repository) that it needs to persist and load
>> instances of Value. It's just that this knowledge does not
>> necessarily need to be expressed in terms of Ecore concepts (types).
>> For various reasons (most of them explained in a previous answer) a
>> CDO server uses own concepts for this purpose. This is particularly
>> true for the repository implementation and for all existing store
>> implementations. It is probably not true for the new HibernateStore
>> implementation which will recreate the original EPackage from string
>> data in a CDOPackage just to be able to reuse mapping creation code
>> that Martin developed in the context of his Teneo project. The actual
>> mapping of instances will be done by Hibernate without dependencies
>> on Ecore again.
>>
>> M;artin, please correct me if I got something wrong ;-)
>>
>> Cheers
>> /Eike
>>
>>
>>> So long & thx for your patience
>>> Thomas
>>
>>
--------------090204060805000606000406
Content-Type: multipart/related;
boundary="------------020504000202060005020609"
--------------020504000202060005020609
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Thomas schrieb:
<blockquote cite="mid:fohv5n$5nd$1@build.eclipse.org" type="cite">Thanks
Eike & Martin.
<br>
<br>
I simply didnt know about map mode. I will have a look at this.
<br>
<br>
Is there any documentation on net4j ? I want to learn more about it :)
<br>
</blockquote>
Not much I fear ;-( The bast is to start with the JavaDoc for
IConnector.<br>
<br>
The basic concepts are IBuffer, IChannel, IProtocol as well as
IConnector and IAcceptor:<br>
- IBuffers (the meaning should be clear) are transmitted through
virtual IChannels and received through IBufferHandlers of the peer
channel instances. <br>
- IConnectors represent the endpoints of a physical connection (for
example sockets) and multiplex arbitrary numbers of IChannels through
this connection. In fact a Connector is an IConnector and an
IChannelMultiplexer. <br>
- IAcceptors accept connections at the server side (of that connection)
and create IConnectors of ConnectorLocation.SERVER. <br>
- IProtocols are basically named IBufferHandlers but make their
association with server-side IChannels much easier through the use of
registered IProtocolFactoies.<br>
<br>
<img src="cid:part1.09070102.02060400@sympedia.de" alt=""><br>
<br>
Since direct (and asynchronous) handling of buffers is fast but
inconvenient for many application needs there is an important
implementation of IProtocol. A SignalProtocol, together with the
Signals it defines, forms a layer on top of the basic concepts and
provides a framework that you can use to decompose your communication
needs into single Signals, each representing a single manifestation (a
communications case) of the client/server paradigm: request -->
indication --> response --> confirmation<br>
<br>
<img src="cid:part2.07030202.09070306@sympedia.de" alt=""><br>
<br>
For each such communications case the application has to provide 2
classes that implement the client-side and the server-side respectively:<br>
<br>
<title></title>
<style type="text/css">
<!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
</style>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<!-- ======================================================== -->
<!-- = Java Sourcecode to HTML automatically converted code = --><!-- = Java2Html Converter 5.0 [2006-02-26] by Markus Gebhard markus@jave.de = -->
<!-- = Further information: http://www.java2html.de = -->
<div class="java" align="left">
<table bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<!-- start source code --> <td align="left" bgcolor="#ffffcc"
nowrap="nowrap" valign="top"> <code><font color="#7f0055"><b>public
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Goto Forum:
Current Time: Sun Dec 08 19:00:13 GMT 2024
Powered by FUDForum. Page generated in 0.13324 seconds
|