Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc) » [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-side (CUSTOM data type prob
[Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-side (CUSTOM data type prob [message #119924] |
Thu, 24 April 2008 17:50 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi Martin, Eike,
I want to solve a problem I have with custom CDO types. To summarize
my problem, I have an EMF type with an attribute of type byte[] and
using Teneo's annotation, I've mapped it to a binary blob. When the
CDOPropertyGetter returns the value, it is returning a String and this
is causing a ClassCastException. So to fix this problem, I'd like to do
the following:
In CDOPropertyGetter:
public Object get(Object target) throws HibernateException
{
InternalCDORevision revision = (InternalCDORevision)target;
Object value = revision.getValue(getCDOFeature());
if(getCDOFeature().getType() == CDOType.CUSTOM)
return EcoreUtil.convertFromString(..., value);
return value;
}
where ... would be replaced by the EMF data type.
Another solution would be to create a CDOCustomPropertyGetter and have
the CDORevisionTuplizer instantiate it by passing it the concrete EMF
data type and this CDOCustomPropertyGetter would do the conversion.
This solution would remove the if statement from my code above.
Anyhow, there is no unique solution to this problem, but they all
require access to the original EMF type... How can I get it?
Thanks,
Eric
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #119978 is a reply to message #119924] |
Fri, 25 April 2008 08:01 |
|
Hi Eric, Martin,
Having read your message I now see a more basic issue with custom
EDataTypes. As you know, CDO itself does not require EMF and your
generated models to be deployed at the server side. The new Hibernate
integration layer (HibernateStore implementation) adds a server-side
dependency on EMF but not on your generated models. The HibernateStore
uses the serialized xml string of your client-side model to recreate the
EPackage instances. WRT the custom EDataTypes there is a good chance that
the dynamic package at the server side behaves quite different from the
generated one. IIRC the serialization of custom EDataTypes relies on
manually written code in the otherwise generated model and the respective
deserialization code will not be present on the server ;-( Not to mention
the potentially non-standard instance classes that you used on client side.
If I'm right, I only see that the generated models, along with all their
dependencies, have to be deployed to the server as well. And we will have
to make sure that the server side EPackage.Registry.INSTANCE is consulted
before we attempt to deserialize the needed EPackages from the xml string
in the db.
What do you think?
Cheers
/Eike
Eric wrote:
> Hi Martin, Eike,
> I want to solve a problem I have with custom CDO types. To summarize
> my problem, I have an EMF type with an attribute of type byte[] and
> using Teneo's annotation, I've mapped it to a binary blob. When the
> CDOPropertyGetter returns the value, it is returning a String and this
> is causing a ClassCastException. So to fix this problem, I'd like to do
> the following:
> In CDOPropertyGetter:
> public Object get(Object target) throws HibernateException
> {
> InternalCDORevision revision = (InternalCDORevision)target;
> Object value = revision.getValue(getCDOFeature());
> if(getCDOFeature().getType() == CDOType.CUSTOM)
> return EcoreUtil.convertFromString(..., value);
> return value;
> }
> where ... would be replaced by the EMF data type.
> Another solution would be to create a CDOCustomPropertyGetter and have
> the CDORevisionTuplizer instantiate it by passing it the concrete EMF
> data type and this CDOCustomPropertyGetter would do the conversion.
> This solution would remove the if statement from my code above.
> Anyhow, there is no unique solution to this problem, but they all
> require access to the original EMF type... How can I get it?
> Thanks,
> Eric
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120072 is a reply to message #119978] |
Fri, 25 April 2008 13:12 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi Eike, Martin,
I did not see that one coming (custom Java code for serialization)...
If this is the case and you want to recreate the "original" type on
server-side, you might not have any other choice than have a model
dependency. :(
That having been said, maybe we don't need to have the EMF type on the
server. Maybe I'm missing the big picture here, but in my case I was
trying to recreate the EMF type in order to store this attribute using
Teneo's original mapping (store a byte[] as a binary blob instead of a
String). Since CDO's internal representation of a custom type is a
String, as long as I'm accessing it through CDO, I shouldn't care how it
is stored in the database. So Teneo could detect (when using CDO only)
that the attribute you are trying to persist is in fact a custom type
and should generate a "String" representation for the mapping file.
This is not fixing the issue where server-side code would like to see
the EMF type, but if I get this right, it should never be the case?!?
Would there be any other benefits if we have access to the model on
server-side? Is it worthwhile?
Any thoughts?
Eric
Eike Stepper wrote:
> Hi Eric, Martin,
>
> Having read your message I now see a more basic issue with custom
> EDataTypes. As you know, CDO itself does not require EMF and your
> generated models to be deployed at the server side. The new Hibernate
> integration layer (HibernateStore implementation) adds a server-side
> dependency on EMF but not on your generated models. The HibernateStore
> uses the serialized xml string of your client-side model to recreate the
> EPackage instances. WRT the custom EDataTypes there is a good chance
> that the dynamic package at the server side behaves quite different from
> the generated one. IIRC the serialization of custom EDataTypes relies on
> manually written code in the otherwise generated model and the
> respective deserialization code will not be present on the server ;-(
> Not to mention the potentially non-standard instance classes that you
> used on client side.
>
> If I'm right, I only see that the generated models, along with all their
> dependencies, have to be deployed to the server as well. And we will
> have to make sure that the server side EPackage.Registry.INSTANCE is
> consulted before we attempt to deserialize the needed EPackages from the
> xml string in the db.
>
> What do you think?
>
> Cheers
> /Eike
>
>
>
> Eric wrote:
>
>> Hi Martin, Eike,
>
>> I want to solve a problem I have with custom CDO types. To
>> summarize my problem, I have an EMF type with an attribute of type
>> byte[] and using Teneo's annotation, I've mapped it to a binary blob.
>> When the CDOPropertyGetter returns the value, it is returning a String
>> and this is causing a ClassCastException. So to fix this problem, I'd
>> like to do the following:
>
>> In CDOPropertyGetter:
>> public Object get(Object target) throws HibernateException
>> {
>> InternalCDORevision revision = (InternalCDORevision)target;
>> Object value = revision.getValue(getCDOFeature());
>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>> return EcoreUtil.convertFromString(..., value);
>> return value;
>> }
>
>> where ... would be replaced by the EMF data type.
>
>> Another solution would be to create a CDOCustomPropertyGetter and have
>> the CDORevisionTuplizer instantiate it by passing it the concrete EMF
>> data type and this CDOCustomPropertyGetter would do the conversion.
>> This solution would remove the if statement from my code above.
>
>> Anyhow, there is no unique solution to this problem, but they all
>> require access to the original EMF type... How can I get it?
>
>> Thanks,
>> Eric
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120083 is a reply to message #120072] |
Fri, 25 April 2008 13:26 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi All,
I think only for primitive types (byte, string, etc.) and their string representations there is no
need for extra server side code. For anything more special, for example a rgb color object then at
server side some client-specific code needs to be installed also, otherwise Teneo/hibernate does not
know how to instantiate a usertype.
Take the example of storing a colour object in 3 int columns. This requires a specific hibernate
usertype which can translate a colour type to these three columns. This usertype is a custom class
which needs to be stored at the server.
Also the custom colour class needs to be added to the server environment, or otherwise how can cdo
handle it? Eike how would the colour instance be passed over the wire, serialized?
gr. Martin
Eric wrote:
> Hi Eike, Martin,
>
> I did not see that one coming (custom Java code for
> serialization)... If this is the case and you want to recreate the
> "original" type on server-side, you might not have any other choice than
> have a model dependency. :(
>
> That having been said, maybe we don't need to have the EMF type on
> the server. Maybe I'm missing the big picture here, but in my case I
> was trying to recreate the EMF type in order to store this attribute
> using Teneo's original mapping (store a byte[] as a binary blob instead
> of a String). Since CDO's internal representation of a custom type is a
> String, as long as I'm accessing it through CDO, I shouldn't care how it
> is stored in the database. So Teneo could detect (when using CDO only)
> that the attribute you are trying to persist is in fact a custom type
> and should generate a "String" representation for the mapping file. This
> is not fixing the issue where server-side code would like to see the EMF
> type, but if I get this right, it should never be the case?!?
>
> Would there be any other benefits if we have access to the model on
> server-side? Is it worthwhile?
>
> Any thoughts?
>
> Eric
>
> Eike Stepper wrote:
>> Hi Eric, Martin,
>>
>> Having read your message I now see a more basic issue with custom
>> EDataTypes. As you know, CDO itself does not require EMF and your
>> generated models to be deployed at the server side. The new Hibernate
>> integration layer (HibernateStore implementation) adds a server-side
>> dependency on EMF but not on your generated models. The HibernateStore
>> uses the serialized xml string of your client-side model to recreate
>> the EPackage instances. WRT the custom EDataTypes there is a good
>> chance that the dynamic package at the server side behaves quite
>> different from the generated one. IIRC the serialization of custom
>> EDataTypes relies on manually written code in the otherwise generated
>> model and the respective deserialization code will not be present on
>> the server ;-( Not to mention the potentially non-standard instance
>> classes that you used on client side.
>>
>> If I'm right, I only see that the generated models, along with all
>> their dependencies, have to be deployed to the server as well. And we
>> will have to make sure that the server side EPackage.Registry.INSTANCE
>> is consulted before we attempt to deserialize the needed EPackages
>> from the xml string in the db.
>>
>> What do you think?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Eric wrote:
>>
>>> Hi Martin, Eike,
>>
>>> I want to solve a problem I have with custom CDO types. To
>>> summarize my problem, I have an EMF type with an attribute of type
>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>> blob. When the CDOPropertyGetter returns the value, it is returning
>>> a String and this is causing a ClassCastException. So to fix this
>>> problem, I'd like to do the following:
>>
>>> In CDOPropertyGetter:
>>> public Object get(Object target) throws HibernateException
>>> {
>>> InternalCDORevision revision = (InternalCDORevision)target;
>>> Object value = revision.getValue(getCDOFeature());
>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>> return EcoreUtil.convertFromString(..., value);
>>> return value;
>>> }
>>
>>> where ... would be replaced by the EMF data type.
>>
>>> Another solution would be to create a CDOCustomPropertyGetter and
>>> have the CDORevisionTuplizer instantiate it by passing it the
>>> concrete EMF data type and this CDOCustomPropertyGetter would do the
>>> conversion. This solution would remove the if statement from my code
>>> above.
>>
>>> Anyhow, there is no unique solution to this problem, but they all
>>> require access to the original EMF type... How can I get it?
>>
>>> Thanks,
>>> Eric
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120095 is a reply to message #120083] |
Fri, 25 April 2008 14:35 |
|
Martin Taal wrote:
> Hi All,
> I think only for primitive types (byte, string, etc.) and their string
representations there is no
> need for extra server side code. For anything more special, for example a
rgb color object then at
> server side some client-specific code needs to be installed also, otherwise
Teneo/hibernate does not
> know how to instantiate a usertype.
> Take the example of storing a colour object in 3 int columns. This requires
a specific hibernate
> usertype which can translate a colour type to these three columns. This
usertype is a custom class
> which needs to be stored at the server.
> Also the custom colour class needs to be added to the server environment, or
otherwise how can cdo
> handle it? Eike how would the colour instance be passed over the wire,
serialized?
I would expect that at client side the generated (and hand modified) model
code serializes the custom-typed value into a string and sends it to the
server. so far no modification to the process necessary.
But arrived at the server side, we need the same generated and
hand-modified model code with all its dependencies so that the Hibernate
layer is able to deserialize the string that comes from the wire to
whatever is coded into the model.
Eventually we can look into how to optimize the transfer over the wire
itself. But I suggest that we go step by step ;-)
The main issue I foresee with the above approach is that we lose the
ability to dynamically register new models at the client side. I propose
that we start with a static approach where a deployer is responsible to
manually install the needed bundles at the server side. If we can make it
work this way I can later try to develop some mechanism that transfers
bundles from the client to the server along with the usual CDOPackages (in
the run of a CommitTransactionRequest/Indication).
Agreed?
Cheers
/Eike
> gr. Martin
> Eric wrote:
>> Hi Eike, Martin,
>>
>> I did not see that one coming (custom Java code for
>> serialization)... If this is the case and you want to recreate the
>> "original" type on server-side, you might not have any other choice than
>> have a model dependency. :(
>>
>> That having been said, maybe we don't need to have the EMF type on
>> the server. Maybe I'm missing the big picture here, but in my case I
>> was trying to recreate the EMF type in order to store this attribute
>> using Teneo's original mapping (store a byte[] as a binary blob instead
>> of a String). Since CDO's internal representation of a custom type is a
>> String, as long as I'm accessing it through CDO, I shouldn't care how it
>> is stored in the database. So Teneo could detect (when using CDO only)
>> that the attribute you are trying to persist is in fact a custom type
>> and should generate a "String" representation for the mapping file. This
>> is not fixing the issue where server-side code would like to see the EMF
>> type, but if I get this right, it should never be the case?!?
>>
>> Would there be any other benefits if we have access to the model on
>> server-side? Is it worthwhile?
>>
>> Any thoughts?
>>
>> Eric
>>
>> Eike Stepper wrote:
>>> Hi Eric, Martin,
>>>
>>> Having read your message I now see a more basic issue with custom
>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>> generated models to be deployed at the server side. The new Hibernate
>>> integration layer (HibernateStore implementation) adds a server-side
>>> dependency on EMF but not on your generated models. The HibernateStore
>>> uses the serialized xml string of your client-side model to recreate
>>> the EPackage instances. WRT the custom EDataTypes there is a good
>>> chance that the dynamic package at the server side behaves quite
>>> different from the generated one. IIRC the serialization of custom
>>> EDataTypes relies on manually written code in the otherwise generated
>>> model and the respective deserialization code will not be present on
>>> the server ;-( Not to mention the potentially non-standard instance
>>> classes that you used on client side.
>>>
>>> If I'm right, I only see that the generated models, along with all
>>> their dependencies, have to be deployed to the server as well. And we
>>> will have to make sure that the server side EPackage.Registry.INSTANCE
>>> is consulted before we attempt to deserialize the needed EPackages
>>> from the xml string in the db.
>>>
>>> What do you think?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Eric wrote:
>>>
>>>> Hi Martin, Eike,
>>>
>>>> I want to solve a problem I have with custom CDO types. To
>>>> summarize my problem, I have an EMF type with an attribute of type
>>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>>> blob. When the CDOPropertyGetter returns the value, it is returning
>>>> a String and this is causing a ClassCastException. So to fix this
>>>> problem, I'd like to do the following:
>>>
>>>> In CDOPropertyGetter:
>>>> public Object get(Object target) throws HibernateException
>>>> {
>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>> Object value = revision.getValue(getCDOFeature());
>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>> return EcoreUtil.convertFromString(..., value);
>>>> return value;
>>>> }
>>>
>>>> where ... would be replaced by the EMF data type.
>>>
>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>> concrete EMF data type and this CDOCustomPropertyGetter would do the
>>>> conversion. This solution would remove the if statement from my code
>>>> above.
>>>
>>>> Anyhow, there is no unique solution to this problem, but they all
>>>> require access to the original EMF type... How can I get it?
>>>
>>>> Thanks,
>>>> Eric
>>>
>>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120165 is a reply to message #120095] |
Fri, 25 April 2008 18:09 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
Afaics the only way to solve this is to have the possibility to add custom code server side.
Btw, I can see also other scenarios were it makes sense to have custom server side code. For example
to implement server side actions based on triggers generated by hibernate interceptors or
eventlisteners.
gr. Martin
Eike Stepper wrote:
> Martin Taal wrote:
>
>> Hi All,
>> I think only for primitive types (byte, string, etc.) and their string
> representations there is no
>> need for extra server side code. For anything more special, for example a
> rgb color object then at
>> server side some client-specific code needs to be installed also,
>> otherwise
> Teneo/hibernate does not
>> know how to instantiate a usertype.
>> Take the example of storing a colour object in 3 int columns. This
>> requires
> a specific hibernate
>> usertype which can translate a colour type to these three columns. This
> usertype is a custom class
>> which needs to be stored at the server.
>> Also the custom colour class needs to be added to the server
>> environment, or
> otherwise how can cdo
>> handle it? Eike how would the colour instance be passed over the wire,
> serialized?
>
> I would expect that at client side the generated (and hand modified)
> model code serializes the custom-typed value into a string and sends it
> to the server. so far no modification to the process necessary.
>
> But arrived at the server side, we need the same generated and
> hand-modified model code with all its dependencies so that the Hibernate
> layer is able to deserialize the string that comes from the wire to
> whatever is coded into the model.
>
> Eventually we can look into how to optimize the transfer over the wire
> itself. But I suggest that we go step by step ;-)
>
> The main issue I foresee with the above approach is that we lose the
> ability to dynamically register new models at the client side. I propose
> that we start with a static approach where a deployer is responsible to
> manually install the needed bundles at the server side. If we can make
> it work this way I can later try to develop some mechanism that
> transfers bundles from the client to the server along with the usual
> CDOPackages (in the run of a CommitTransactionRequest/Indication).
>
> Agreed?
>
> Cheers
> /Eike
>
>
>
>> gr. Martin
>
>> Eric wrote:
>>> Hi Eike, Martin,
>>>
>>> I did not see that one coming (custom Java code for
>>> serialization)... If this is the case and you want to recreate the
>>> "original" type on server-side, you might not have any other choice
>>> than have a model dependency. :(
>>>
>>> That having been said, maybe we don't need to have the EMF type
>>> on the server. Maybe I'm missing the big picture here, but in my
>>> case I was trying to recreate the EMF type in order to store this
>>> attribute using Teneo's original mapping (store a byte[] as a binary
>>> blob instead of a String). Since CDO's internal representation of a
>>> custom type is a String, as long as I'm accessing it through CDO, I
>>> shouldn't care how it is stored in the database. So Teneo could
>>> detect (when using CDO only) that the attribute you are trying to
>>> persist is in fact a custom type and should generate a "String"
>>> representation for the mapping file. This is not fixing the issue
>>> where server-side code would like to see the EMF type, but if I get
>>> this right, it should never be the case?!?
>>>
>>> Would there be any other benefits if we have access to the model
>>> on server-side? Is it worthwhile?
>>>
>>> Any thoughts?
>>>
>>> Eric
>>>
>>> Eike Stepper wrote:
>>>> Hi Eric, Martin,
>>>>
>>>> Having read your message I now see a more basic issue with custom
>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>> generated models to be deployed at the server side. The new
>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>> server-side dependency on EMF but not on your generated models. The
>>>> HibernateStore uses the serialized xml string of your client-side
>>>> model to recreate the EPackage instances. WRT the custom EDataTypes
>>>> there is a good chance that the dynamic package at the server side
>>>> behaves quite different from the generated one. IIRC the
>>>> serialization of custom EDataTypes relies on manually written code
>>>> in the otherwise generated model and the respective deserialization
>>>> code will not be present on the server ;-( Not to mention the
>>>> potentially non-standard instance classes that you used on client side.
>>>>
>>>> If I'm right, I only see that the generated models, along with all
>>>> their dependencies, have to be deployed to the server as well. And
>>>> we will have to make sure that the server side
>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>> deserialize the needed EPackages from the xml string in the db.
>>>>
>>>> What do you think?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Eric wrote:
>>>>
>>>>> Hi Martin, Eike,
>>>>
>>>>> I want to solve a problem I have with custom CDO types. To
>>>>> summarize my problem, I have an EMF type with an attribute of type
>>>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>>>> blob. When the CDOPropertyGetter returns the value, it is
>>>>> returning a String and this is causing a ClassCastException. So to
>>>>> fix this problem, I'd like to do the following:
>>>>
>>>>> In CDOPropertyGetter:
>>>>> public Object get(Object target) throws HibernateException
>>>>> {
>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>> Object value = revision.getValue(getCDOFeature());
>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>> return EcoreUtil.convertFromString(..., value);
>>>>> return value;
>>>>> }
>>>>
>>>>> where ... would be replaced by the EMF data type.
>>>>
>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>> the conversion. This solution would remove the if statement from my
>>>>> code above.
>>>>
>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>> require access to the original EMF type... How can I get it?
>>>>
>>>>> Thanks,
>>>>> Eric
>>>>
>>>>
>
>
>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120191 is a reply to message #120165] |
Sat, 26 April 2008 09:20 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Hi guys,
I think the problem is two-fold:
1) There seem to be users who don't really care about *how* the model is
persisted. I call these "model centric". In this case a String is
appropriate for now. As Eric pointed out, this case must be supported by
the Hibernate layer. Eric, I suggest that you file a Bugzilla.
2) The other group of users can be called "db centric". They want to
control *how* exactly their models get persisted. If we want to support
this case we won't be able to go without having the generated model code
on the server side. It should be easy for the Hibernate layer to
interrogate the global package registry prior and falling back to
desrerialization from the db only in case a certain package is not
globally registered. It is also imagineable to use a store-local
registry that can be configured individually. I think a more complex
issue is the question how to get the desired/needed packages *into* the
used package registry. I see two ways that should both be supported:
2.1) Administratively provisioning the server with the needed models.
Depending on the chosen registry approach (direct global or store-local)
we could benefit from OSGi dynamic loading. If the global registry is
used it will be dynamically configured through an extension point. If a
store-local approach is chosen the registry would have to be configured
through the server config file which is only read on server startup.
2.2) Dynamically adding models through CommitTransactionRequests issued
by the client (which is the standard in CDO). In this case both the
calculation of the required bundles at client side and the transmission
over the wire are comparingly easy to solve. What about security concerns?
Any thoughts?
Cheers
/Eike
Martin Taal schrieb:
> Hi Eike,
> Afaics the only way to solve this is to have the possibility to add
> custom code server side.
>
> Btw, I can see also other scenarios were it makes sense to have custom
> server side code. For example to implement server side actions based
> on triggers generated by hibernate interceptors or eventlisteners.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal wrote:
>>
>>> Hi All,
>>> I think only for primitive types (byte, string, etc.) and their string
>> representations there is no
>>> need for extra server side code. For anything more special, for
>>> example a
>> rgb color object then at
>>> server side some client-specific code needs to be installed also,
>>> otherwise
>> Teneo/hibernate does not
>>> know how to instantiate a usertype.
>>> Take the example of storing a colour object in 3 int columns. This
>>> requires
>> a specific hibernate
>>> usertype which can translate a colour type to these three columns. This
>> usertype is a custom class
>>> which needs to be stored at the server.
>>> Also the custom colour class needs to be added to the server
>>> environment, or
>> otherwise how can cdo
>>> handle it? Eike how would the colour instance be passed over the wire,
>> serialized?
>>
>> I would expect that at client side the generated (and hand modified)
>> model code serializes the custom-typed value into a string and sends
>> it to the server. so far no modification to the process necessary.
>>
>> But arrived at the server side, we need the same generated and
>> hand-modified model code with all its dependencies so that the
>> Hibernate layer is able to deserialize the string that comes from the
>> wire to whatever is coded into the model.
>>
>> Eventually we can look into how to optimize the transfer over the
>> wire itself. But I suggest that we go step by step ;-)
>>
>> The main issue I foresee with the above approach is that we lose the
>> ability to dynamically register new models at the client side. I
>> propose that we start with a static approach where a deployer is
>> responsible to manually install the needed bundles at the server
>> side. If we can make it work this way I can later try to develop some
>> mechanism that transfers bundles from the client to the server along
>> with the usual CDOPackages (in the run of a
>> CommitTransactionRequest/Indication).
>>
>> Agreed?
>>
>> Cheers
>> /Eike
>>
>>
>>
>>> gr. Martin
>>
>>> Eric wrote:
>>>> Hi Eike, Martin,
>>>>
>>>> I did not see that one coming (custom Java code for
>>>> serialization)... If this is the case and you want to recreate the
>>>> "original" type on server-side, you might not have any other choice
>>>> than have a model dependency. :(
>>>>
>>>> That having been said, maybe we don't need to have the EMF type
>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>> case I was trying to recreate the EMF type in order to store this
>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>> binary blob instead of a String). Since CDO's internal
>>>> representation of a custom type is a String, as long as I'm
>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>> database. So Teneo could detect (when using CDO only) that the
>>>> attribute you are trying to persist is in fact a custom type and
>>>> should generate a "String" representation for the mapping file.
>>>> This is not fixing the issue where server-side code would like to
>>>> see the EMF type, but if I get this right, it should never be the
>>>> case?!?
>>>>
>>>> Would there be any other benefits if we have access to the
>>>> model on server-side? Is it worthwhile?
>>>>
>>>> Any thoughts?
>>>>
>>>> Eric
>>>>
>>>> Eike Stepper wrote:
>>>>> Hi Eric, Martin,
>>>>>
>>>>> Having read your message I now see a more basic issue with custom
>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>> generated models to be deployed at the server side. The new
>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>> server-side dependency on EMF but not on your generated models.
>>>>> The HibernateStore uses the serialized xml string of your
>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>> at the server side behaves quite different from the generated one.
>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>> written code in the otherwise generated model and the respective
>>>>> deserialization code will not be present on the server ;-( Not to
>>>>> mention the potentially non-standard instance classes that you
>>>>> used on client side.
>>>>>
>>>>> If I'm right, I only see that the generated models, along with all
>>>>> their dependencies, have to be deployed to the server as well. And
>>>>> we will have to make sure that the server side
>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>
>>>>> What do you think?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>> Eric wrote:
>>>>>
>>>>>> Hi Martin, Eike,
>>>>>
>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>> to fix this problem, I'd like to do the following:
>>>>>
>>>>>> In CDOPropertyGetter:
>>>>>> public Object get(Object target) throws HibernateException
>>>>>> {
>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>> return value;
>>>>>> }
>>>>>
>>>>>> where ... would be replaced by the EMF data type.
>>>>>
>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>> the conversion. This solution would remove the if statement from
>>>>>> my code above.
>>>>>
>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>> require access to the original EMF type... How can I get it?
>>>>>
>>>>>> Thanks,
>>>>>> Eric
>>>>>
>>>>>
>>
>>
>>
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120274 is a reply to message #120191] |
Sun, 27 April 2008 20:52 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See comments below.
gr. Martin
Eike Stepper wrote:
> Hi guys,
>
> I think the problem is two-fold:
>
> 1) There seem to be users who don't really care about *how* the model is
> persisted. I call these "model centric". In this case a String is
> appropriate for now. As Eric pointed out, this case must be supported by
> the Hibernate layer. Eric, I suggest that you file a Bugzilla.
MT>> Yes I agree, I am not sure how the hibernate layer would know which types are to be stringized
because then it should put type="string" in the mapping.But how can it know this?
>
> 2) The other group of users can be called "db centric". They want to
> control *how* exactly their models get persisted. If we want to support
> this case we won't be able to go without having the generated model code
> on the server side. It should be easy for the Hibernate layer to
> interrogate the global package registry prior and falling back to
> desrerialization from the db only in case a certain package is not
> globally registered. It is also imagineable to use a store-local
> registry that can be configured individually. I think a more complex
> issue is the question how to get the desired/needed packages *into* the
> used package registry. I see two ways that should both be supported:
MT>> Do you mean java package or ecore package? For the hibernate layer getting access to the
required classes is relevant. With required classes I mean the actual class of the value of the
attribute and the class for the hibernate converter.
MT>> In my view the required models and the java packages implementing model specifics (like types
and converters) are fairly static. This means that they can be installed at installation time (and
upgrade time) and are not that dynamic. So would the solution not just be to allow the developer to
add plugins to the server runtime which provide the value classes and converter and (de-)serializer
to get the value objects over the wire?
Or what do you think?
>
> 2.1) Administratively provisioning the server with the needed models.
> Depending on the chosen registry approach (direct global or store-local)
> we could benefit from OSGi dynamic loading. If the global registry is
> used it will be dynamically configured through an extension point. If a
> store-local approach is chosen the registry would have to be configured
> through the server config file which is only read on server startup.
>
> 2.2) Dynamically adding models through CommitTransactionRequests issued
> by the client (which is the standard in CDO). In this case both the
> calculation of the required bundles at client side and the transmission
> over the wire are comparingly easy to solve. What about security concerns?
>
> Any thoughts?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Eike,
>> Afaics the only way to solve this is to have the possibility to add
>> custom code server side.
>>
>> Btw, I can see also other scenarios were it makes sense to have custom
>> server side code. For example to implement server side actions based
>> on triggers generated by hibernate interceptors or eventlisteners.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal wrote:
>>>
>>>> Hi All,
>>>> I think only for primitive types (byte, string, etc.) and their string
>>> representations there is no
>>>> need for extra server side code. For anything more special, for
>>>> example a
>>> rgb color object then at
>>>> server side some client-specific code needs to be installed also,
>>>> otherwise
>>> Teneo/hibernate does not
>>>> know how to instantiate a usertype.
>>>> Take the example of storing a colour object in 3 int columns. This
>>>> requires
>>> a specific hibernate
>>>> usertype which can translate a colour type to these three columns. This
>>> usertype is a custom class
>>>> which needs to be stored at the server.
>>>> Also the custom colour class needs to be added to the server
>>>> environment, or
>>> otherwise how can cdo
>>>> handle it? Eike how would the colour instance be passed over the wire,
>>> serialized?
>>>
>>> I would expect that at client side the generated (and hand modified)
>>> model code serializes the custom-typed value into a string and sends
>>> it to the server. so far no modification to the process necessary.
>>>
>>> But arrived at the server side, we need the same generated and
>>> hand-modified model code with all its dependencies so that the
>>> Hibernate layer is able to deserialize the string that comes from the
>>> wire to whatever is coded into the model.
>>>
>>> Eventually we can look into how to optimize the transfer over the
>>> wire itself. But I suggest that we go step by step ;-)
>>>
>>> The main issue I foresee with the above approach is that we lose the
>>> ability to dynamically register new models at the client side. I
>>> propose that we start with a static approach where a deployer is
>>> responsible to manually install the needed bundles at the server
>>> side. If we can make it work this way I can later try to develop some
>>> mechanism that transfers bundles from the client to the server along
>>> with the usual CDOPackages (in the run of a
>>> CommitTransactionRequest/Indication).
>>>
>>> Agreed?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>>> gr. Martin
>>>
>>>> Eric wrote:
>>>>> Hi Eike, Martin,
>>>>>
>>>>> I did not see that one coming (custom Java code for
>>>>> serialization)... If this is the case and you want to recreate the
>>>>> "original" type on server-side, you might not have any other choice
>>>>> than have a model dependency. :(
>>>>>
>>>>> That having been said, maybe we don't need to have the EMF type
>>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>>> case I was trying to recreate the EMF type in order to store this
>>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>>> binary blob instead of a String). Since CDO's internal
>>>>> representation of a custom type is a String, as long as I'm
>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>> attribute you are trying to persist is in fact a custom type and
>>>>> should generate a "String" representation for the mapping file.
>>>>> This is not fixing the issue where server-side code would like to
>>>>> see the EMF type, but if I get this right, it should never be the
>>>>> case?!?
>>>>>
>>>>> Would there be any other benefits if we have access to the
>>>>> model on server-side? Is it worthwhile?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Eric
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Hi Eric, Martin,
>>>>>>
>>>>>> Having read your message I now see a more basic issue with custom
>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>> generated models to be deployed at the server side. The new
>>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>>> server-side dependency on EMF but not on your generated models.
>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>> at the server side behaves quite different from the generated one.
>>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>>> written code in the otherwise generated model and the respective
>>>>>> deserialization code will not be present on the server ;-( Not to
>>>>>> mention the potentially non-standard instance classes that you
>>>>>> used on client side.
>>>>>>
>>>>>> If I'm right, I only see that the generated models, along with all
>>>>>> their dependencies, have to be deployed to the server as well. And
>>>>>> we will have to make sure that the server side
>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>> Eric wrote:
>>>>>>
>>>>>>> Hi Martin, Eike,
>>>>>>
>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>>> to fix this problem, I'd like to do the following:
>>>>>>
>>>>>>> In CDOPropertyGetter:
>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>> {
>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>> return value;
>>>>>>> }
>>>>>>
>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>
>>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>>> the conversion. This solution would remove the if statement from
>>>>>>> my code above.
>>>>>>
>>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>>> require access to the original EMF type... How can I get it?
>>>>>>
>>>>>>> Thanks,
>>>>>>> Eric
>>>>>>
>>>>>>
>>>
>>>
>>>
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120299 is a reply to message #120274] |
Mon, 28 April 2008 06:50 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> See comments below.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi guys,
>>
>> I think the problem is two-fold:
>>
>> 1) There seem to be users who don't really care about *how* the model
>> is persisted. I call these "model centric". In this case a String is
>> appropriate for now. As Eric pointed out, this case must be supported
>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
> MT>> Yes I agree, I am not sure how the hibernate layer would know
> which types are to be stringized because then it should put
> type="string" in the mapping.But how can it know this?
I think this should be the fallback approach in case the store is unable
to reach the generated code for non-basic EDataTypes via 2.1 or 2.2. So
whenever the mapping engine encounters EDataTypes with an instance class
which it can't access via its ClassLoader it should use String (or
something more configurable). Would that be possible?
>> 2) The other group of users can be called "db centric". They want to
>> control *how* exactly their models get persisted. If we want to
>> support this case we won't be able to go without having the generated
>> model code on the server side. It should be easy for the Hibernate
>> layer to interrogate the global package registry prior and falling
>> back to desrerialization from the db only in case a certain package
>> is not globally registered. It is also imagineable to use a
>> store-local registry that can be configured individually. I think a
>> more complex issue is the question how to get the desired/needed
>> packages *into* the used package registry. I see two ways that should
>> both be supported:
>
> MT>> Do you mean java package or ecore package? For the hibernate
> layer getting access to the required classes is relevant. With
> required classes I mean the actual class of the value of the attribute
> and the class for the hibernate converter.
Aren't Ecore packages and Java packages equivalent here? Since we talk
about generated models I really mean the generated model bundles which
contain the model itself plus the generated Java packages. Somewhere in
this bundle or in its dependency tree the needed instance classes must
be found, as well as the serialization code to convert between String
(which comes over the wire) and the instance class.
> MT>> In my view the required models and the java packages implementing
> model specifics (like types and converters) are fairly static. This
> means that they can be installed at installation time (and upgrade
> time) and are not that dynamic. So would the solution not just be to
> allow the developer to add plugins to the server runtime which provide
> the value classes and converter and (de-)serializer to get the value
> objects over the wire?
> Or what do you think?
Yes, that's my case 2.1. Case 2.2 would be an additional feature where
the clients can commit additional packages which would be dynamically
added to the repository.
If we want to start work on these features I'd suggest that I start on
the configuration issues (of the server and the config negotiation with
the client) and then find a way to transfer additional binary data (e.g.
bundles) with a CommitTransaction Request.
Ok?
Cheers
/Eike
>> 2.1) Administratively provisioning the server with the needed models.
>> Depending on the chosen registry approach (direct global or
>> store-local) we could benefit from OSGi dynamic loading. If the
>> global registry is used it will be dynamically configured through an
>> extension point. If a store-local approach is chosen the registry
>> would have to be configured through the server config file which is
>> only read on server startup.
>>
>> 2.2) Dynamically adding models through CommitTransactionRequests
>> issued by the client (which is the standard in CDO). In this case
>> both the calculation of the required bundles at client side and the
>> transmission over the wire are comparingly easy to solve. What about
>> security concerns?
>>
>> Any thoughts?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Eike,
>>> Afaics the only way to solve this is to have the possibility to add
>>> custom code server side.
>>>
>>> Btw, I can see also other scenarios were it makes sense to have
>>> custom server side code. For example to implement server side
>>> actions based on triggers generated by hibernate interceptors or
>>> eventlisteners.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Martin Taal wrote:
>>>>
>>>>> Hi All,
>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>> string
>>>> representations there is no
>>>>> need for extra server side code. For anything more special, for
>>>>> example a
>>>> rgb color object then at
>>>>> server side some client-specific code needs to be installed also,
>>>>> otherwise
>>>> Teneo/hibernate does not
>>>>> know how to instantiate a usertype.
>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>> requires
>>>> a specific hibernate
>>>>> usertype which can translate a colour type to these three columns.
>>>>> This
>>>> usertype is a custom class
>>>>> which needs to be stored at the server.
>>>>> Also the custom colour class needs to be added to the server
>>>>> environment, or
>>>> otherwise how can cdo
>>>>> handle it? Eike how would the colour instance be passed over the
>>>>> wire,
>>>> serialized?
>>>>
>>>> I would expect that at client side the generated (and hand
>>>> modified) model code serializes the custom-typed value into a
>>>> string and sends it to the server. so far no modification to the
>>>> process necessary.
>>>>
>>>> But arrived at the server side, we need the same generated and
>>>> hand-modified model code with all its dependencies so that the
>>>> Hibernate layer is able to deserialize the string that comes from
>>>> the wire to whatever is coded into the model.
>>>>
>>>> Eventually we can look into how to optimize the transfer over the
>>>> wire itself. But I suggest that we go step by step ;-)
>>>>
>>>> The main issue I foresee with the above approach is that we lose
>>>> the ability to dynamically register new models at the client side.
>>>> I propose that we start with a static approach where a deployer is
>>>> responsible to manually install the needed bundles at the server
>>>> side. If we can make it work this way I can later try to develop
>>>> some mechanism that transfers bundles from the client to the server
>>>> along with the usual CDOPackages (in the run of a
>>>> CommitTransactionRequest/Indication).
>>>>
>>>> Agreed?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>>> gr. Martin
>>>>
>>>>> Eric wrote:
>>>>>> Hi Eike, Martin,
>>>>>>
>>>>>> I did not see that one coming (custom Java code for
>>>>>> serialization)... If this is the case and you want to recreate
>>>>>> the "original" type on server-side, you might not have any other
>>>>>> choice than have a model dependency. :(
>>>>>>
>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>> internal representation of a custom type is a String, as long as
>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>> type and should generate a "String" representation for the
>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>> should never be the case?!?
>>>>>>
>>>>>> Would there be any other benefits if we have access to the
>>>>>> model on server-side? Is it worthwhile?
>>>>>>
>>>>>> Any thoughts?
>>>>>>
>>>>>> Eric
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Hi Eric, Martin,
>>>>>>>
>>>>>>> Having read your message I now see a more basic issue with
>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>> package at the server side behaves quite different from the
>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>> and the respective deserialization code will not be present on
>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>> instance classes that you used on client side.
>>>>>>>
>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>> well. And we will have to make sure that the server side
>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Eric wrote:
>>>>>>>
>>>>>>>> Hi Martin, Eike,
>>>>>>>
>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>> is returning a String and this is causing a
>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>> following:
>>>>>>>
>>>>>>>> In CDOPropertyGetter:
>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>> {
>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>> return value;
>>>>>>>> }
>>>>>>>
>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>
>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>> statement from my code above.
>>>>>>>
>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Eric
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120340 is a reply to message #120191] |
Mon, 28 April 2008 14:12 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi guys,
Eike, I've created a bugzilla entry and added a test case:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if you
have any questions.
Martin, as I explained in Bugzilla, when Teneo is creating the
mapping for my model, I get the following error:
------
[ERROR] Argument is not an array
java.lang.IllegalArgumentException: Argument is not an array
at java.lang.reflect.Array.getLength(Native Method)
at
org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
at org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
at
org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
at
org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
at
org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
at
org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
at
org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
at org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
at
org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
at
org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
at
org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
at
org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
at
org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at
org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at
org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
at
org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
at
org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
at
org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
------
My attribute is a byte array (byte[]) and here is Teneo's mapping:
<array name="barCode" table="`product_barcode`"
cascade="all,delete-orphan">
<key update="true">
<column name="`product_barcode_e_id`" not-null="true" unique="false"/>
</key>
<list-index column="`product_barcode_idx`"/>
<element type="byte"/>
</array>
I've seen a few posts with similar problems and one of those posts
suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
This triggered a binary blob in my mapping and the mapping became valid,
but I can't understand why this is happening... Is this (can't process
byte[]) a bug?
Thanks,
Eric
Eike Stepper wrote:
> Hi guys,
>
> I think the problem is two-fold:
>
> 1) There seem to be users who don't really care about *how* the model is
> persisted. I call these "model centric". In this case a String is
> appropriate for now. As Eric pointed out, this case must be supported by
> the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>
> 2) The other group of users can be called "db centric". They want to
> control *how* exactly their models get persisted. If we want to support
> this case we won't be able to go without having the generated model code
> on the server side. It should be easy for the Hibernate layer to
> interrogate the global package registry prior and falling back to
> desrerialization from the db only in case a certain package is not
> globally registered. It is also imagineable to use a store-local
> registry that can be configured individually. I think a more complex
> issue is the question how to get the desired/needed packages *into* the
> used package registry. I see two ways that should both be supported:
>
> 2.1) Administratively provisioning the server with the needed models.
> Depending on the chosen registry approach (direct global or store-local)
> we could benefit from OSGi dynamic loading. If the global registry is
> used it will be dynamically configured through an extension point. If a
> store-local approach is chosen the registry would have to be configured
> through the server config file which is only read on server startup.
>
> 2.2) Dynamically adding models through CommitTransactionRequests issued
> by the client (which is the standard in CDO). In this case both the
> calculation of the required bundles at client side and the transmission
> over the wire are comparingly easy to solve. What about security concerns?
>
> Any thoughts?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Eike,
>> Afaics the only way to solve this is to have the possibility to add
>> custom code server side.
>>
>> Btw, I can see also other scenarios were it makes sense to have custom
>> server side code. For example to implement server side actions based
>> on triggers generated by hibernate interceptors or eventlisteners.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal wrote:
>>>
>>>> Hi All,
>>>> I think only for primitive types (byte, string, etc.) and their string
>>> representations there is no
>>>> need for extra server side code. For anything more special, for
>>>> example a
>>> rgb color object then at
>>>> server side some client-specific code needs to be installed also,
>>>> otherwise
>>> Teneo/hibernate does not
>>>> know how to instantiate a usertype.
>>>> Take the example of storing a colour object in 3 int columns. This
>>>> requires
>>> a specific hibernate
>>>> usertype which can translate a colour type to these three columns. This
>>> usertype is a custom class
>>>> which needs to be stored at the server.
>>>> Also the custom colour class needs to be added to the server
>>>> environment, or
>>> otherwise how can cdo
>>>> handle it? Eike how would the colour instance be passed over the wire,
>>> serialized?
>>>
>>> I would expect that at client side the generated (and hand modified)
>>> model code serializes the custom-typed value into a string and sends
>>> it to the server. so far no modification to the process necessary.
>>>
>>> But arrived at the server side, we need the same generated and
>>> hand-modified model code with all its dependencies so that the
>>> Hibernate layer is able to deserialize the string that comes from the
>>> wire to whatever is coded into the model.
>>>
>>> Eventually we can look into how to optimize the transfer over the
>>> wire itself. But I suggest that we go step by step ;-)
>>>
>>> The main issue I foresee with the above approach is that we lose the
>>> ability to dynamically register new models at the client side. I
>>> propose that we start with a static approach where a deployer is
>>> responsible to manually install the needed bundles at the server
>>> side. If we can make it work this way I can later try to develop some
>>> mechanism that transfers bundles from the client to the server along
>>> with the usual CDOPackages (in the run of a
>>> CommitTransactionRequest/Indication).
>>>
>>> Agreed?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>>> gr. Martin
>>>
>>>> Eric wrote:
>>>>> Hi Eike, Martin,
>>>>>
>>>>> I did not see that one coming (custom Java code for
>>>>> serialization)... If this is the case and you want to recreate the
>>>>> "original" type on server-side, you might not have any other choice
>>>>> than have a model dependency. :(
>>>>>
>>>>> That having been said, maybe we don't need to have the EMF type
>>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>>> case I was trying to recreate the EMF type in order to store this
>>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>>> binary blob instead of a String). Since CDO's internal
>>>>> representation of a custom type is a String, as long as I'm
>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>> attribute you are trying to persist is in fact a custom type and
>>>>> should generate a "String" representation for the mapping file.
>>>>> This is not fixing the issue where server-side code would like to
>>>>> see the EMF type, but if I get this right, it should never be the
>>>>> case?!?
>>>>>
>>>>> Would there be any other benefits if we have access to the
>>>>> model on server-side? Is it worthwhile?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Eric
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Hi Eric, Martin,
>>>>>>
>>>>>> Having read your message I now see a more basic issue with custom
>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>> generated models to be deployed at the server side. The new
>>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>>> server-side dependency on EMF but not on your generated models.
>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>> at the server side behaves quite different from the generated one.
>>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>>> written code in the otherwise generated model and the respective
>>>>>> deserialization code will not be present on the server ;-( Not to
>>>>>> mention the potentially non-standard instance classes that you
>>>>>> used on client side.
>>>>>>
>>>>>> If I'm right, I only see that the generated models, along with all
>>>>>> their dependencies, have to be deployed to the server as well. And
>>>>>> we will have to make sure that the server side
>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>> Eric wrote:
>>>>>>
>>>>>>> Hi Martin, Eike,
>>>>>>
>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>>> to fix this problem, I'd like to do the following:
>>>>>>
>>>>>>> In CDOPropertyGetter:
>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>> {
>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>> return value;
>>>>>>> }
>>>>>>
>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>
>>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>>> the conversion. This solution would remove the if statement from
>>>>>>> my code above.
>>>>>>
>>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>>> require access to the original EMF type... How can I get it?
>>>>>>
>>>>>>> Thanks,
>>>>>>> Eric
>>>>>>
>>>>>>
>>>
>>>
>>>
>>
>>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120368 is a reply to message #120340] |
Mon, 28 April 2008 14:30 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eric,
What is the class of the object passed to hibernate? If you put a breakpoint in
PersistentArrayHolder.java:45 then you should be able to see it.
gr. Martin
Eric wrote:
> Hi guys,
>
> Eike, I've created a bugzilla entry and added a test case:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if you
> have any questions.
>
> Martin, as I explained in Bugzilla, when Teneo is creating the mapping
> for my model, I get the following error:
> ------
> [ERROR] Argument is not an array
> java.lang.IllegalArgumentException: Argument is not an array
> at java.lang.reflect.Array.getLength(Native Method)
> at
> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>
> at org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
> at
> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>
> at
> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>
> at
> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>
> at
> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
> at
> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>
> at
> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
> at
> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>
> at
> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>
> at
> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>
> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
> at
> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>
> at
> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>
> at
> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>
> at
> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>
> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
> Source)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
> at java.lang.Thread.run(Unknown Source)
> ------
>
> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>
> <array name="barCode" table="`product_barcode`"
> cascade="all,delete-orphan">
> <key update="true">
> <column name="`product_barcode_e_id`" not-null="true"
> unique="false"/>
> </key>
> <list-index column="`product_barcode_idx`"/>
> <element type="byte"/>
> </array>
>
> I've seen a few posts with similar problems and one of those posts
> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
> This triggered a binary blob in my mapping and the mapping became valid,
> but I can't understand why this is happening... Is this (can't process
> byte[]) a bug?
>
> Thanks,
> Eric
>
> Eike Stepper wrote:
>> Hi guys,
>>
>> I think the problem is two-fold:
>>
>> 1) There seem to be users who don't really care about *how* the model
>> is persisted. I call these "model centric". In this case a String is
>> appropriate for now. As Eric pointed out, this case must be supported
>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>>
>> 2) The other group of users can be called "db centric". They want to
>> control *how* exactly their models get persisted. If we want to
>> support this case we won't be able to go without having the generated
>> model code on the server side. It should be easy for the Hibernate
>> layer to interrogate the global package registry prior and falling
>> back to desrerialization from the db only in case a certain package is
>> not globally registered. It is also imagineable to use a store-local
>> registry that can be configured individually. I think a more complex
>> issue is the question how to get the desired/needed packages *into*
>> the used package registry. I see two ways that should both be supported:
>>
>> 2.1) Administratively provisioning the server with the needed models.
>> Depending on the chosen registry approach (direct global or
>> store-local) we could benefit from OSGi dynamic loading. If the global
>> registry is used it will be dynamically configured through an
>> extension point. If a store-local approach is chosen the registry
>> would have to be configured through the server config file which is
>> only read on server startup.
>>
>> 2.2) Dynamically adding models through CommitTransactionRequests
>> issued by the client (which is the standard in CDO). In this case both
>> the calculation of the required bundles at client side and the
>> transmission over the wire are comparingly easy to solve. What about
>> security concerns?
>>
>> Any thoughts?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Eike,
>>> Afaics the only way to solve this is to have the possibility to add
>>> custom code server side.
>>>
>>> Btw, I can see also other scenarios were it makes sense to have
>>> custom server side code. For example to implement server side actions
>>> based on triggers generated by hibernate interceptors or eventlisteners.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Martin Taal wrote:
>>>>
>>>>> Hi All,
>>>>> I think only for primitive types (byte, string, etc.) and their string
>>>> representations there is no
>>>>> need for extra server side code. For anything more special, for
>>>>> example a
>>>> rgb color object then at
>>>>> server side some client-specific code needs to be installed also,
>>>>> otherwise
>>>> Teneo/hibernate does not
>>>>> know how to instantiate a usertype.
>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>> requires
>>>> a specific hibernate
>>>>> usertype which can translate a colour type to these three columns.
>>>>> This
>>>> usertype is a custom class
>>>>> which needs to be stored at the server.
>>>>> Also the custom colour class needs to be added to the server
>>>>> environment, or
>>>> otherwise how can cdo
>>>>> handle it? Eike how would the colour instance be passed over the wire,
>>>> serialized?
>>>>
>>>> I would expect that at client side the generated (and hand modified)
>>>> model code serializes the custom-typed value into a string and sends
>>>> it to the server. so far no modification to the process necessary.
>>>>
>>>> But arrived at the server side, we need the same generated and
>>>> hand-modified model code with all its dependencies so that the
>>>> Hibernate layer is able to deserialize the string that comes from
>>>> the wire to whatever is coded into the model.
>>>>
>>>> Eventually we can look into how to optimize the transfer over the
>>>> wire itself. But I suggest that we go step by step ;-)
>>>>
>>>> The main issue I foresee with the above approach is that we lose the
>>>> ability to dynamically register new models at the client side. I
>>>> propose that we start with a static approach where a deployer is
>>>> responsible to manually install the needed bundles at the server
>>>> side. If we can make it work this way I can later try to develop
>>>> some mechanism that transfers bundles from the client to the server
>>>> along with the usual CDOPackages (in the run of a
>>>> CommitTransactionRequest/Indication).
>>>>
>>>> Agreed?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>>> gr. Martin
>>>>
>>>>> Eric wrote:
>>>>>> Hi Eike, Martin,
>>>>>>
>>>>>> I did not see that one coming (custom Java code for
>>>>>> serialization)... If this is the case and you want to recreate the
>>>>>> "original" type on server-side, you might not have any other
>>>>>> choice than have a model dependency. :(
>>>>>>
>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>> in my case I was trying to recreate the EMF type in order to store
>>>>>> this attribute using Teneo's original mapping (store a byte[] as a
>>>>>> binary blob instead of a String). Since CDO's internal
>>>>>> representation of a custom type is a String, as long as I'm
>>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>>> attribute you are trying to persist is in fact a custom type and
>>>>>> should generate a "String" representation for the mapping file.
>>>>>> This is not fixing the issue where server-side code would like to
>>>>>> see the EMF type, but if I get this right, it should never be the
>>>>>> case?!?
>>>>>>
>>>>>> Would there be any other benefits if we have access to the
>>>>>> model on server-side? Is it worthwhile?
>>>>>>
>>>>>> Any thoughts?
>>>>>>
>>>>>> Eric
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Hi Eric, Martin,
>>>>>>>
>>>>>>> Having read your message I now see a more basic issue with custom
>>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>>> generated models to be deployed at the server side. The new
>>>>>>> Hibernate integration layer (HibernateStore implementation) adds
>>>>>>> a server-side dependency on EMF but not on your generated models.
>>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>>> at the server side behaves quite different from the generated
>>>>>>> one. IIRC the serialization of custom EDataTypes relies on
>>>>>>> manually written code in the otherwise generated model and the
>>>>>>> respective deserialization code will not be present on the server
>>>>>>> ;-( Not to mention the potentially non-standard instance classes
>>>>>>> that you used on client side.
>>>>>>>
>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>> well. And we will have to make sure that the server side
>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Eric wrote:
>>>>>>>
>>>>>>>> Hi Martin, Eike,
>>>>>>>
>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>> is returning a String and this is causing a ClassCastException.
>>>>>>>> So to fix this problem, I'd like to do the following:
>>>>>>>
>>>>>>>> In CDOPropertyGetter:
>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>> {
>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>> return value;
>>>>>>>> }
>>>>>>>
>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>
>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>> statement from my code above.
>>>>>>>
>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Eric
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>>
>>>
>>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120380 is a reply to message #120368] |
Mon, 28 April 2008 14:55 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi Martin,
the object seems to be a String.
Eric
Martin Taal wrote:
> Hi Eric,
> What is the class of the object passed to hibernate? If you put a
> breakpoint in PersistentArrayHolder.java:45 then you should be able to
> see it.
>
> gr. Martin
>
> Eric wrote:
>> Hi guys,
>>
>> Eike, I've created a bugzilla entry and added a test case:
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if
>> you have any questions.
>>
>> Martin, as I explained in Bugzilla, when Teneo is creating the
>> mapping for my model, I get the following error:
>> ------
>> [ERROR] Argument is not an array
>> java.lang.IllegalArgumentException: Argument is not an array
>> at java.lang.reflect.Array.getLength(Native Method)
>> at
>> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>>
>> at
>> org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
>> at
>> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>>
>> at
>> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
>>
>> at
>> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
>> at
>> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>>
>> at
>> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>>
>> at
>> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>>
>> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
>> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
>> at
>> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>>
>> at
>> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>>
>> at
>> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>>
>> at
>> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>>
>> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
>> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
>> Source)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
>> at java.lang.Thread.run(Unknown Source)
>> ------
>>
>> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>>
>> <array name="barCode" table="`product_barcode`"
>> cascade="all,delete-orphan">
>> <key update="true">
>> <column name="`product_barcode_e_id`" not-null="true"
>> unique="false"/>
>> </key>
>> <list-index column="`product_barcode_idx`"/>
>> <element type="byte"/>
>> </array>
>>
>> I've seen a few posts with similar problems and one of those posts
>> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
>> This triggered a binary blob in my mapping and the mapping became
>> valid, but I can't understand why this is happening... Is this (can't
>> process byte[]) a bug?
>>
>> Thanks,
>> Eric
>>
>> Eike Stepper wrote:
>>> Hi guys,
>>>
>>> I think the problem is two-fold:
>>>
>>> 1) There seem to be users who don't really care about *how* the model
>>> is persisted. I call these "model centric". In this case a String is
>>> appropriate for now. As Eric pointed out, this case must be supported
>>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>>>
>>> 2) The other group of users can be called "db centric". They want to
>>> control *how* exactly their models get persisted. If we want to
>>> support this case we won't be able to go without having the generated
>>> model code on the server side. It should be easy for the Hibernate
>>> layer to interrogate the global package registry prior and falling
>>> back to desrerialization from the db only in case a certain package
>>> is not globally registered. It is also imagineable to use a
>>> store-local registry that can be configured individually. I think a
>>> more complex issue is the question how to get the desired/needed
>>> packages *into* the used package registry. I see two ways that should
>>> both be supported:
>>>
>>> 2.1) Administratively provisioning the server with the needed models.
>>> Depending on the chosen registry approach (direct global or
>>> store-local) we could benefit from OSGi dynamic loading. If the
>>> global registry is used it will be dynamically configured through an
>>> extension point. If a store-local approach is chosen the registry
>>> would have to be configured through the server config file which is
>>> only read on server startup.
>>>
>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>> issued by the client (which is the standard in CDO). In this case
>>> both the calculation of the required bundles at client side and the
>>> transmission over the wire are comparingly easy to solve. What about
>>> security concerns?
>>>
>>> Any thoughts?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> Afaics the only way to solve this is to have the possibility to add
>>>> custom code server side.
>>>>
>>>> Btw, I can see also other scenarios were it makes sense to have
>>>> custom server side code. For example to implement server side
>>>> actions based on triggers generated by hibernate interceptors or
>>>> eventlisteners.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Martin Taal wrote:
>>>>>
>>>>>> Hi All,
>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>> string
>>>>> representations there is no
>>>>>> need for extra server side code. For anything more special, for
>>>>>> example a
>>>>> rgb color object then at
>>>>>> server side some client-specific code needs to be installed also,
>>>>>> otherwise
>>>>> Teneo/hibernate does not
>>>>>> know how to instantiate a usertype.
>>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>>> requires
>>>>> a specific hibernate
>>>>>> usertype which can translate a colour type to these three columns.
>>>>>> This
>>>>> usertype is a custom class
>>>>>> which needs to be stored at the server.
>>>>>> Also the custom colour class needs to be added to the server
>>>>>> environment, or
>>>>> otherwise how can cdo
>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>> wire,
>>>>> serialized?
>>>>>
>>>>> I would expect that at client side the generated (and hand
>>>>> modified) model code serializes the custom-typed value into a
>>>>> string and sends it to the server. so far no modification to the
>>>>> process necessary.
>>>>>
>>>>> But arrived at the server side, we need the same generated and
>>>>> hand-modified model code with all its dependencies so that the
>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>> the wire to whatever is coded into the model.
>>>>>
>>>>> Eventually we can look into how to optimize the transfer over the
>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>
>>>>> The main issue I foresee with the above approach is that we lose
>>>>> the ability to dynamically register new models at the client side.
>>>>> I propose that we start with a static approach where a deployer is
>>>>> responsible to manually install the needed bundles at the server
>>>>> side. If we can make it work this way I can later try to develop
>>>>> some mechanism that transfers bundles from the client to the server
>>>>> along with the usual CDOPackages (in the run of a
>>>>> CommitTransactionRequest/Indication).
>>>>>
>>>>> Agreed?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>>> gr. Martin
>>>>>
>>>>>> Eric wrote:
>>>>>>> Hi Eike, Martin,
>>>>>>>
>>>>>>> I did not see that one coming (custom Java code for
>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>> choice than have a model dependency. :(
>>>>>>>
>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>> type and should generate a "String" representation for the
>>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>>> should never be the case?!?
>>>>>>>
>>>>>>> Would there be any other benefits if we have access to the
>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>
>>>>>>> Any thoughts?
>>>>>>>
>>>>>>> Eric
>>>>>>>
>>>>>>> Eike Stepper wrote:
>>>>>>>> Hi Eric, Martin,
>>>>>>>>
>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>>> package at the server side behaves quite different from the
>>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>>> and the respective deserialization code will not be present on
>>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>>> instance classes that you used on client side.
>>>>>>>>
>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>
>>>>>>>> What do you think?
>>>>>>>>
>>>>>>>> Cheers
>>>>>>>> /Eike
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>
>>>>>>>>> Hi Martin, Eike,
>>>>>>>>
>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>> is returning a String and this is causing a
>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>>> following:
>>>>>>>>
>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>> {
>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>> return value;
>>>>>>>>> }
>>>>>>>>
>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>
>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>> statement from my code above.
>>>>>>>>
>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Eric
>>>>>>>>
>>>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120394 is a reply to message #120380] |
Mon, 28 April 2008 15:00 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
So this is again the String from CDO because it is considered a custom
type. So my @Lob annotation wasn't needed at all.
Eric wrote:
> Hi Martin,
>
> the object seems to be a String.
>
> Eric
>
> Martin Taal wrote:
>> Hi Eric,
>> What is the class of the object passed to hibernate? If you put a
>> breakpoint in PersistentArrayHolder.java:45 then you should be able to
>> see it.
>>
>> gr. Martin
>>
>> Eric wrote:
>>> Hi guys,
>>>
>>> Eike, I've created a bugzilla entry and added a test case:
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if
>>> you have any questions.
>>>
>>> Martin, as I explained in Bugzilla, when Teneo is creating the
>>> mapping for my model, I get the following error:
>>> ------
>>> [ERROR] Argument is not an array
>>> java.lang.IllegalArgumentException: Argument is not an array
>>> at java.lang.reflect.Array.getLength(Native Method)
>>> at
>>> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>>>
>>> at
>>> org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
>>> at
>>> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>>>
>>> at
>>> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
>>>
>>> at
>>> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
>>> at
>>> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>>>
>>> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
>>> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
>>> at
>>> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>>>
>>> at
>>> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>>>
>>> at
>>> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>>>
>>> at
>>> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>>>
>>> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
>>> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
>>> Source)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
>>> Source)
>>> at java.lang.Thread.run(Unknown Source)
>>> ------
>>>
>>> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>>>
>>> <array name="barCode" table="`product_barcode`"
>>> cascade="all,delete-orphan">
>>> <key update="true">
>>> <column name="`product_barcode_e_id`" not-null="true"
>>> unique="false"/>
>>> </key>
>>> <list-index column="`product_barcode_idx`"/>
>>> <element type="byte"/>
>>> </array>
>>>
>>> I've seen a few posts with similar problems and one of those posts
>>> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
>>> This triggered a binary blob in my mapping and the mapping became
>>> valid, but I can't understand why this is happening... Is this
>>> (can't process byte[]) a bug?
>>>
>>> Thanks,
>>> Eric
>>>
>>> Eike Stepper wrote:
>>>> Hi guys,
>>>>
>>>> I think the problem is two-fold:
>>>>
>>>> 1) There seem to be users who don't really care about *how* the
>>>> model is persisted. I call these "model centric". In this case a
>>>> String is appropriate for now. As Eric pointed out, this case must
>>>> be supported by the Hibernate layer. Eric, I suggest that you file a
>>>> Bugzilla.
>>>>
>>>> 2) The other group of users can be called "db centric". They want to
>>>> control *how* exactly their models get persisted. If we want to
>>>> support this case we won't be able to go without having the
>>>> generated model code on the server side. It should be easy for the
>>>> Hibernate layer to interrogate the global package registry prior and
>>>> falling back to desrerialization from the db only in case a certain
>>>> package is not globally registered. It is also imagineable to use a
>>>> store-local registry that can be configured individually. I think a
>>>> more complex issue is the question how to get the desired/needed
>>>> packages *into* the used package registry. I see two ways that
>>>> should both be supported:
>>>>
>>>> 2.1) Administratively provisioning the server with the needed
>>>> models. Depending on the chosen registry approach (direct global or
>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>> global registry is used it will be dynamically configured through an
>>>> extension point. If a store-local approach is chosen the registry
>>>> would have to be configured through the server config file which is
>>>> only read on server startup.
>>>>
>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>> issued by the client (which is the standard in CDO). In this case
>>>> both the calculation of the required bundles at client side and the
>>>> transmission over the wire are comparingly easy to solve. What about
>>>> security concerns?
>>>>
>>>> Any thoughts?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Martin Taal schrieb:
>>>>> Hi Eike,
>>>>> Afaics the only way to solve this is to have the possibility to add
>>>>> custom code server side.
>>>>>
>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>> custom server side code. For example to implement server side
>>>>> actions based on triggers generated by hibernate interceptors or
>>>>> eventlisteners.
>>>>>
>>>>> gr. Martin
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Martin Taal wrote:
>>>>>>
>>>>>>> Hi All,
>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>> string
>>>>>> representations there is no
>>>>>>> need for extra server side code. For anything more special, for
>>>>>>> example a
>>>>>> rgb color object then at
>>>>>>> server side some client-specific code needs to be installed also,
>>>>>>> otherwise
>>>>>> Teneo/hibernate does not
>>>>>>> know how to instantiate a usertype.
>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>> This requires
>>>>>> a specific hibernate
>>>>>>> usertype which can translate a colour type to these three
>>>>>>> columns. This
>>>>>> usertype is a custom class
>>>>>>> which needs to be stored at the server.
>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>> environment, or
>>>>>> otherwise how can cdo
>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>> wire,
>>>>>> serialized?
>>>>>>
>>>>>> I would expect that at client side the generated (and hand
>>>>>> modified) model code serializes the custom-typed value into a
>>>>>> string and sends it to the server. so far no modification to the
>>>>>> process necessary.
>>>>>>
>>>>>> But arrived at the server side, we need the same generated and
>>>>>> hand-modified model code with all its dependencies so that the
>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>> the wire to whatever is coded into the model.
>>>>>>
>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>
>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>> the ability to dynamically register new models at the client side.
>>>>>> I propose that we start with a static approach where a deployer is
>>>>>> responsible to manually install the needed bundles at the server
>>>>>> side. If we can make it work this way I can later try to develop
>>>>>> some mechanism that transfers bundles from the client to the
>>>>>> server along with the usual CDOPackages (in the run of a
>>>>>> CommitTransactionRequest/Indication).
>>>>>>
>>>>>> Agreed?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>>> gr. Martin
>>>>>>
>>>>>>> Eric wrote:
>>>>>>>> Hi Eike, Martin,
>>>>>>>>
>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>>> choice than have a model dependency. :(
>>>>>>>>
>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>>> type and should generate a "String" representation for the
>>>>>>>> mapping file. This is not fixing the issue where server-side
>>>>>>>> code would like to see the EMF type, but if I get this right, it
>>>>>>>> should never be the case?!?
>>>>>>>>
>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>
>>>>>>>> Any thoughts?
>>>>>>>>
>>>>>>>> Eric
>>>>>>>>
>>>>>>>> Eike Stepper wrote:
>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>
>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>>> and your generated models to be deployed at the server side.
>>>>>>>>> The new Hibernate integration layer (HibernateStore
>>>>>>>>> implementation) adds a server-side dependency on EMF but not on
>>>>>>>>> your generated models. The HibernateStore uses the serialized
>>>>>>>>> xml string of your client-side model to recreate the EPackage
>>>>>>>>> instances. WRT the custom EDataTypes there is a good chance
>>>>>>>>> that the dynamic package at the server side behaves quite
>>>>>>>>> different from the generated one. IIRC the serialization of
>>>>>>>>> custom EDataTypes relies on manually written code in the
>>>>>>>>> otherwise generated model and the respective deserialization
>>>>>>>>> code will not be present on the server ;-( Not to mention the
>>>>>>>>> potentially non-standard instance classes that you used on
>>>>>>>>> client side.
>>>>>>>>>
>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>
>>>>>>>>> What do you think?
>>>>>>>>>
>>>>>>>>> Cheers
>>>>>>>>> /Eike
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Eric wrote:
>>>>>>>>>
>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>
>>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>>> is returning a String and this is causing a
>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>> the following:
>>>>>>>>>
>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>> {
>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>> return value;
>>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>
>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>> statement from my code above.
>>>>>>>>>
>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>
>>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120433 is a reply to message #120299] |
Mon, 28 April 2008 19:41 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I am not sure if the java class and ecore package are the same. In my view the custom types are
mostly used for simple types, so for example as the instance class in a custom edatatype. These
simple instance classes don't necessarily have to be explicitly modeled.
For the rest I am ofcourse in favor of adding this, at least I think it is a nice extra feature. My
opinion is still that it does not need to be too flexible, imho many times the types are known at
system install/startup time. But that's just my opinion.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> See comments below.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Hi guys,
>>>
>>> I think the problem is two-fold:
>>>
>>> 1) There seem to be users who don't really care about *how* the model
>>> is persisted. I call these "model centric". In this case a String is
>>> appropriate for now. As Eric pointed out, this case must be supported
>>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>> which types are to be stringized because then it should put
>> type="string" in the mapping.But how can it know this?
> I think this should be the fallback approach in case the store is unable
> to reach the generated code for non-basic EDataTypes via 2.1 or 2.2. So
> whenever the mapping engine encounters EDataTypes with an instance class
> which it can't access via its ClassLoader it should use String (or
> something more configurable). Would that be possible?
>
>>> 2) The other group of users can be called "db centric". They want to
>>> control *how* exactly their models get persisted. If we want to
>>> support this case we won't be able to go without having the generated
>>> model code on the server side. It should be easy for the Hibernate
>>> layer to interrogate the global package registry prior and falling
>>> back to desrerialization from the db only in case a certain package
>>> is not globally registered. It is also imagineable to use a
>>> store-local registry that can be configured individually. I think a
>>> more complex issue is the question how to get the desired/needed
>>> packages *into* the used package registry. I see two ways that should
>>> both be supported:
>>
>> MT>> Do you mean java package or ecore package? For the hibernate
>> layer getting access to the required classes is relevant. With
>> required classes I mean the actual class of the value of the attribute
>> and the class for the hibernate converter.
> Aren't Ecore packages and Java packages equivalent here? Since we talk
> about generated models I really mean the generated model bundles which
> contain the model itself plus the generated Java packages. Somewhere in
> this bundle or in its dependency tree the needed instance classes must
> be found, as well as the serialization code to convert between String
> (which comes over the wire) and the instance class.
>
>> MT>> In my view the required models and the java packages implementing
>> model specifics (like types and converters) are fairly static. This
>> means that they can be installed at installation time (and upgrade
>> time) and are not that dynamic. So would the solution not just be to
>> allow the developer to add plugins to the server runtime which provide
>> the value classes and converter and (de-)serializer to get the value
>> objects over the wire?
>> Or what do you think?
> Yes, that's my case 2.1. Case 2.2 would be an additional feature where
> the clients can commit additional packages which would be dynamically
> added to the repository.
>
> If we want to start work on these features I'd suggest that I start on
> the configuration issues (of the server and the config negotiation with
> the client) and then find a way to transfer additional binary data (e.g.
> bundles) with a CommitTransaction Request.
>
> Ok?
>
> Cheers
> /Eike
>
>
>>> 2.1) Administratively provisioning the server with the needed models.
>>> Depending on the chosen registry approach (direct global or
>>> store-local) we could benefit from OSGi dynamic loading. If the
>>> global registry is used it will be dynamically configured through an
>>> extension point. If a store-local approach is chosen the registry
>>> would have to be configured through the server config file which is
>>> only read on server startup.
>>>
>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>> issued by the client (which is the standard in CDO). In this case
>>> both the calculation of the required bundles at client side and the
>>> transmission over the wire are comparingly easy to solve. What about
>>> security concerns?
>>>
>>> Any thoughts?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> Afaics the only way to solve this is to have the possibility to add
>>>> custom code server side.
>>>>
>>>> Btw, I can see also other scenarios were it makes sense to have
>>>> custom server side code. For example to implement server side
>>>> actions based on triggers generated by hibernate interceptors or
>>>> eventlisteners.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Martin Taal wrote:
>>>>>
>>>>>> Hi All,
>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>> string
>>>>> representations there is no
>>>>>> need for extra server side code. For anything more special, for
>>>>>> example a
>>>>> rgb color object then at
>>>>>> server side some client-specific code needs to be installed also,
>>>>>> otherwise
>>>>> Teneo/hibernate does not
>>>>>> know how to instantiate a usertype.
>>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>>> requires
>>>>> a specific hibernate
>>>>>> usertype which can translate a colour type to these three columns.
>>>>>> This
>>>>> usertype is a custom class
>>>>>> which needs to be stored at the server.
>>>>>> Also the custom colour class needs to be added to the server
>>>>>> environment, or
>>>>> otherwise how can cdo
>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>> wire,
>>>>> serialized?
>>>>>
>>>>> I would expect that at client side the generated (and hand
>>>>> modified) model code serializes the custom-typed value into a
>>>>> string and sends it to the server. so far no modification to the
>>>>> process necessary.
>>>>>
>>>>> But arrived at the server side, we need the same generated and
>>>>> hand-modified model code with all its dependencies so that the
>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>> the wire to whatever is coded into the model.
>>>>>
>>>>> Eventually we can look into how to optimize the transfer over the
>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>
>>>>> The main issue I foresee with the above approach is that we lose
>>>>> the ability to dynamically register new models at the client side.
>>>>> I propose that we start with a static approach where a deployer is
>>>>> responsible to manually install the needed bundles at the server
>>>>> side. If we can make it work this way I can later try to develop
>>>>> some mechanism that transfers bundles from the client to the server
>>>>> along with the usual CDOPackages (in the run of a
>>>>> CommitTransactionRequest/Indication).
>>>>>
>>>>> Agreed?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>>> gr. Martin
>>>>>
>>>>>> Eric wrote:
>>>>>>> Hi Eike, Martin,
>>>>>>>
>>>>>>> I did not see that one coming (custom Java code for
>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>> choice than have a model dependency. :(
>>>>>>>
>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>> type and should generate a "String" representation for the
>>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>>> should never be the case?!?
>>>>>>>
>>>>>>> Would there be any other benefits if we have access to the
>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>
>>>>>>> Any thoughts?
>>>>>>>
>>>>>>> Eric
>>>>>>>
>>>>>>> Eike Stepper wrote:
>>>>>>>> Hi Eric, Martin,
>>>>>>>>
>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>>> package at the server side behaves quite different from the
>>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>>> and the respective deserialization code will not be present on
>>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>>> instance classes that you used on client side.
>>>>>>>>
>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>
>>>>>>>> What do you think?
>>>>>>>>
>>>>>>>> Cheers
>>>>>>>> /Eike
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>
>>>>>>>>> Hi Martin, Eike,
>>>>>>>>
>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>> is returning a String and this is causing a
>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>>> following:
>>>>>>>>
>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>> {
>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>> return value;
>>>>>>>>> }
>>>>>>>>
>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>
>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>> statement from my code above.
>>>>>>>>
>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Eric
>>>>>>>>
>>>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120473 is a reply to message #120433] |
Mon, 28 April 2008 20:30 |
Eclipse User |
|
|
|
Originally posted by: stepper.sympedia.de
Martin Taal schrieb:
> Hi Eike,
> I am not sure if the java class and ecore package are the same. In my
> view the custom types are mostly used for simple types, so for example
> as the instance class in a custom edatatype. These simple instance
> classes don't necessarily have to be explicitly modeled.
I think the generated model package will be needed to deserialize the
string that comes over the wire. whether the instance class is modeled
or not doesn't seem to matter since it must be somewhere in the
dependency tree anyway. Do I miss something?
> For the rest I am ofcourse in favor of adding this, at least I think
> it is a nice extra feature. My opinion is still that it does not need
> to be too flexible, imho many times the types are known at system
> install/startup time. But that's just my opinion.
There are also other users being keen on this feature. They want to be
able to dynamically commit the packages with all the code and distribute
them on demand to the other clients. It's just a fortunate accident that
I come to this issue now ;-)
I have https://bugs.eclipse.org/bugs/show_bug.cgi?id=229126 for that.
Cheers
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal schrieb:
>>> Hi Eike,
>>> See comments below.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Hi guys,
>>>>
>>>> I think the problem is two-fold:
>>>>
>>>> 1) There seem to be users who don't really care about *how* the
>>>> model is persisted. I call these "model centric". In this case a
>>>> String is appropriate for now. As Eric pointed out, this case must
>>>> be supported by the Hibernate layer. Eric, I suggest that you file
>>>> a Bugzilla.
>>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>>> which types are to be stringized because then it should put
>>> type="string" in the mapping.But how can it know this?
>> I think this should be the fallback approach in case the store is
>> unable to reach the generated code for non-basic EDataTypes via 2.1
>> or 2.2. So whenever the mapping engine encounters EDataTypes with an
>> instance class which it can't access via its ClassLoader it should
>> use String (or something more configurable). Would that be possible?
>>
>>>> 2) The other group of users can be called "db centric". They want
>>>> to control *how* exactly their models get persisted. If we want to
>>>> support this case we won't be able to go without having the
>>>> generated model code on the server side. It should be easy for the
>>>> Hibernate layer to interrogate the global package registry prior
>>>> and falling back to desrerialization from the db only in case a
>>>> certain package is not globally registered. It is also imagineable
>>>> to use a store-local registry that can be configured individually.
>>>> I think a more complex issue is the question how to get the
>>>> desired/needed packages *into* the used package registry. I see two
>>>> ways that should both be supported:
>>>
>>> MT>> Do you mean java package or ecore package? For the hibernate
>>> layer getting access to the required classes is relevant. With
>>> required classes I mean the actual class of the value of the
>>> attribute and the class for the hibernate converter.
>> Aren't Ecore packages and Java packages equivalent here? Since we
>> talk about generated models I really mean the generated model bundles
>> which contain the model itself plus the generated Java packages.
>> Somewhere in this bundle or in its dependency tree the needed
>> instance classes must be found, as well as the serialization code to
>> convert between String (which comes over the wire) and the instance
>> class.
>>
>>> MT>> In my view the required models and the java packages
>>> implementing model specifics (like types and converters) are fairly
>>> static. This means that they can be installed at installation time
>>> (and upgrade time) and are not that dynamic. So would the solution
>>> not just be to allow the developer to add plugins to the server
>>> runtime which provide the value classes and converter and
>>> (de-)serializer to get the value objects over the wire?
>>> Or what do you think?
>> Yes, that's my case 2.1. Case 2.2 would be an additional feature
>> where the clients can commit additional packages which would be
>> dynamically added to the repository.
>>
>> If we want to start work on these features I'd suggest that I start
>> on the configuration issues (of the server and the config negotiation
>> with the client) and then find a way to transfer additional binary
>> data (e.g. bundles) with a CommitTransaction Request.
>>
>> Ok?
>>
>> Cheers
>> /Eike
>>
>>
>>>> 2.1) Administratively provisioning the server with the needed
>>>> models. Depending on the chosen registry approach (direct global or
>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>> global registry is used it will be dynamically configured through
>>>> an extension point. If a store-local approach is chosen the
>>>> registry would have to be configured through the server config file
>>>> which is only read on server startup.
>>>>
>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>> issued by the client (which is the standard in CDO). In this case
>>>> both the calculation of the required bundles at client side and the
>>>> transmission over the wire are comparingly easy to solve. What
>>>> about security concerns?
>>>>
>>>> Any thoughts?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Martin Taal schrieb:
>>>>> Hi Eike,
>>>>> Afaics the only way to solve this is to have the possibility to
>>>>> add custom code server side.
>>>>>
>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>> custom server side code. For example to implement server side
>>>>> actions based on triggers generated by hibernate interceptors or
>>>>> eventlisteners.
>>>>>
>>>>> gr. Martin
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Martin Taal wrote:
>>>>>>
>>>>>>> Hi All,
>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>> string
>>>>>> representations there is no
>>>>>>> need for extra server side code. For anything more special, for
>>>>>>> example a
>>>>>> rgb color object then at
>>>>>>> server side some client-specific code needs to be installed
>>>>>>> also, otherwise
>>>>>> Teneo/hibernate does not
>>>>>>> know how to instantiate a usertype.
>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>> This requires
>>>>>> a specific hibernate
>>>>>>> usertype which can translate a colour type to these three
>>>>>>> columns. This
>>>>>> usertype is a custom class
>>>>>>> which needs to be stored at the server.
>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>> environment, or
>>>>>> otherwise how can cdo
>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>> wire,
>>>>>> serialized?
>>>>>>
>>>>>> I would expect that at client side the generated (and hand
>>>>>> modified) model code serializes the custom-typed value into a
>>>>>> string and sends it to the server. so far no modification to the
>>>>>> process necessary.
>>>>>>
>>>>>> But arrived at the server side, we need the same generated and
>>>>>> hand-modified model code with all its dependencies so that the
>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>> the wire to whatever is coded into the model.
>>>>>>
>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>
>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>> the ability to dynamically register new models at the client
>>>>>> side. I propose that we start with a static approach where a
>>>>>> deployer is responsible to manually install the needed bundles at
>>>>>> the server side. If we can make it work this way I can later try
>>>>>> to develop some mechanism that transfers bundles from the client
>>>>>> to the server along with the usual CDOPackages (in the run of a
>>>>>> CommitTransactionRequest/Indication).
>>>>>>
>>>>>> Agreed?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>>> gr. Martin
>>>>>>
>>>>>>> Eric wrote:
>>>>>>>> Hi Eike, Martin,
>>>>>>>>
>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>> the "original" type on server-side, you might not have any
>>>>>>>> other choice than have a model dependency. :(
>>>>>>>>
>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>> type on the server. Maybe I'm missing the big picture here,
>>>>>>>> but in my case I was trying to recreate the EMF type in order
>>>>>>>> to store this attribute using Teneo's original mapping (store a
>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>> internal representation of a custom type is a String, as long
>>>>>>>> as I'm accessing it through CDO, I shouldn't care how it is
>>>>>>>> stored in the database. So Teneo could detect (when using CDO
>>>>>>>> only) that the attribute you are trying to persist is in fact a
>>>>>>>> custom type and should generate a "String" representation for
>>>>>>>> the mapping file. This is not fixing the issue where
>>>>>>>> server-side code would like to see the EMF type, but if I get
>>>>>>>> this right, it should never be the case?!?
>>>>>>>>
>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>
>>>>>>>> Any thoughts?
>>>>>>>>
>>>>>>>> Eric
>>>>>>>>
>>>>>>>> Eike Stepper wrote:
>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>
>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require
>>>>>>>>> EMF and your generated models to be deployed at the server
>>>>>>>>> side. The new Hibernate integration layer (HibernateStore
>>>>>>>>> implementation) adds a server-side dependency on EMF but not
>>>>>>>>> on your generated models. The HibernateStore uses the
>>>>>>>>> serialized xml string of your client-side model to recreate
>>>>>>>>> the EPackage instances. WRT the custom EDataTypes there is a
>>>>>>>>> good chance that the dynamic package at the server side
>>>>>>>>> behaves quite different from the generated one. IIRC the
>>>>>>>>> serialization of custom EDataTypes relies on manually written
>>>>>>>>> code in the otherwise generated model and the respective
>>>>>>>>> deserialization code will not be present on the server ;-( Not
>>>>>>>>> to mention the potentially non-standard instance classes that
>>>>>>>>> you used on client side.
>>>>>>>>>
>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>
>>>>>>>>> What do you think?
>>>>>>>>>
>>>>>>>>> Cheers
>>>>>>>>> /Eike
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Eric wrote:
>>>>>>>>>
>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>
>>>>>>>>>> I want to solve a problem I have with custom CDO types.
>>>>>>>>>> To summarize my problem, I have an EMF type with an attribute
>>>>>>>>>> of type byte[] and using Teneo's annotation, I've mapped it
>>>>>>>>>> to a binary blob. When the CDOPropertyGetter returns the
>>>>>>>>>> value, it is returning a String and this is causing a
>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>> the following:
>>>>>>>>>
>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>> {
>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>> return value;
>>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>
>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>> statement from my code above.
>>>>>>>>>
>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>> all require access to the original EMF type... How can I get
>>>>>>>>>> it?
>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>
>>>
>>>
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #120486 is a reply to message #120473] |
Mon, 28 April 2008 20:52 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Yes it must be somewhere in the dependency tree so we mean the same thing.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> I am not sure if the java class and ecore package are the same. In my
>> view the custom types are mostly used for simple types, so for example
>> as the instance class in a custom edatatype. These simple instance
>> classes don't necessarily have to be explicitly modeled.
> I think the generated model package will be needed to deserialize the
> string that comes over the wire. whether the instance class is modeled
> or not doesn't seem to matter since it must be somewhere in the
> dependency tree anyway. Do I miss something?
>
>> For the rest I am ofcourse in favor of adding this, at least I think
>> it is a nice extra feature. My opinion is still that it does not need
>> to be too flexible, imho many times the types are known at system
>> install/startup time. But that's just my opinion.
> There are also other users being keen on this feature. They want to be
> able to dynamically commit the packages with all the code and distribute
> them on demand to the other clients. It's just a fortunate accident that
> I come to this issue now ;-)
> I have https://bugs.eclipse.org/bugs/show_bug.cgi?id=229126 for that.
>
> Cheers
> /Eike
>
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> See comments below.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Hi guys,
>>>>>
>>>>> I think the problem is two-fold:
>>>>>
>>>>> 1) There seem to be users who don't really care about *how* the
>>>>> model is persisted. I call these "model centric". In this case a
>>>>> String is appropriate for now. As Eric pointed out, this case must
>>>>> be supported by the Hibernate layer. Eric, I suggest that you file
>>>>> a Bugzilla.
>>>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>>>> which types are to be stringized because then it should put
>>>> type="string" in the mapping.But how can it know this?
>>> I think this should be the fallback approach in case the store is
>>> unable to reach the generated code for non-basic EDataTypes via 2.1
>>> or 2.2. So whenever the mapping engine encounters EDataTypes with an
>>> instance class which it can't access via its ClassLoader it should
>>> use String (or something more configurable). Would that be possible?
>>>
>>>>> 2) The other group of users can be called "db centric". They want
>>>>> to control *how* exactly their models get persisted. If we want to
>>>>> support this case we won't be able to go without having the
>>>>> generated model code on the server side. It should be easy for the
>>>>> Hibernate layer to interrogate the global package registry prior
>>>>> and falling back to desrerialization from the db only in case a
>>>>> certain package is not globally registered. It is also imagineable
>>>>> to use a store-local registry that can be configured individually.
>>>>> I think a more complex issue is the question how to get the
>>>>> desired/needed packages *into* the used package registry. I see two
>>>>> ways that should both be supported:
>>>>
>>>> MT>> Do you mean java package or ecore package? For the hibernate
>>>> layer getting access to the required classes is relevant. With
>>>> required classes I mean the actual class of the value of the
>>>> attribute and the class for the hibernate converter.
>>> Aren't Ecore packages and Java packages equivalent here? Since we
>>> talk about generated models I really mean the generated model bundles
>>> which contain the model itself plus the generated Java packages.
>>> Somewhere in this bundle or in its dependency tree the needed
>>> instance classes must be found, as well as the serialization code to
>>> convert between String (which comes over the wire) and the instance
>>> class.
>>>
>>>> MT>> In my view the required models and the java packages
>>>> implementing model specifics (like types and converters) are fairly
>>>> static. This means that they can be installed at installation time
>>>> (and upgrade time) and are not that dynamic. So would the solution
>>>> not just be to allow the developer to add plugins to the server
>>>> runtime which provide the value classes and converter and
>>>> (de-)serializer to get the value objects over the wire?
>>>> Or what do you think?
>>> Yes, that's my case 2.1. Case 2.2 would be an additional feature
>>> where the clients can commit additional packages which would be
>>> dynamically added to the repository.
>>>
>>> If we want to start work on these features I'd suggest that I start
>>> on the configuration issues (of the server and the config negotiation
>>> with the client) and then find a way to transfer additional binary
>>> data (e.g. bundles) with a CommitTransaction Request.
>>>
>>> Ok?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>>> 2.1) Administratively provisioning the server with the needed
>>>>> models. Depending on the chosen registry approach (direct global or
>>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>>> global registry is used it will be dynamically configured through
>>>>> an extension point. If a store-local approach is chosen the
>>>>> registry would have to be configured through the server config file
>>>>> which is only read on server startup.
>>>>>
>>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>>> issued by the client (which is the standard in CDO). In this case
>>>>> both the calculation of the required bundles at client side and the
>>>>> transmission over the wire are comparingly easy to solve. What
>>>>> about security concerns?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>> Martin Taal schrieb:
>>>>>> Hi Eike,
>>>>>> Afaics the only way to solve this is to have the possibility to
>>>>>> add custom code server side.
>>>>>>
>>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>>> custom server side code. For example to implement server side
>>>>>> actions based on triggers generated by hibernate interceptors or
>>>>>> eventlisteners.
>>>>>>
>>>>>> gr. Martin
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Martin Taal wrote:
>>>>>>>
>>>>>>>> Hi All,
>>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>>> string
>>>>>>> representations there is no
>>>>>>>> need for extra server side code. For anything more special, for
>>>>>>>> example a
>>>>>>> rgb color object then at
>>>>>>>> server side some client-specific code needs to be installed
>>>>>>>> also, otherwise
>>>>>>> Teneo/hibernate does not
>>>>>>>> know how to instantiate a usertype.
>>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>>> This requires
>>>>>>> a specific hibernate
>>>>>>>> usertype which can translate a colour type to these three
>>>>>>>> columns. This
>>>>>>> usertype is a custom class
>>>>>>>> which needs to be stored at the server.
>>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>>> environment, or
>>>>>>> otherwise how can cdo
>>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>>> wire,
>>>>>>> serialized?
>>>>>>>
>>>>>>> I would expect that at client side the generated (and hand
>>>>>>> modified) model code serializes the custom-typed value into a
>>>>>>> string and sends it to the server. so far no modification to the
>>>>>>> process necessary.
>>>>>>>
>>>>>>> But arrived at the server side, we need the same generated and
>>>>>>> hand-modified model code with all its dependencies so that the
>>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>>> the wire to whatever is coded into the model.
>>>>>>>
>>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>>
>>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>>> the ability to dynamically register new models at the client
>>>>>>> side. I propose that we start with a static approach where a
>>>>>>> deployer is responsible to manually install the needed bundles at
>>>>>>> the server side. If we can make it work this way I can later try
>>>>>>> to develop some mechanism that transfers bundles from the client
>>>>>>> to the server along with the usual CDOPackages (in the run of a
>>>>>>> CommitTransactionRequest/Indication).
>>>>>>>
>>>>>>> Agreed?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> gr. Martin
>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>> Hi Eike, Martin,
>>>>>>>>>
>>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>>> the "original" type on server-side, you might not have any
>>>>>>>>> other choice than have a model dependency. :(
>>>>>>>>>
>>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>>> type on the server. Maybe I'm missing the big picture here,
>>>>>>>>> but in my case I was trying to recreate the EMF type in order
>>>>>>>>> to store this attribute using Teneo's original mapping (store a
>>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>>> internal representation of a custom type is a String, as long
>>>>>>>>> as I'm accessing it through CDO, I shouldn't care how it is
>>>>>>>>> stored in the database. So Teneo could detect (when using CDO
>>>>>>>>> only) that the attribute you are trying to persist is in fact a
>>>>>>>>> custom type and should generate a "String" representation for
>>>>>>>>> the mapping file. This is not fixing the issue where
>>>>>>>>> server-side code would like to see the EMF type, but if I get
>>>>>>>>> this right, it should never be the case?!?
>>>>>>>>>
>>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>>
>>>>>>>>> Any thoughts?
>>>>>>>>>
>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>> Eike Stepper wrote:
>>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>>
>>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require
>>>>>>>>>> EMF and your generated models to be deployed at the server
>>>>>>>>>> side. The new Hibernate integration layer (HibernateStore
>>>>>>>>>> implementation) adds a server-side dependency on EMF but not
>>>>>>>>>> on your generated models. The HibernateStore uses the
>>>>>>>>>> serialized xml string of your client-side model to recreate
>>>>>>>>>> the EPackage instances. WRT the custom EDataTypes there is a
>>>>>>>>>> good chance that the dynamic package at the server side
>>>>>>>>>> behaves quite different from the generated one. IIRC the
>>>>>>>>>> serialization of custom EDataTypes relies on manually written
>>>>>>>>>> code in the otherwise generated model and the respective
>>>>>>>>>> deserialization code will not be present on the server ;-( Not
>>>>>>>>>> to mention the potentially non-standard instance classes that
>>>>>>>>>> you used on client side.
>>>>>>>>>>
>>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>>
>>>>>>>>>> What do you think?
>>>>>>>>>>
>>>>>>>>>> Cheers
>>>>>>>>>> /Eike
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Eric wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>>
>>>>>>>>>>> I want to solve a problem I have with custom CDO types.
>>>>>>>>>>> To summarize my problem, I have an EMF type with an attribute
>>>>>>>>>>> of type byte[] and using Teneo's annotation, I've mapped it
>>>>>>>>>>> to a binary blob. When the CDOPropertyGetter returns the
>>>>>>>>>>> value, it is returning a String and this is causing a
>>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>>> the following:
>>>>>>>>>>
>>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>>> {
>>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>>> return value;
>>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>>
>>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>>> statement from my code above.
>>>>>>>>>>
>>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>>> all require access to the original EMF type... How can I get
>>>>>>>>>>> it?
>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Eric
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>>>
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617908 is a reply to message #119924] |
Fri, 25 April 2008 08:01 |
|
Hi Eric, Martin,
Having read your message I now see a more basic issue with custom
EDataTypes. As you know, CDO itself does not require EMF and your
generated models to be deployed at the server side. The new Hibernate
integration layer (HibernateStore implementation) adds a server-side
dependency on EMF but not on your generated models. The HibernateStore
uses the serialized xml string of your client-side model to recreate the
EPackage instances. WRT the custom EDataTypes there is a good chance that
the dynamic package at the server side behaves quite different from the
generated one. IIRC the serialization of custom EDataTypes relies on
manually written code in the otherwise generated model and the respective
deserialization code will not be present on the server ;-( Not to mention
the potentially non-standard instance classes that you used on client side.
If I'm right, I only see that the generated models, along with all their
dependencies, have to be deployed to the server as well. And we will have
to make sure that the server side EPackage.Registry.INSTANCE is consulted
before we attempt to deserialize the needed EPackages from the xml string
in the db.
What do you think?
Cheers
/Eike
Eric wrote:
> Hi Martin, Eike,
> I want to solve a problem I have with custom CDO types. To summarize
> my problem, I have an EMF type with an attribute of type byte[] and
> using Teneo's annotation, I've mapped it to a binary blob. When the
> CDOPropertyGetter returns the value, it is returning a String and this
> is causing a ClassCastException. So to fix this problem, I'd like to do
> the following:
> In CDOPropertyGetter:
> public Object get(Object target) throws HibernateException
> {
> InternalCDORevision revision = (InternalCDORevision)target;
> Object value = revision.getValue(getCDOFeature());
> if(getCDOFeature().getType() == CDOType.CUSTOM)
> return EcoreUtil.convertFromString(..., value);
> return value;
> }
> where ... would be replaced by the EMF data type.
> Another solution would be to create a CDOCustomPropertyGetter and have
> the CDORevisionTuplizer instantiate it by passing it the concrete EMF
> data type and this CDOCustomPropertyGetter would do the conversion.
> This solution would remove the if statement from my code above.
> Anyhow, there is no unique solution to this problem, but they all
> require access to the original EMF type... How can I get it?
> Thanks,
> Eric
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617912 is a reply to message #119978] |
Fri, 25 April 2008 13:12 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi Eike, Martin,
I did not see that one coming (custom Java code for serialization)...
If this is the case and you want to recreate the "original" type on
server-side, you might not have any other choice than have a model
dependency. :(
That having been said, maybe we don't need to have the EMF type on the
server. Maybe I'm missing the big picture here, but in my case I was
trying to recreate the EMF type in order to store this attribute using
Teneo's original mapping (store a byte[] as a binary blob instead of a
String). Since CDO's internal representation of a custom type is a
String, as long as I'm accessing it through CDO, I shouldn't care how it
is stored in the database. So Teneo could detect (when using CDO only)
that the attribute you are trying to persist is in fact a custom type
and should generate a "String" representation for the mapping file.
This is not fixing the issue where server-side code would like to see
the EMF type, but if I get this right, it should never be the case?!?
Would there be any other benefits if we have access to the model on
server-side? Is it worthwhile?
Any thoughts?
Eric
Eike Stepper wrote:
> Hi Eric, Martin,
>
> Having read your message I now see a more basic issue with custom
> EDataTypes. As you know, CDO itself does not require EMF and your
> generated models to be deployed at the server side. The new Hibernate
> integration layer (HibernateStore implementation) adds a server-side
> dependency on EMF but not on your generated models. The HibernateStore
> uses the serialized xml string of your client-side model to recreate the
> EPackage instances. WRT the custom EDataTypes there is a good chance
> that the dynamic package at the server side behaves quite different from
> the generated one. IIRC the serialization of custom EDataTypes relies on
> manually written code in the otherwise generated model and the
> respective deserialization code will not be present on the server ;-(
> Not to mention the potentially non-standard instance classes that you
> used on client side.
>
> If I'm right, I only see that the generated models, along with all their
> dependencies, have to be deployed to the server as well. And we will
> have to make sure that the server side EPackage.Registry.INSTANCE is
> consulted before we attempt to deserialize the needed EPackages from the
> xml string in the db.
>
> What do you think?
>
> Cheers
> /Eike
>
>
>
> Eric wrote:
>
>> Hi Martin, Eike,
>
>> I want to solve a problem I have with custom CDO types. To
>> summarize my problem, I have an EMF type with an attribute of type
>> byte[] and using Teneo's annotation, I've mapped it to a binary blob.
>> When the CDOPropertyGetter returns the value, it is returning a String
>> and this is causing a ClassCastException. So to fix this problem, I'd
>> like to do the following:
>
>> In CDOPropertyGetter:
>> public Object get(Object target) throws HibernateException
>> {
>> InternalCDORevision revision = (InternalCDORevision)target;
>> Object value = revision.getValue(getCDOFeature());
>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>> return EcoreUtil.convertFromString(..., value);
>> return value;
>> }
>
>> where ... would be replaced by the EMF data type.
>
>> Another solution would be to create a CDOCustomPropertyGetter and have
>> the CDORevisionTuplizer instantiate it by passing it the concrete EMF
>> data type and this CDOCustomPropertyGetter would do the conversion.
>> This solution would remove the if statement from my code above.
>
>> Anyhow, there is no unique solution to this problem, but they all
>> require access to the original EMF type... How can I get it?
>
>> Thanks,
>> Eric
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617913 is a reply to message #120072] |
Fri, 25 April 2008 13:26 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi All,
I think only for primitive types (byte, string, etc.) and their string representations there is no
need for extra server side code. For anything more special, for example a rgb color object then at
server side some client-specific code needs to be installed also, otherwise Teneo/hibernate does not
know how to instantiate a usertype.
Take the example of storing a colour object in 3 int columns. This requires a specific hibernate
usertype which can translate a colour type to these three columns. This usertype is a custom class
which needs to be stored at the server.
Also the custom colour class needs to be added to the server environment, or otherwise how can cdo
handle it? Eike how would the colour instance be passed over the wire, serialized?
gr. Martin
Eric wrote:
> Hi Eike, Martin,
>
> I did not see that one coming (custom Java code for
> serialization)... If this is the case and you want to recreate the
> "original" type on server-side, you might not have any other choice than
> have a model dependency. :(
>
> That having been said, maybe we don't need to have the EMF type on
> the server. Maybe I'm missing the big picture here, but in my case I
> was trying to recreate the EMF type in order to store this attribute
> using Teneo's original mapping (store a byte[] as a binary blob instead
> of a String). Since CDO's internal representation of a custom type is a
> String, as long as I'm accessing it through CDO, I shouldn't care how it
> is stored in the database. So Teneo could detect (when using CDO only)
> that the attribute you are trying to persist is in fact a custom type
> and should generate a "String" representation for the mapping file. This
> is not fixing the issue where server-side code would like to see the EMF
> type, but if I get this right, it should never be the case?!?
>
> Would there be any other benefits if we have access to the model on
> server-side? Is it worthwhile?
>
> Any thoughts?
>
> Eric
>
> Eike Stepper wrote:
>> Hi Eric, Martin,
>>
>> Having read your message I now see a more basic issue with custom
>> EDataTypes. As you know, CDO itself does not require EMF and your
>> generated models to be deployed at the server side. The new Hibernate
>> integration layer (HibernateStore implementation) adds a server-side
>> dependency on EMF but not on your generated models. The HibernateStore
>> uses the serialized xml string of your client-side model to recreate
>> the EPackage instances. WRT the custom EDataTypes there is a good
>> chance that the dynamic package at the server side behaves quite
>> different from the generated one. IIRC the serialization of custom
>> EDataTypes relies on manually written code in the otherwise generated
>> model and the respective deserialization code will not be present on
>> the server ;-( Not to mention the potentially non-standard instance
>> classes that you used on client side.
>>
>> If I'm right, I only see that the generated models, along with all
>> their dependencies, have to be deployed to the server as well. And we
>> will have to make sure that the server side EPackage.Registry.INSTANCE
>> is consulted before we attempt to deserialize the needed EPackages
>> from the xml string in the db.
>>
>> What do you think?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Eric wrote:
>>
>>> Hi Martin, Eike,
>>
>>> I want to solve a problem I have with custom CDO types. To
>>> summarize my problem, I have an EMF type with an attribute of type
>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>> blob. When the CDOPropertyGetter returns the value, it is returning
>>> a String and this is causing a ClassCastException. So to fix this
>>> problem, I'd like to do the following:
>>
>>> In CDOPropertyGetter:
>>> public Object get(Object target) throws HibernateException
>>> {
>>> InternalCDORevision revision = (InternalCDORevision)target;
>>> Object value = revision.getValue(getCDOFeature());
>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>> return EcoreUtil.convertFromString(..., value);
>>> return value;
>>> }
>>
>>> where ... would be replaced by the EMF data type.
>>
>>> Another solution would be to create a CDOCustomPropertyGetter and
>>> have the CDORevisionTuplizer instantiate it by passing it the
>>> concrete EMF data type and this CDOCustomPropertyGetter would do the
>>> conversion. This solution would remove the if statement from my code
>>> above.
>>
>>> Anyhow, there is no unique solution to this problem, but they all
>>> require access to the original EMF type... How can I get it?
>>
>>> Thanks,
>>> Eric
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617914 is a reply to message #120083] |
Fri, 25 April 2008 14:35 |
|
Martin Taal wrote:
> Hi All,
> I think only for primitive types (byte, string, etc.) and their string
representations there is no
> need for extra server side code. For anything more special, for example a
rgb color object then at
> server side some client-specific code needs to be installed also, otherwise
Teneo/hibernate does not
> know how to instantiate a usertype.
> Take the example of storing a colour object in 3 int columns. This requires
a specific hibernate
> usertype which can translate a colour type to these three columns. This
usertype is a custom class
> which needs to be stored at the server.
> Also the custom colour class needs to be added to the server environment, or
otherwise how can cdo
> handle it? Eike how would the colour instance be passed over the wire,
serialized?
I would expect that at client side the generated (and hand modified) model
code serializes the custom-typed value into a string and sends it to the
server. so far no modification to the process necessary.
But arrived at the server side, we need the same generated and
hand-modified model code with all its dependencies so that the Hibernate
layer is able to deserialize the string that comes from the wire to
whatever is coded into the model.
Eventually we can look into how to optimize the transfer over the wire
itself. But I suggest that we go step by step ;-)
The main issue I foresee with the above approach is that we lose the
ability to dynamically register new models at the client side. I propose
that we start with a static approach where a deployer is responsible to
manually install the needed bundles at the server side. If we can make it
work this way I can later try to develop some mechanism that transfers
bundles from the client to the server along with the usual CDOPackages (in
the run of a CommitTransactionRequest/Indication).
Agreed?
Cheers
/Eike
> gr. Martin
> Eric wrote:
>> Hi Eike, Martin,
>>
>> I did not see that one coming (custom Java code for
>> serialization)... If this is the case and you want to recreate the
>> "original" type on server-side, you might not have any other choice than
>> have a model dependency. :(
>>
>> That having been said, maybe we don't need to have the EMF type on
>> the server. Maybe I'm missing the big picture here, but in my case I
>> was trying to recreate the EMF type in order to store this attribute
>> using Teneo's original mapping (store a byte[] as a binary blob instead
>> of a String). Since CDO's internal representation of a custom type is a
>> String, as long as I'm accessing it through CDO, I shouldn't care how it
>> is stored in the database. So Teneo could detect (when using CDO only)
>> that the attribute you are trying to persist is in fact a custom type
>> and should generate a "String" representation for the mapping file. This
>> is not fixing the issue where server-side code would like to see the EMF
>> type, but if I get this right, it should never be the case?!?
>>
>> Would there be any other benefits if we have access to the model on
>> server-side? Is it worthwhile?
>>
>> Any thoughts?
>>
>> Eric
>>
>> Eike Stepper wrote:
>>> Hi Eric, Martin,
>>>
>>> Having read your message I now see a more basic issue with custom
>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>> generated models to be deployed at the server side. The new Hibernate
>>> integration layer (HibernateStore implementation) adds a server-side
>>> dependency on EMF but not on your generated models. The HibernateStore
>>> uses the serialized xml string of your client-side model to recreate
>>> the EPackage instances. WRT the custom EDataTypes there is a good
>>> chance that the dynamic package at the server side behaves quite
>>> different from the generated one. IIRC the serialization of custom
>>> EDataTypes relies on manually written code in the otherwise generated
>>> model and the respective deserialization code will not be present on
>>> the server ;-( Not to mention the potentially non-standard instance
>>> classes that you used on client side.
>>>
>>> If I'm right, I only see that the generated models, along with all
>>> their dependencies, have to be deployed to the server as well. And we
>>> will have to make sure that the server side EPackage.Registry.INSTANCE
>>> is consulted before we attempt to deserialize the needed EPackages
>>> from the xml string in the db.
>>>
>>> What do you think?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Eric wrote:
>>>
>>>> Hi Martin, Eike,
>>>
>>>> I want to solve a problem I have with custom CDO types. To
>>>> summarize my problem, I have an EMF type with an attribute of type
>>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>>> blob. When the CDOPropertyGetter returns the value, it is returning
>>>> a String and this is causing a ClassCastException. So to fix this
>>>> problem, I'd like to do the following:
>>>
>>>> In CDOPropertyGetter:
>>>> public Object get(Object target) throws HibernateException
>>>> {
>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>> Object value = revision.getValue(getCDOFeature());
>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>> return EcoreUtil.convertFromString(..., value);
>>>> return value;
>>>> }
>>>
>>>> where ... would be replaced by the EMF data type.
>>>
>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>> concrete EMF data type and this CDOCustomPropertyGetter would do the
>>>> conversion. This solution would remove the if statement from my code
>>>> above.
>>>
>>>> Anyhow, there is no unique solution to this problem, but they all
>>>> require access to the original EMF type... How can I get it?
>>>
>>>> Thanks,
>>>> Eric
>>>
>>>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617919 is a reply to message #120095] |
Fri, 25 April 2008 18:09 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
Afaics the only way to solve this is to have the possibility to add custom code server side.
Btw, I can see also other scenarios were it makes sense to have custom server side code. For example
to implement server side actions based on triggers generated by hibernate interceptors or
eventlisteners.
gr. Martin
Eike Stepper wrote:
> Martin Taal wrote:
>
>> Hi All,
>> I think only for primitive types (byte, string, etc.) and their string
> representations there is no
>> need for extra server side code. For anything more special, for example a
> rgb color object then at
>> server side some client-specific code needs to be installed also,
>> otherwise
> Teneo/hibernate does not
>> know how to instantiate a usertype.
>> Take the example of storing a colour object in 3 int columns. This
>> requires
> a specific hibernate
>> usertype which can translate a colour type to these three columns. This
> usertype is a custom class
>> which needs to be stored at the server.
>> Also the custom colour class needs to be added to the server
>> environment, or
> otherwise how can cdo
>> handle it? Eike how would the colour instance be passed over the wire,
> serialized?
>
> I would expect that at client side the generated (and hand modified)
> model code serializes the custom-typed value into a string and sends it
> to the server. so far no modification to the process necessary.
>
> But arrived at the server side, we need the same generated and
> hand-modified model code with all its dependencies so that the Hibernate
> layer is able to deserialize the string that comes from the wire to
> whatever is coded into the model.
>
> Eventually we can look into how to optimize the transfer over the wire
> itself. But I suggest that we go step by step ;-)
>
> The main issue I foresee with the above approach is that we lose the
> ability to dynamically register new models at the client side. I propose
> that we start with a static approach where a deployer is responsible to
> manually install the needed bundles at the server side. If we can make
> it work this way I can later try to develop some mechanism that
> transfers bundles from the client to the server along with the usual
> CDOPackages (in the run of a CommitTransactionRequest/Indication).
>
> Agreed?
>
> Cheers
> /Eike
>
>
>
>> gr. Martin
>
>> Eric wrote:
>>> Hi Eike, Martin,
>>>
>>> I did not see that one coming (custom Java code for
>>> serialization)... If this is the case and you want to recreate the
>>> "original" type on server-side, you might not have any other choice
>>> than have a model dependency. :(
>>>
>>> That having been said, maybe we don't need to have the EMF type
>>> on the server. Maybe I'm missing the big picture here, but in my
>>> case I was trying to recreate the EMF type in order to store this
>>> attribute using Teneo's original mapping (store a byte[] as a binary
>>> blob instead of a String). Since CDO's internal representation of a
>>> custom type is a String, as long as I'm accessing it through CDO, I
>>> shouldn't care how it is stored in the database. So Teneo could
>>> detect (when using CDO only) that the attribute you are trying to
>>> persist is in fact a custom type and should generate a "String"
>>> representation for the mapping file. This is not fixing the issue
>>> where server-side code would like to see the EMF type, but if I get
>>> this right, it should never be the case?!?
>>>
>>> Would there be any other benefits if we have access to the model
>>> on server-side? Is it worthwhile?
>>>
>>> Any thoughts?
>>>
>>> Eric
>>>
>>> Eike Stepper wrote:
>>>> Hi Eric, Martin,
>>>>
>>>> Having read your message I now see a more basic issue with custom
>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>> generated models to be deployed at the server side. The new
>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>> server-side dependency on EMF but not on your generated models. The
>>>> HibernateStore uses the serialized xml string of your client-side
>>>> model to recreate the EPackage instances. WRT the custom EDataTypes
>>>> there is a good chance that the dynamic package at the server side
>>>> behaves quite different from the generated one. IIRC the
>>>> serialization of custom EDataTypes relies on manually written code
>>>> in the otherwise generated model and the respective deserialization
>>>> code will not be present on the server ;-( Not to mention the
>>>> potentially non-standard instance classes that you used on client side.
>>>>
>>>> If I'm right, I only see that the generated models, along with all
>>>> their dependencies, have to be deployed to the server as well. And
>>>> we will have to make sure that the server side
>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>> deserialize the needed EPackages from the xml string in the db.
>>>>
>>>> What do you think?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Eric wrote:
>>>>
>>>>> Hi Martin, Eike,
>>>>
>>>>> I want to solve a problem I have with custom CDO types. To
>>>>> summarize my problem, I have an EMF type with an attribute of type
>>>>> byte[] and using Teneo's annotation, I've mapped it to a binary
>>>>> blob. When the CDOPropertyGetter returns the value, it is
>>>>> returning a String and this is causing a ClassCastException. So to
>>>>> fix this problem, I'd like to do the following:
>>>>
>>>>> In CDOPropertyGetter:
>>>>> public Object get(Object target) throws HibernateException
>>>>> {
>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>> Object value = revision.getValue(getCDOFeature());
>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>> return EcoreUtil.convertFromString(..., value);
>>>>> return value;
>>>>> }
>>>>
>>>>> where ... would be replaced by the EMF data type.
>>>>
>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>> the conversion. This solution would remove the if statement from my
>>>>> code above.
>>>>
>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>> require access to the original EMF type... How can I get it?
>>>>
>>>>> Thanks,
>>>>> Eric
>>>>
>>>>
>
>
>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617921 is a reply to message #120165] |
Sat, 26 April 2008 09:20 |
|
Hi guys,
I think the problem is two-fold:
1) There seem to be users who don't really care about *how* the model is
persisted. I call these "model centric". In this case a String is
appropriate for now. As Eric pointed out, this case must be supported by
the Hibernate layer. Eric, I suggest that you file a Bugzilla.
2) The other group of users can be called "db centric". They want to
control *how* exactly their models get persisted. If we want to support
this case we won't be able to go without having the generated model code
on the server side. It should be easy for the Hibernate layer to
interrogate the global package registry prior and falling back to
desrerialization from the db only in case a certain package is not
globally registered. It is also imagineable to use a store-local
registry that can be configured individually. I think a more complex
issue is the question how to get the desired/needed packages *into* the
used package registry. I see two ways that should both be supported:
2.1) Administratively provisioning the server with the needed models.
Depending on the chosen registry approach (direct global or store-local)
we could benefit from OSGi dynamic loading. If the global registry is
used it will be dynamically configured through an extension point. If a
store-local approach is chosen the registry would have to be configured
through the server config file which is only read on server startup.
2.2) Dynamically adding models through CommitTransactionRequests issued
by the client (which is the standard in CDO). In this case both the
calculation of the required bundles at client side and the transmission
over the wire are comparingly easy to solve. What about security concerns?
Any thoughts?
Cheers
/Eike
Martin Taal schrieb:
> Hi Eike,
> Afaics the only way to solve this is to have the possibility to add
> custom code server side.
>
> Btw, I can see also other scenarios were it makes sense to have custom
> server side code. For example to implement server side actions based
> on triggers generated by hibernate interceptors or eventlisteners.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal wrote:
>>
>>> Hi All,
>>> I think only for primitive types (byte, string, etc.) and their string
>> representations there is no
>>> need for extra server side code. For anything more special, for
>>> example a
>> rgb color object then at
>>> server side some client-specific code needs to be installed also,
>>> otherwise
>> Teneo/hibernate does not
>>> know how to instantiate a usertype.
>>> Take the example of storing a colour object in 3 int columns. This
>>> requires
>> a specific hibernate
>>> usertype which can translate a colour type to these three columns. This
>> usertype is a custom class
>>> which needs to be stored at the server.
>>> Also the custom colour class needs to be added to the server
>>> environment, or
>> otherwise how can cdo
>>> handle it? Eike how would the colour instance be passed over the wire,
>> serialized?
>>
>> I would expect that at client side the generated (and hand modified)
>> model code serializes the custom-typed value into a string and sends
>> it to the server. so far no modification to the process necessary.
>>
>> But arrived at the server side, we need the same generated and
>> hand-modified model code with all its dependencies so that the
>> Hibernate layer is able to deserialize the string that comes from the
>> wire to whatever is coded into the model.
>>
>> Eventually we can look into how to optimize the transfer over the
>> wire itself. But I suggest that we go step by step ;-)
>>
>> The main issue I foresee with the above approach is that we lose the
>> ability to dynamically register new models at the client side. I
>> propose that we start with a static approach where a deployer is
>> responsible to manually install the needed bundles at the server
>> side. If we can make it work this way I can later try to develop some
>> mechanism that transfers bundles from the client to the server along
>> with the usual CDOPackages (in the run of a
>> CommitTransactionRequest/Indication).
>>
>> Agreed?
>>
>> Cheers
>> /Eike
>>
>>
>>
>>> gr. Martin
>>
>>> Eric wrote:
>>>> Hi Eike, Martin,
>>>>
>>>> I did not see that one coming (custom Java code for
>>>> serialization)... If this is the case and you want to recreate the
>>>> "original" type on server-side, you might not have any other choice
>>>> than have a model dependency. :(
>>>>
>>>> That having been said, maybe we don't need to have the EMF type
>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>> case I was trying to recreate the EMF type in order to store this
>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>> binary blob instead of a String). Since CDO's internal
>>>> representation of a custom type is a String, as long as I'm
>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>> database. So Teneo could detect (when using CDO only) that the
>>>> attribute you are trying to persist is in fact a custom type and
>>>> should generate a "String" representation for the mapping file.
>>>> This is not fixing the issue where server-side code would like to
>>>> see the EMF type, but if I get this right, it should never be the
>>>> case?!?
>>>>
>>>> Would there be any other benefits if we have access to the
>>>> model on server-side? Is it worthwhile?
>>>>
>>>> Any thoughts?
>>>>
>>>> Eric
>>>>
>>>> Eike Stepper wrote:
>>>>> Hi Eric, Martin,
>>>>>
>>>>> Having read your message I now see a more basic issue with custom
>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>> generated models to be deployed at the server side. The new
>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>> server-side dependency on EMF but not on your generated models.
>>>>> The HibernateStore uses the serialized xml string of your
>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>> at the server side behaves quite different from the generated one.
>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>> written code in the otherwise generated model and the respective
>>>>> deserialization code will not be present on the server ;-( Not to
>>>>> mention the potentially non-standard instance classes that you
>>>>> used on client side.
>>>>>
>>>>> If I'm right, I only see that the generated models, along with all
>>>>> their dependencies, have to be deployed to the server as well. And
>>>>> we will have to make sure that the server side
>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>
>>>>> What do you think?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>> Eric wrote:
>>>>>
>>>>>> Hi Martin, Eike,
>>>>>
>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>> to fix this problem, I'd like to do the following:
>>>>>
>>>>>> In CDOPropertyGetter:
>>>>>> public Object get(Object target) throws HibernateException
>>>>>> {
>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>> return value;
>>>>>> }
>>>>>
>>>>>> where ... would be replaced by the EMF data type.
>>>>>
>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>> the conversion. This solution would remove the if statement from
>>>>>> my code above.
>>>>>
>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>> require access to the original EMF type... How can I get it?
>>>>>
>>>>>> Thanks,
>>>>>> Eric
>>>>>
>>>>>
>>
>>
>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617927 is a reply to message #120191] |
Sun, 27 April 2008 20:52 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
See comments below.
gr. Martin
Eike Stepper wrote:
> Hi guys,
>
> I think the problem is two-fold:
>
> 1) There seem to be users who don't really care about *how* the model is
> persisted. I call these "model centric". In this case a String is
> appropriate for now. As Eric pointed out, this case must be supported by
> the Hibernate layer. Eric, I suggest that you file a Bugzilla.
MT>> Yes I agree, I am not sure how the hibernate layer would know which types are to be stringized
because then it should put type="string" in the mapping.But how can it know this?
>
> 2) The other group of users can be called "db centric". They want to
> control *how* exactly their models get persisted. If we want to support
> this case we won't be able to go without having the generated model code
> on the server side. It should be easy for the Hibernate layer to
> interrogate the global package registry prior and falling back to
> desrerialization from the db only in case a certain package is not
> globally registered. It is also imagineable to use a store-local
> registry that can be configured individually. I think a more complex
> issue is the question how to get the desired/needed packages *into* the
> used package registry. I see two ways that should both be supported:
MT>> Do you mean java package or ecore package? For the hibernate layer getting access to the
required classes is relevant. With required classes I mean the actual class of the value of the
attribute and the class for the hibernate converter.
MT>> In my view the required models and the java packages implementing model specifics (like types
and converters) are fairly static. This means that they can be installed at installation time (and
upgrade time) and are not that dynamic. So would the solution not just be to allow the developer to
add plugins to the server runtime which provide the value classes and converter and (de-)serializer
to get the value objects over the wire?
Or what do you think?
>
> 2.1) Administratively provisioning the server with the needed models.
> Depending on the chosen registry approach (direct global or store-local)
> we could benefit from OSGi dynamic loading. If the global registry is
> used it will be dynamically configured through an extension point. If a
> store-local approach is chosen the registry would have to be configured
> through the server config file which is only read on server startup.
>
> 2.2) Dynamically adding models through CommitTransactionRequests issued
> by the client (which is the standard in CDO). In this case both the
> calculation of the required bundles at client side and the transmission
> over the wire are comparingly easy to solve. What about security concerns?
>
> Any thoughts?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Eike,
>> Afaics the only way to solve this is to have the possibility to add
>> custom code server side.
>>
>> Btw, I can see also other scenarios were it makes sense to have custom
>> server side code. For example to implement server side actions based
>> on triggers generated by hibernate interceptors or eventlisteners.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal wrote:
>>>
>>>> Hi All,
>>>> I think only for primitive types (byte, string, etc.) and their string
>>> representations there is no
>>>> need for extra server side code. For anything more special, for
>>>> example a
>>> rgb color object then at
>>>> server side some client-specific code needs to be installed also,
>>>> otherwise
>>> Teneo/hibernate does not
>>>> know how to instantiate a usertype.
>>>> Take the example of storing a colour object in 3 int columns. This
>>>> requires
>>> a specific hibernate
>>>> usertype which can translate a colour type to these three columns. This
>>> usertype is a custom class
>>>> which needs to be stored at the server.
>>>> Also the custom colour class needs to be added to the server
>>>> environment, or
>>> otherwise how can cdo
>>>> handle it? Eike how would the colour instance be passed over the wire,
>>> serialized?
>>>
>>> I would expect that at client side the generated (and hand modified)
>>> model code serializes the custom-typed value into a string and sends
>>> it to the server. so far no modification to the process necessary.
>>>
>>> But arrived at the server side, we need the same generated and
>>> hand-modified model code with all its dependencies so that the
>>> Hibernate layer is able to deserialize the string that comes from the
>>> wire to whatever is coded into the model.
>>>
>>> Eventually we can look into how to optimize the transfer over the
>>> wire itself. But I suggest that we go step by step ;-)
>>>
>>> The main issue I foresee with the above approach is that we lose the
>>> ability to dynamically register new models at the client side. I
>>> propose that we start with a static approach where a deployer is
>>> responsible to manually install the needed bundles at the server
>>> side. If we can make it work this way I can later try to develop some
>>> mechanism that transfers bundles from the client to the server along
>>> with the usual CDOPackages (in the run of a
>>> CommitTransactionRequest/Indication).
>>>
>>> Agreed?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>>> gr. Martin
>>>
>>>> Eric wrote:
>>>>> Hi Eike, Martin,
>>>>>
>>>>> I did not see that one coming (custom Java code for
>>>>> serialization)... If this is the case and you want to recreate the
>>>>> "original" type on server-side, you might not have any other choice
>>>>> than have a model dependency. :(
>>>>>
>>>>> That having been said, maybe we don't need to have the EMF type
>>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>>> case I was trying to recreate the EMF type in order to store this
>>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>>> binary blob instead of a String). Since CDO's internal
>>>>> representation of a custom type is a String, as long as I'm
>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>> attribute you are trying to persist is in fact a custom type and
>>>>> should generate a "String" representation for the mapping file.
>>>>> This is not fixing the issue where server-side code would like to
>>>>> see the EMF type, but if I get this right, it should never be the
>>>>> case?!?
>>>>>
>>>>> Would there be any other benefits if we have access to the
>>>>> model on server-side? Is it worthwhile?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Eric
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Hi Eric, Martin,
>>>>>>
>>>>>> Having read your message I now see a more basic issue with custom
>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>> generated models to be deployed at the server side. The new
>>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>>> server-side dependency on EMF but not on your generated models.
>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>> at the server side behaves quite different from the generated one.
>>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>>> written code in the otherwise generated model and the respective
>>>>>> deserialization code will not be present on the server ;-( Not to
>>>>>> mention the potentially non-standard instance classes that you
>>>>>> used on client side.
>>>>>>
>>>>>> If I'm right, I only see that the generated models, along with all
>>>>>> their dependencies, have to be deployed to the server as well. And
>>>>>> we will have to make sure that the server side
>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>> Eric wrote:
>>>>>>
>>>>>>> Hi Martin, Eike,
>>>>>>
>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>>> to fix this problem, I'd like to do the following:
>>>>>>
>>>>>>> In CDOPropertyGetter:
>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>> {
>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>> return value;
>>>>>>> }
>>>>>>
>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>
>>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>>> the conversion. This solution would remove the if statement from
>>>>>>> my code above.
>>>>>>
>>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>>> require access to the original EMF type... How can I get it?
>>>>>>
>>>>>>> Thanks,
>>>>>>> Eric
>>>>>>
>>>>>>
>>>
>>>
>>>
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617929 is a reply to message #120274] |
Mon, 28 April 2008 06:50 |
|
Martin Taal schrieb:
> Hi Eike,
> See comments below.
>
> gr. Martin
>
> Eike Stepper wrote:
>> Hi guys,
>>
>> I think the problem is two-fold:
>>
>> 1) There seem to be users who don't really care about *how* the model
>> is persisted. I call these "model centric". In this case a String is
>> appropriate for now. As Eric pointed out, this case must be supported
>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
> MT>> Yes I agree, I am not sure how the hibernate layer would know
> which types are to be stringized because then it should put
> type="string" in the mapping.But how can it know this?
I think this should be the fallback approach in case the store is unable
to reach the generated code for non-basic EDataTypes via 2.1 or 2.2. So
whenever the mapping engine encounters EDataTypes with an instance class
which it can't access via its ClassLoader it should use String (or
something more configurable). Would that be possible?
>> 2) The other group of users can be called "db centric". They want to
>> control *how* exactly their models get persisted. If we want to
>> support this case we won't be able to go without having the generated
>> model code on the server side. It should be easy for the Hibernate
>> layer to interrogate the global package registry prior and falling
>> back to desrerialization from the db only in case a certain package
>> is not globally registered. It is also imagineable to use a
>> store-local registry that can be configured individually. I think a
>> more complex issue is the question how to get the desired/needed
>> packages *into* the used package registry. I see two ways that should
>> both be supported:
>
> MT>> Do you mean java package or ecore package? For the hibernate
> layer getting access to the required classes is relevant. With
> required classes I mean the actual class of the value of the attribute
> and the class for the hibernate converter.
Aren't Ecore packages and Java packages equivalent here? Since we talk
about generated models I really mean the generated model bundles which
contain the model itself plus the generated Java packages. Somewhere in
this bundle or in its dependency tree the needed instance classes must
be found, as well as the serialization code to convert between String
(which comes over the wire) and the instance class.
> MT>> In my view the required models and the java packages implementing
> model specifics (like types and converters) are fairly static. This
> means that they can be installed at installation time (and upgrade
> time) and are not that dynamic. So would the solution not just be to
> allow the developer to add plugins to the server runtime which provide
> the value classes and converter and (de-)serializer to get the value
> objects over the wire?
> Or what do you think?
Yes, that's my case 2.1. Case 2.2 would be an additional feature where
the clients can commit additional packages which would be dynamically
added to the repository.
If we want to start work on these features I'd suggest that I start on
the configuration issues (of the server and the config negotiation with
the client) and then find a way to transfer additional binary data (e.g.
bundles) with a CommitTransaction Request.
Ok?
Cheers
/Eike
>> 2.1) Administratively provisioning the server with the needed models.
>> Depending on the chosen registry approach (direct global or
>> store-local) we could benefit from OSGi dynamic loading. If the
>> global registry is used it will be dynamically configured through an
>> extension point. If a store-local approach is chosen the registry
>> would have to be configured through the server config file which is
>> only read on server startup.
>>
>> 2.2) Dynamically adding models through CommitTransactionRequests
>> issued by the client (which is the standard in CDO). In this case
>> both the calculation of the required bundles at client side and the
>> transmission over the wire are comparingly easy to solve. What about
>> security concerns?
>>
>> Any thoughts?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Eike,
>>> Afaics the only way to solve this is to have the possibility to add
>>> custom code server side.
>>>
>>> Btw, I can see also other scenarios were it makes sense to have
>>> custom server side code. For example to implement server side
>>> actions based on triggers generated by hibernate interceptors or
>>> eventlisteners.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Martin Taal wrote:
>>>>
>>>>> Hi All,
>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>> string
>>>> representations there is no
>>>>> need for extra server side code. For anything more special, for
>>>>> example a
>>>> rgb color object then at
>>>>> server side some client-specific code needs to be installed also,
>>>>> otherwise
>>>> Teneo/hibernate does not
>>>>> know how to instantiate a usertype.
>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>> requires
>>>> a specific hibernate
>>>>> usertype which can translate a colour type to these three columns.
>>>>> This
>>>> usertype is a custom class
>>>>> which needs to be stored at the server.
>>>>> Also the custom colour class needs to be added to the server
>>>>> environment, or
>>>> otherwise how can cdo
>>>>> handle it? Eike how would the colour instance be passed over the
>>>>> wire,
>>>> serialized?
>>>>
>>>> I would expect that at client side the generated (and hand
>>>> modified) model code serializes the custom-typed value into a
>>>> string and sends it to the server. so far no modification to the
>>>> process necessary.
>>>>
>>>> But arrived at the server side, we need the same generated and
>>>> hand-modified model code with all its dependencies so that the
>>>> Hibernate layer is able to deserialize the string that comes from
>>>> the wire to whatever is coded into the model.
>>>>
>>>> Eventually we can look into how to optimize the transfer over the
>>>> wire itself. But I suggest that we go step by step ;-)
>>>>
>>>> The main issue I foresee with the above approach is that we lose
>>>> the ability to dynamically register new models at the client side.
>>>> I propose that we start with a static approach where a deployer is
>>>> responsible to manually install the needed bundles at the server
>>>> side. If we can make it work this way I can later try to develop
>>>> some mechanism that transfers bundles from the client to the server
>>>> along with the usual CDOPackages (in the run of a
>>>> CommitTransactionRequest/Indication).
>>>>
>>>> Agreed?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>>> gr. Martin
>>>>
>>>>> Eric wrote:
>>>>>> Hi Eike, Martin,
>>>>>>
>>>>>> I did not see that one coming (custom Java code for
>>>>>> serialization)... If this is the case and you want to recreate
>>>>>> the "original" type on server-side, you might not have any other
>>>>>> choice than have a model dependency. :(
>>>>>>
>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>> internal representation of a custom type is a String, as long as
>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>> type and should generate a "String" representation for the
>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>> should never be the case?!?
>>>>>>
>>>>>> Would there be any other benefits if we have access to the
>>>>>> model on server-side? Is it worthwhile?
>>>>>>
>>>>>> Any thoughts?
>>>>>>
>>>>>> Eric
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Hi Eric, Martin,
>>>>>>>
>>>>>>> Having read your message I now see a more basic issue with
>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>> package at the server side behaves quite different from the
>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>> and the respective deserialization code will not be present on
>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>> instance classes that you used on client side.
>>>>>>>
>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>> well. And we will have to make sure that the server side
>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Eric wrote:
>>>>>>>
>>>>>>>> Hi Martin, Eike,
>>>>>>>
>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>> is returning a String and this is causing a
>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>> following:
>>>>>>>
>>>>>>>> In CDOPropertyGetter:
>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>> {
>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>> return value;
>>>>>>>> }
>>>>>>>
>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>
>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>> statement from my code above.
>>>>>>>
>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Eric
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>>
>>>
>>>
>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617932 is a reply to message #120191] |
Mon, 28 April 2008 14:12 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi guys,
Eike, I've created a bugzilla entry and added a test case:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if you
have any questions.
Martin, as I explained in Bugzilla, when Teneo is creating the
mapping for my model, I get the following error:
------
[ERROR] Argument is not an array
java.lang.IllegalArgumentException: Argument is not an array
at java.lang.reflect.Array.getLength(Native Method)
at
org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
at org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
at
org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
at
org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
at
org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
at
org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
at
org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
at org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
at
org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
at
org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
at
org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
at
org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
at
org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
at
org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
at
org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
at
org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
at
org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
at
org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
------
My attribute is a byte array (byte[]) and here is Teneo's mapping:
<array name="barCode" table="`product_barcode`"
cascade="all,delete-orphan">
<key update="true">
<column name="`product_barcode_e_id`" not-null="true" unique="false"/>
</key>
<list-index column="`product_barcode_idx`"/>
<element type="byte"/>
</array>
I've seen a few posts with similar problems and one of those posts
suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
This triggered a binary blob in my mapping and the mapping became valid,
but I can't understand why this is happening... Is this (can't process
byte[]) a bug?
Thanks,
Eric
Eike Stepper wrote:
> Hi guys,
>
> I think the problem is two-fold:
>
> 1) There seem to be users who don't really care about *how* the model is
> persisted. I call these "model centric". In this case a String is
> appropriate for now. As Eric pointed out, this case must be supported by
> the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>
> 2) The other group of users can be called "db centric". They want to
> control *how* exactly their models get persisted. If we want to support
> this case we won't be able to go without having the generated model code
> on the server side. It should be easy for the Hibernate layer to
> interrogate the global package registry prior and falling back to
> desrerialization from the db only in case a certain package is not
> globally registered. It is also imagineable to use a store-local
> registry that can be configured individually. I think a more complex
> issue is the question how to get the desired/needed packages *into* the
> used package registry. I see two ways that should both be supported:
>
> 2.1) Administratively provisioning the server with the needed models.
> Depending on the chosen registry approach (direct global or store-local)
> we could benefit from OSGi dynamic loading. If the global registry is
> used it will be dynamically configured through an extension point. If a
> store-local approach is chosen the registry would have to be configured
> through the server config file which is only read on server startup.
>
> 2.2) Dynamically adding models through CommitTransactionRequests issued
> by the client (which is the standard in CDO). In this case both the
> calculation of the required bundles at client side and the transmission
> over the wire are comparingly easy to solve. What about security concerns?
>
> Any thoughts?
>
> Cheers
> /Eike
>
>
>
> Martin Taal schrieb:
>> Hi Eike,
>> Afaics the only way to solve this is to have the possibility to add
>> custom code server side.
>>
>> Btw, I can see also other scenarios were it makes sense to have custom
>> server side code. For example to implement server side actions based
>> on triggers generated by hibernate interceptors or eventlisteners.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal wrote:
>>>
>>>> Hi All,
>>>> I think only for primitive types (byte, string, etc.) and their string
>>> representations there is no
>>>> need for extra server side code. For anything more special, for
>>>> example a
>>> rgb color object then at
>>>> server side some client-specific code needs to be installed also,
>>>> otherwise
>>> Teneo/hibernate does not
>>>> know how to instantiate a usertype.
>>>> Take the example of storing a colour object in 3 int columns. This
>>>> requires
>>> a specific hibernate
>>>> usertype which can translate a colour type to these three columns. This
>>> usertype is a custom class
>>>> which needs to be stored at the server.
>>>> Also the custom colour class needs to be added to the server
>>>> environment, or
>>> otherwise how can cdo
>>>> handle it? Eike how would the colour instance be passed over the wire,
>>> serialized?
>>>
>>> I would expect that at client side the generated (and hand modified)
>>> model code serializes the custom-typed value into a string and sends
>>> it to the server. so far no modification to the process necessary.
>>>
>>> But arrived at the server side, we need the same generated and
>>> hand-modified model code with all its dependencies so that the
>>> Hibernate layer is able to deserialize the string that comes from the
>>> wire to whatever is coded into the model.
>>>
>>> Eventually we can look into how to optimize the transfer over the
>>> wire itself. But I suggest that we go step by step ;-)
>>>
>>> The main issue I foresee with the above approach is that we lose the
>>> ability to dynamically register new models at the client side. I
>>> propose that we start with a static approach where a deployer is
>>> responsible to manually install the needed bundles at the server
>>> side. If we can make it work this way I can later try to develop some
>>> mechanism that transfers bundles from the client to the server along
>>> with the usual CDOPackages (in the run of a
>>> CommitTransactionRequest/Indication).
>>>
>>> Agreed?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>>> gr. Martin
>>>
>>>> Eric wrote:
>>>>> Hi Eike, Martin,
>>>>>
>>>>> I did not see that one coming (custom Java code for
>>>>> serialization)... If this is the case and you want to recreate the
>>>>> "original" type on server-side, you might not have any other choice
>>>>> than have a model dependency. :(
>>>>>
>>>>> That having been said, maybe we don't need to have the EMF type
>>>>> on the server. Maybe I'm missing the big picture here, but in my
>>>>> case I was trying to recreate the EMF type in order to store this
>>>>> attribute using Teneo's original mapping (store a byte[] as a
>>>>> binary blob instead of a String). Since CDO's internal
>>>>> representation of a custom type is a String, as long as I'm
>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>> attribute you are trying to persist is in fact a custom type and
>>>>> should generate a "String" representation for the mapping file.
>>>>> This is not fixing the issue where server-side code would like to
>>>>> see the EMF type, but if I get this right, it should never be the
>>>>> case?!?
>>>>>
>>>>> Would there be any other benefits if we have access to the
>>>>> model on server-side? Is it worthwhile?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Eric
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Hi Eric, Martin,
>>>>>>
>>>>>> Having read your message I now see a more basic issue with custom
>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>> generated models to be deployed at the server side. The new
>>>>>> Hibernate integration layer (HibernateStore implementation) adds a
>>>>>> server-side dependency on EMF but not on your generated models.
>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>> at the server side behaves quite different from the generated one.
>>>>>> IIRC the serialization of custom EDataTypes relies on manually
>>>>>> written code in the otherwise generated model and the respective
>>>>>> deserialization code will not be present on the server ;-( Not to
>>>>>> mention the potentially non-standard instance classes that you
>>>>>> used on client side.
>>>>>>
>>>>>> If I'm right, I only see that the generated models, along with all
>>>>>> their dependencies, have to be deployed to the server as well. And
>>>>>> we will have to make sure that the server side
>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>> Eric wrote:
>>>>>>
>>>>>>> Hi Martin, Eike,
>>>>>>
>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it is
>>>>>>> returning a String and this is causing a ClassCastException. So
>>>>>>> to fix this problem, I'd like to do the following:
>>>>>>
>>>>>>> In CDOPropertyGetter:
>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>> {
>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>> return value;
>>>>>>> }
>>>>>>
>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>
>>>>>>> Another solution would be to create a CDOCustomPropertyGetter and
>>>>>>> have the CDORevisionTuplizer instantiate it by passing it the
>>>>>>> concrete EMF data type and this CDOCustomPropertyGetter would do
>>>>>>> the conversion. This solution would remove the if statement from
>>>>>>> my code above.
>>>>>>
>>>>>>> Anyhow, there is no unique solution to this problem, but they all
>>>>>>> require access to the original EMF type... How can I get it?
>>>>>>
>>>>>>> Thanks,
>>>>>>> Eric
>>>>>>
>>>>>>
>>>
>>>
>>>
>>
>>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617934 is a reply to message #120340] |
Mon, 28 April 2008 14:30 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eric,
What is the class of the object passed to hibernate? If you put a breakpoint in
PersistentArrayHolder.java:45 then you should be able to see it.
gr. Martin
Eric wrote:
> Hi guys,
>
> Eike, I've created a bugzilla entry and added a test case:
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if you
> have any questions.
>
> Martin, as I explained in Bugzilla, when Teneo is creating the mapping
> for my model, I get the following error:
> ------
> [ERROR] Argument is not an array
> java.lang.IllegalArgumentException: Argument is not an array
> at java.lang.reflect.Array.getLength(Native Method)
> at
> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>
> at org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
> at
> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>
> at
> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>
> at
> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>
> at
> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
> at
> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>
> at
> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
> at
> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>
> at
> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>
> at
> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>
> at
> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>
> at
> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>
> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
> at
> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>
> at
> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>
> at
> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>
> at
> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>
> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
> Source)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
> at java.lang.Thread.run(Unknown Source)
> ------
>
> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>
> <array name="barCode" table="`product_barcode`"
> cascade="all,delete-orphan">
> <key update="true">
> <column name="`product_barcode_e_id`" not-null="true"
> unique="false"/>
> </key>
> <list-index column="`product_barcode_idx`"/>
> <element type="byte"/>
> </array>
>
> I've seen a few posts with similar problems and one of those posts
> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
> This triggered a binary blob in my mapping and the mapping became valid,
> but I can't understand why this is happening... Is this (can't process
> byte[]) a bug?
>
> Thanks,
> Eric
>
> Eike Stepper wrote:
>> Hi guys,
>>
>> I think the problem is two-fold:
>>
>> 1) There seem to be users who don't really care about *how* the model
>> is persisted. I call these "model centric". In this case a String is
>> appropriate for now. As Eric pointed out, this case must be supported
>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>>
>> 2) The other group of users can be called "db centric". They want to
>> control *how* exactly their models get persisted. If we want to
>> support this case we won't be able to go without having the generated
>> model code on the server side. It should be easy for the Hibernate
>> layer to interrogate the global package registry prior and falling
>> back to desrerialization from the db only in case a certain package is
>> not globally registered. It is also imagineable to use a store-local
>> registry that can be configured individually. I think a more complex
>> issue is the question how to get the desired/needed packages *into*
>> the used package registry. I see two ways that should both be supported:
>>
>> 2.1) Administratively provisioning the server with the needed models.
>> Depending on the chosen registry approach (direct global or
>> store-local) we could benefit from OSGi dynamic loading. If the global
>> registry is used it will be dynamically configured through an
>> extension point. If a store-local approach is chosen the registry
>> would have to be configured through the server config file which is
>> only read on server startup.
>>
>> 2.2) Dynamically adding models through CommitTransactionRequests
>> issued by the client (which is the standard in CDO). In this case both
>> the calculation of the required bundles at client side and the
>> transmission over the wire are comparingly easy to solve. What about
>> security concerns?
>>
>> Any thoughts?
>>
>> Cheers
>> /Eike
>>
>>
>>
>> Martin Taal schrieb:
>>> Hi Eike,
>>> Afaics the only way to solve this is to have the possibility to add
>>> custom code server side.
>>>
>>> Btw, I can see also other scenarios were it makes sense to have
>>> custom server side code. For example to implement server side actions
>>> based on triggers generated by hibernate interceptors or eventlisteners.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Martin Taal wrote:
>>>>
>>>>> Hi All,
>>>>> I think only for primitive types (byte, string, etc.) and their string
>>>> representations there is no
>>>>> need for extra server side code. For anything more special, for
>>>>> example a
>>>> rgb color object then at
>>>>> server side some client-specific code needs to be installed also,
>>>>> otherwise
>>>> Teneo/hibernate does not
>>>>> know how to instantiate a usertype.
>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>> requires
>>>> a specific hibernate
>>>>> usertype which can translate a colour type to these three columns.
>>>>> This
>>>> usertype is a custom class
>>>>> which needs to be stored at the server.
>>>>> Also the custom colour class needs to be added to the server
>>>>> environment, or
>>>> otherwise how can cdo
>>>>> handle it? Eike how would the colour instance be passed over the wire,
>>>> serialized?
>>>>
>>>> I would expect that at client side the generated (and hand modified)
>>>> model code serializes the custom-typed value into a string and sends
>>>> it to the server. so far no modification to the process necessary.
>>>>
>>>> But arrived at the server side, we need the same generated and
>>>> hand-modified model code with all its dependencies so that the
>>>> Hibernate layer is able to deserialize the string that comes from
>>>> the wire to whatever is coded into the model.
>>>>
>>>> Eventually we can look into how to optimize the transfer over the
>>>> wire itself. But I suggest that we go step by step ;-)
>>>>
>>>> The main issue I foresee with the above approach is that we lose the
>>>> ability to dynamically register new models at the client side. I
>>>> propose that we start with a static approach where a deployer is
>>>> responsible to manually install the needed bundles at the server
>>>> side. If we can make it work this way I can later try to develop
>>>> some mechanism that transfers bundles from the client to the server
>>>> along with the usual CDOPackages (in the run of a
>>>> CommitTransactionRequest/Indication).
>>>>
>>>> Agreed?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>>> gr. Martin
>>>>
>>>>> Eric wrote:
>>>>>> Hi Eike, Martin,
>>>>>>
>>>>>> I did not see that one coming (custom Java code for
>>>>>> serialization)... If this is the case and you want to recreate the
>>>>>> "original" type on server-side, you might not have any other
>>>>>> choice than have a model dependency. :(
>>>>>>
>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>> in my case I was trying to recreate the EMF type in order to store
>>>>>> this attribute using Teneo's original mapping (store a byte[] as a
>>>>>> binary blob instead of a String). Since CDO's internal
>>>>>> representation of a custom type is a String, as long as I'm
>>>>>> accessing it through CDO, I shouldn't care how it is stored in the
>>>>>> database. So Teneo could detect (when using CDO only) that the
>>>>>> attribute you are trying to persist is in fact a custom type and
>>>>>> should generate a "String" representation for the mapping file.
>>>>>> This is not fixing the issue where server-side code would like to
>>>>>> see the EMF type, but if I get this right, it should never be the
>>>>>> case?!?
>>>>>>
>>>>>> Would there be any other benefits if we have access to the
>>>>>> model on server-side? Is it worthwhile?
>>>>>>
>>>>>> Any thoughts?
>>>>>>
>>>>>> Eric
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Hi Eric, Martin,
>>>>>>>
>>>>>>> Having read your message I now see a more basic issue with custom
>>>>>>> EDataTypes. As you know, CDO itself does not require EMF and your
>>>>>>> generated models to be deployed at the server side. The new
>>>>>>> Hibernate integration layer (HibernateStore implementation) adds
>>>>>>> a server-side dependency on EMF but not on your generated models.
>>>>>>> The HibernateStore uses the serialized xml string of your
>>>>>>> client-side model to recreate the EPackage instances. WRT the
>>>>>>> custom EDataTypes there is a good chance that the dynamic package
>>>>>>> at the server side behaves quite different from the generated
>>>>>>> one. IIRC the serialization of custom EDataTypes relies on
>>>>>>> manually written code in the otherwise generated model and the
>>>>>>> respective deserialization code will not be present on the server
>>>>>>> ;-( Not to mention the potentially non-standard instance classes
>>>>>>> that you used on client side.
>>>>>>>
>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>> well. And we will have to make sure that the server side
>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>
>>>>>>> What do you think?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Eric wrote:
>>>>>>>
>>>>>>>> Hi Martin, Eike,
>>>>>>>
>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>> is returning a String and this is causing a ClassCastException.
>>>>>>>> So to fix this problem, I'd like to do the following:
>>>>>>>
>>>>>>>> In CDOPropertyGetter:
>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>> {
>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>> return value;
>>>>>>>> }
>>>>>>>
>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>
>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>> statement from my code above.
>>>>>>>
>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Eric
>>>>>>>
>>>>>>>
>>>>
>>>>
>>>>
>>>
>>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617935 is a reply to message #120368] |
Mon, 28 April 2008 14:55 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
Hi Martin,
the object seems to be a String.
Eric
Martin Taal wrote:
> Hi Eric,
> What is the class of the object passed to hibernate? If you put a
> breakpoint in PersistentArrayHolder.java:45 then you should be able to
> see it.
>
> gr. Martin
>
> Eric wrote:
>> Hi guys,
>>
>> Eike, I've created a bugzilla entry and added a test case:
>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if
>> you have any questions.
>>
>> Martin, as I explained in Bugzilla, when Teneo is creating the
>> mapping for my model, I get the following error:
>> ------
>> [ERROR] Argument is not an array
>> java.lang.IllegalArgumentException: Argument is not an array
>> at java.lang.reflect.Array.getLength(Native Method)
>> at
>> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>>
>> at
>> org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
>> at
>> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>>
>> at
>> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
>>
>> at
>> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>>
>> at
>> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
>> at
>> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>>
>> at
>> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>>
>> at
>> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>>
>> at
>> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>>
>> at
>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>>
>> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
>> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
>> at
>> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>>
>> at
>> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>>
>> at
>> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>>
>> at
>> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>>
>> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
>> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
>> Source)
>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
>> at java.lang.Thread.run(Unknown Source)
>> ------
>>
>> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>>
>> <array name="barCode" table="`product_barcode`"
>> cascade="all,delete-orphan">
>> <key update="true">
>> <column name="`product_barcode_e_id`" not-null="true"
>> unique="false"/>
>> </key>
>> <list-index column="`product_barcode_idx`"/>
>> <element type="byte"/>
>> </array>
>>
>> I've seen a few posts with similar problems and one of those posts
>> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
>> This triggered a binary blob in my mapping and the mapping became
>> valid, but I can't understand why this is happening... Is this (can't
>> process byte[]) a bug?
>>
>> Thanks,
>> Eric
>>
>> Eike Stepper wrote:
>>> Hi guys,
>>>
>>> I think the problem is two-fold:
>>>
>>> 1) There seem to be users who don't really care about *how* the model
>>> is persisted. I call these "model centric". In this case a String is
>>> appropriate for now. As Eric pointed out, this case must be supported
>>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>>>
>>> 2) The other group of users can be called "db centric". They want to
>>> control *how* exactly their models get persisted. If we want to
>>> support this case we won't be able to go without having the generated
>>> model code on the server side. It should be easy for the Hibernate
>>> layer to interrogate the global package registry prior and falling
>>> back to desrerialization from the db only in case a certain package
>>> is not globally registered. It is also imagineable to use a
>>> store-local registry that can be configured individually. I think a
>>> more complex issue is the question how to get the desired/needed
>>> packages *into* the used package registry. I see two ways that should
>>> both be supported:
>>>
>>> 2.1) Administratively provisioning the server with the needed models.
>>> Depending on the chosen registry approach (direct global or
>>> store-local) we could benefit from OSGi dynamic loading. If the
>>> global registry is used it will be dynamically configured through an
>>> extension point. If a store-local approach is chosen the registry
>>> would have to be configured through the server config file which is
>>> only read on server startup.
>>>
>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>> issued by the client (which is the standard in CDO). In this case
>>> both the calculation of the required bundles at client side and the
>>> transmission over the wire are comparingly easy to solve. What about
>>> security concerns?
>>>
>>> Any thoughts?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> Afaics the only way to solve this is to have the possibility to add
>>>> custom code server side.
>>>>
>>>> Btw, I can see also other scenarios were it makes sense to have
>>>> custom server side code. For example to implement server side
>>>> actions based on triggers generated by hibernate interceptors or
>>>> eventlisteners.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Martin Taal wrote:
>>>>>
>>>>>> Hi All,
>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>> string
>>>>> representations there is no
>>>>>> need for extra server side code. For anything more special, for
>>>>>> example a
>>>>> rgb color object then at
>>>>>> server side some client-specific code needs to be installed also,
>>>>>> otherwise
>>>>> Teneo/hibernate does not
>>>>>> know how to instantiate a usertype.
>>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>>> requires
>>>>> a specific hibernate
>>>>>> usertype which can translate a colour type to these three columns.
>>>>>> This
>>>>> usertype is a custom class
>>>>>> which needs to be stored at the server.
>>>>>> Also the custom colour class needs to be added to the server
>>>>>> environment, or
>>>>> otherwise how can cdo
>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>> wire,
>>>>> serialized?
>>>>>
>>>>> I would expect that at client side the generated (and hand
>>>>> modified) model code serializes the custom-typed value into a
>>>>> string and sends it to the server. so far no modification to the
>>>>> process necessary.
>>>>>
>>>>> But arrived at the server side, we need the same generated and
>>>>> hand-modified model code with all its dependencies so that the
>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>> the wire to whatever is coded into the model.
>>>>>
>>>>> Eventually we can look into how to optimize the transfer over the
>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>
>>>>> The main issue I foresee with the above approach is that we lose
>>>>> the ability to dynamically register new models at the client side.
>>>>> I propose that we start with a static approach where a deployer is
>>>>> responsible to manually install the needed bundles at the server
>>>>> side. If we can make it work this way I can later try to develop
>>>>> some mechanism that transfers bundles from the client to the server
>>>>> along with the usual CDOPackages (in the run of a
>>>>> CommitTransactionRequest/Indication).
>>>>>
>>>>> Agreed?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>>> gr. Martin
>>>>>
>>>>>> Eric wrote:
>>>>>>> Hi Eike, Martin,
>>>>>>>
>>>>>>> I did not see that one coming (custom Java code for
>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>> choice than have a model dependency. :(
>>>>>>>
>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>> type and should generate a "String" representation for the
>>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>>> should never be the case?!?
>>>>>>>
>>>>>>> Would there be any other benefits if we have access to the
>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>
>>>>>>> Any thoughts?
>>>>>>>
>>>>>>> Eric
>>>>>>>
>>>>>>> Eike Stepper wrote:
>>>>>>>> Hi Eric, Martin,
>>>>>>>>
>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>>> package at the server side behaves quite different from the
>>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>>> and the respective deserialization code will not be present on
>>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>>> instance classes that you used on client side.
>>>>>>>>
>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>
>>>>>>>> What do you think?
>>>>>>>>
>>>>>>>> Cheers
>>>>>>>> /Eike
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>
>>>>>>>>> Hi Martin, Eike,
>>>>>>>>
>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>> is returning a String and this is causing a
>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>>> following:
>>>>>>>>
>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>> {
>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>> return value;
>>>>>>>>> }
>>>>>>>>
>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>
>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>> statement from my code above.
>>>>>>>>
>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Eric
>>>>>>>>
>>>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>
>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617936 is a reply to message #120380] |
Mon, 28 April 2008 15:00 |
Eric Messages: 40 Registered: July 2009 |
Member |
|
|
So this is again the String from CDO because it is considered a custom
type. So my @Lob annotation wasn't needed at all.
Eric wrote:
> Hi Martin,
>
> the object seems to be a String.
>
> Eric
>
> Martin Taal wrote:
>> Hi Eric,
>> What is the class of the object passed to hibernate? If you put a
>> breakpoint in PersistentArrayHolder.java:45 then you should be able to
>> see it.
>>
>> gr. Martin
>>
>> Eric wrote:
>>> Hi guys,
>>>
>>> Eike, I've created a bugzilla entry and added a test case:
>>> https://bugs.eclipse.org/bugs/show_bug.cgi?id=229049 Let me know if
>>> you have any questions.
>>>
>>> Martin, as I explained in Bugzilla, when Teneo is creating the
>>> mapping for my model, I get the following error:
>>> ------
>>> [ERROR] Argument is not an array
>>> java.lang.IllegalArgumentException: Argument is not an array
>>> at java.lang.reflect.Array.getLength(Native Method)
>>> at
>>> org.hibernate.collection.PersistentArrayHolder.getSnapshot(P ersistentArrayHolder.java:45)
>>>
>>> at
>>> org.hibernate.engine.CollectionEntry.<init>(CollectionEntry.java:68)
>>> at
>>> org.hibernate.engine.StatefulPersistenceContext.addCollectio n(StatefulPersistenceContext.java:784)
>>>
>>> at
>>> org.hibernate.engine.StatefulPersistenceContext.addNewCollec tion(StatefulPersistenceContext.java:751)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processArrayOrNewCollect ion(WrapVisitor.java:77)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processCollection(WrapVi sitor.java:51)
>>>
>>> at
>>> org.hibernate.event.def.AbstractVisitor.processValue(Abstrac tVisitor.java:101)
>>>
>>> at
>>> org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor .java:98)
>>> at
>>> org.hibernate.event.def.AbstractVisitor.processEntityPropert yValues(AbstractVisitor.java:55)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.visitColle ctionsBeforeSave(AbstractSaveEventListener.java:371)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.performSav eOrReplicate(AbstractSaveEventListener.java:273)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.performSav e(AbstractSaveEventListener.java:181)
>>>
>>> at
>>> org.hibernate.event.def.AbstractSaveEventListener.saveWithGe neratedId(AbstractSaveEventListener.java:107)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.sav eWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener .java:187)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveEventListener.saveWithGen eratedOrRequestedId(DefaultSaveEventListener.java:33)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.ent ityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveEventListener.performSave OrUpdate(DefaultSaveEventListener.java:27)
>>>
>>> at
>>> org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onS aveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
>>>
>>> at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535 )
>>> at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
>>> at
>>> org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore Writer.commit(HibernateStoreWriter.java:64)
>>>
>>> at
>>> org.eclipse.emf.cdo.internal.server.Transaction.commit(Trans action.java:179)
>>>
>>> at
>>> org.eclipse.emf.cdo.internal.server.protocol.CommitTransacti onIndication.indicating(CommitTransactionIndication.java:109 )
>>>
>>> at
>>> org.eclipse.net4j.signal.IndicationWithResponse.execute(Indi cationWithResponse.java:46)
>>>
>>> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:143)
>>> at org.eclipse.net4j.signal.Signal.run(Signal.java:124)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unkno wn
>>> Source)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
>>> Source)
>>> at java.lang.Thread.run(Unknown Source)
>>> ------
>>>
>>> My attribute is a byte array (byte[]) and here is Teneo's mapping:
>>>
>>> <array name="barCode" table="`product_barcode`"
>>> cascade="all,delete-orphan">
>>> <key update="true">
>>> <column name="`product_barcode_e_id`" not-null="true"
>>> unique="false"/>
>>> </key>
>>> <list-index column="`product_barcode_idx`"/>
>>> <element type="byte"/>
>>> </array>
>>>
>>> I've seen a few posts with similar problems and one of those posts
>>> suggested to use '@Lob @Column(length=<size>)' as a Teneo annotation.
>>> This triggered a binary blob in my mapping and the mapping became
>>> valid, but I can't understand why this is happening... Is this
>>> (can't process byte[]) a bug?
>>>
>>> Thanks,
>>> Eric
>>>
>>> Eike Stepper wrote:
>>>> Hi guys,
>>>>
>>>> I think the problem is two-fold:
>>>>
>>>> 1) There seem to be users who don't really care about *how* the
>>>> model is persisted. I call these "model centric". In this case a
>>>> String is appropriate for now. As Eric pointed out, this case must
>>>> be supported by the Hibernate layer. Eric, I suggest that you file a
>>>> Bugzilla.
>>>>
>>>> 2) The other group of users can be called "db centric". They want to
>>>> control *how* exactly their models get persisted. If we want to
>>>> support this case we won't be able to go without having the
>>>> generated model code on the server side. It should be easy for the
>>>> Hibernate layer to interrogate the global package registry prior and
>>>> falling back to desrerialization from the db only in case a certain
>>>> package is not globally registered. It is also imagineable to use a
>>>> store-local registry that can be configured individually. I think a
>>>> more complex issue is the question how to get the desired/needed
>>>> packages *into* the used package registry. I see two ways that
>>>> should both be supported:
>>>>
>>>> 2.1) Administratively provisioning the server with the needed
>>>> models. Depending on the chosen registry approach (direct global or
>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>> global registry is used it will be dynamically configured through an
>>>> extension point. If a store-local approach is chosen the registry
>>>> would have to be configured through the server config file which is
>>>> only read on server startup.
>>>>
>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>> issued by the client (which is the standard in CDO). In this case
>>>> both the calculation of the required bundles at client side and the
>>>> transmission over the wire are comparingly easy to solve. What about
>>>> security concerns?
>>>>
>>>> Any thoughts?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Martin Taal schrieb:
>>>>> Hi Eike,
>>>>> Afaics the only way to solve this is to have the possibility to add
>>>>> custom code server side.
>>>>>
>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>> custom server side code. For example to implement server side
>>>>> actions based on triggers generated by hibernate interceptors or
>>>>> eventlisteners.
>>>>>
>>>>> gr. Martin
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Martin Taal wrote:
>>>>>>
>>>>>>> Hi All,
>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>> string
>>>>>> representations there is no
>>>>>>> need for extra server side code. For anything more special, for
>>>>>>> example a
>>>>>> rgb color object then at
>>>>>>> server side some client-specific code needs to be installed also,
>>>>>>> otherwise
>>>>>> Teneo/hibernate does not
>>>>>>> know how to instantiate a usertype.
>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>> This requires
>>>>>> a specific hibernate
>>>>>>> usertype which can translate a colour type to these three
>>>>>>> columns. This
>>>>>> usertype is a custom class
>>>>>>> which needs to be stored at the server.
>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>> environment, or
>>>>>> otherwise how can cdo
>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>> wire,
>>>>>> serialized?
>>>>>>
>>>>>> I would expect that at client side the generated (and hand
>>>>>> modified) model code serializes the custom-typed value into a
>>>>>> string and sends it to the server. so far no modification to the
>>>>>> process necessary.
>>>>>>
>>>>>> But arrived at the server side, we need the same generated and
>>>>>> hand-modified model code with all its dependencies so that the
>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>> the wire to whatever is coded into the model.
>>>>>>
>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>
>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>> the ability to dynamically register new models at the client side.
>>>>>> I propose that we start with a static approach where a deployer is
>>>>>> responsible to manually install the needed bundles at the server
>>>>>> side. If we can make it work this way I can later try to develop
>>>>>> some mechanism that transfers bundles from the client to the
>>>>>> server along with the usual CDOPackages (in the run of a
>>>>>> CommitTransactionRequest/Indication).
>>>>>>
>>>>>> Agreed?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>>> gr. Martin
>>>>>>
>>>>>>> Eric wrote:
>>>>>>>> Hi Eike, Martin,
>>>>>>>>
>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>>> choice than have a model dependency. :(
>>>>>>>>
>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>>> type and should generate a "String" representation for the
>>>>>>>> mapping file. This is not fixing the issue where server-side
>>>>>>>> code would like to see the EMF type, but if I get this right, it
>>>>>>>> should never be the case?!?
>>>>>>>>
>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>
>>>>>>>> Any thoughts?
>>>>>>>>
>>>>>>>> Eric
>>>>>>>>
>>>>>>>> Eike Stepper wrote:
>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>
>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>>> and your generated models to be deployed at the server side.
>>>>>>>>> The new Hibernate integration layer (HibernateStore
>>>>>>>>> implementation) adds a server-side dependency on EMF but not on
>>>>>>>>> your generated models. The HibernateStore uses the serialized
>>>>>>>>> xml string of your client-side model to recreate the EPackage
>>>>>>>>> instances. WRT the custom EDataTypes there is a good chance
>>>>>>>>> that the dynamic package at the server side behaves quite
>>>>>>>>> different from the generated one. IIRC the serialization of
>>>>>>>>> custom EDataTypes relies on manually written code in the
>>>>>>>>> otherwise generated model and the respective deserialization
>>>>>>>>> code will not be present on the server ;-( Not to mention the
>>>>>>>>> potentially non-standard instance classes that you used on
>>>>>>>>> client side.
>>>>>>>>>
>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>
>>>>>>>>> What do you think?
>>>>>>>>>
>>>>>>>>> Cheers
>>>>>>>>> /Eike
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Eric wrote:
>>>>>>>>>
>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>
>>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>>> is returning a String and this is causing a
>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>> the following:
>>>>>>>>>
>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>> {
>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>> return value;
>>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>
>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>> statement from my code above.
>>>>>>>>>
>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>
>>
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617939 is a reply to message #120299] |
Mon, 28 April 2008 19:41 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Hi Eike,
I am not sure if the java class and ecore package are the same. In my view the custom types are
mostly used for simple types, so for example as the instance class in a custom edatatype. These
simple instance classes don't necessarily have to be explicitly modeled.
For the rest I am ofcourse in favor of adding this, at least I think it is a nice extra feature. My
opinion is still that it does not need to be too flexible, imho many times the types are known at
system install/startup time. But that's just my opinion.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> See comments below.
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Hi guys,
>>>
>>> I think the problem is two-fold:
>>>
>>> 1) There seem to be users who don't really care about *how* the model
>>> is persisted. I call these "model centric". In this case a String is
>>> appropriate for now. As Eric pointed out, this case must be supported
>>> by the Hibernate layer. Eric, I suggest that you file a Bugzilla.
>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>> which types are to be stringized because then it should put
>> type="string" in the mapping.But how can it know this?
> I think this should be the fallback approach in case the store is unable
> to reach the generated code for non-basic EDataTypes via 2.1 or 2.2. So
> whenever the mapping engine encounters EDataTypes with an instance class
> which it can't access via its ClassLoader it should use String (or
> something more configurable). Would that be possible?
>
>>> 2) The other group of users can be called "db centric". They want to
>>> control *how* exactly their models get persisted. If we want to
>>> support this case we won't be able to go without having the generated
>>> model code on the server side. It should be easy for the Hibernate
>>> layer to interrogate the global package registry prior and falling
>>> back to desrerialization from the db only in case a certain package
>>> is not globally registered. It is also imagineable to use a
>>> store-local registry that can be configured individually. I think a
>>> more complex issue is the question how to get the desired/needed
>>> packages *into* the used package registry. I see two ways that should
>>> both be supported:
>>
>> MT>> Do you mean java package or ecore package? For the hibernate
>> layer getting access to the required classes is relevant. With
>> required classes I mean the actual class of the value of the attribute
>> and the class for the hibernate converter.
> Aren't Ecore packages and Java packages equivalent here? Since we talk
> about generated models I really mean the generated model bundles which
> contain the model itself plus the generated Java packages. Somewhere in
> this bundle or in its dependency tree the needed instance classes must
> be found, as well as the serialization code to convert between String
> (which comes over the wire) and the instance class.
>
>> MT>> In my view the required models and the java packages implementing
>> model specifics (like types and converters) are fairly static. This
>> means that they can be installed at installation time (and upgrade
>> time) and are not that dynamic. So would the solution not just be to
>> allow the developer to add plugins to the server runtime which provide
>> the value classes and converter and (de-)serializer to get the value
>> objects over the wire?
>> Or what do you think?
> Yes, that's my case 2.1. Case 2.2 would be an additional feature where
> the clients can commit additional packages which would be dynamically
> added to the repository.
>
> If we want to start work on these features I'd suggest that I start on
> the configuration issues (of the server and the config negotiation with
> the client) and then find a way to transfer additional binary data (e.g.
> bundles) with a CommitTransaction Request.
>
> Ok?
>
> Cheers
> /Eike
>
>
>>> 2.1) Administratively provisioning the server with the needed models.
>>> Depending on the chosen registry approach (direct global or
>>> store-local) we could benefit from OSGi dynamic loading. If the
>>> global registry is used it will be dynamically configured through an
>>> extension point. If a store-local approach is chosen the registry
>>> would have to be configured through the server config file which is
>>> only read on server startup.
>>>
>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>> issued by the client (which is the standard in CDO). In this case
>>> both the calculation of the required bundles at client side and the
>>> transmission over the wire are comparingly easy to solve. What about
>>> security concerns?
>>>
>>> Any thoughts?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> Afaics the only way to solve this is to have the possibility to add
>>>> custom code server side.
>>>>
>>>> Btw, I can see also other scenarios were it makes sense to have
>>>> custom server side code. For example to implement server side
>>>> actions based on triggers generated by hibernate interceptors or
>>>> eventlisteners.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Martin Taal wrote:
>>>>>
>>>>>> Hi All,
>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>> string
>>>>> representations there is no
>>>>>> need for extra server side code. For anything more special, for
>>>>>> example a
>>>>> rgb color object then at
>>>>>> server side some client-specific code needs to be installed also,
>>>>>> otherwise
>>>>> Teneo/hibernate does not
>>>>>> know how to instantiate a usertype.
>>>>>> Take the example of storing a colour object in 3 int columns. This
>>>>>> requires
>>>>> a specific hibernate
>>>>>> usertype which can translate a colour type to these three columns.
>>>>>> This
>>>>> usertype is a custom class
>>>>>> which needs to be stored at the server.
>>>>>> Also the custom colour class needs to be added to the server
>>>>>> environment, or
>>>>> otherwise how can cdo
>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>> wire,
>>>>> serialized?
>>>>>
>>>>> I would expect that at client side the generated (and hand
>>>>> modified) model code serializes the custom-typed value into a
>>>>> string and sends it to the server. so far no modification to the
>>>>> process necessary.
>>>>>
>>>>> But arrived at the server side, we need the same generated and
>>>>> hand-modified model code with all its dependencies so that the
>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>> the wire to whatever is coded into the model.
>>>>>
>>>>> Eventually we can look into how to optimize the transfer over the
>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>
>>>>> The main issue I foresee with the above approach is that we lose
>>>>> the ability to dynamically register new models at the client side.
>>>>> I propose that we start with a static approach where a deployer is
>>>>> responsible to manually install the needed bundles at the server
>>>>> side. If we can make it work this way I can later try to develop
>>>>> some mechanism that transfers bundles from the client to the server
>>>>> along with the usual CDOPackages (in the run of a
>>>>> CommitTransactionRequest/Indication).
>>>>>
>>>>> Agreed?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>>> gr. Martin
>>>>>
>>>>>> Eric wrote:
>>>>>>> Hi Eike, Martin,
>>>>>>>
>>>>>>> I did not see that one coming (custom Java code for
>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>> the "original" type on server-side, you might not have any other
>>>>>>> choice than have a model dependency. :(
>>>>>>>
>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>> type on the server. Maybe I'm missing the big picture here, but
>>>>>>> in my case I was trying to recreate the EMF type in order to
>>>>>>> store this attribute using Teneo's original mapping (store a
>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>> internal representation of a custom type is a String, as long as
>>>>>>> I'm accessing it through CDO, I shouldn't care how it is stored
>>>>>>> in the database. So Teneo could detect (when using CDO only)
>>>>>>> that the attribute you are trying to persist is in fact a custom
>>>>>>> type and should generate a "String" representation for the
>>>>>>> mapping file. This is not fixing the issue where server-side code
>>>>>>> would like to see the EMF type, but if I get this right, it
>>>>>>> should never be the case?!?
>>>>>>>
>>>>>>> Would there be any other benefits if we have access to the
>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>
>>>>>>> Any thoughts?
>>>>>>>
>>>>>>> Eric
>>>>>>>
>>>>>>> Eike Stepper wrote:
>>>>>>>> Hi Eric, Martin,
>>>>>>>>
>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>> custom EDataTypes. As you know, CDO itself does not require EMF
>>>>>>>> and your generated models to be deployed at the server side. The
>>>>>>>> new Hibernate integration layer (HibernateStore implementation)
>>>>>>>> adds a server-side dependency on EMF but not on your generated
>>>>>>>> models. The HibernateStore uses the serialized xml string of
>>>>>>>> your client-side model to recreate the EPackage instances. WRT
>>>>>>>> the custom EDataTypes there is a good chance that the dynamic
>>>>>>>> package at the server side behaves quite different from the
>>>>>>>> generated one. IIRC the serialization of custom EDataTypes
>>>>>>>> relies on manually written code in the otherwise generated model
>>>>>>>> and the respective deserialization code will not be present on
>>>>>>>> the server ;-( Not to mention the potentially non-standard
>>>>>>>> instance classes that you used on client side.
>>>>>>>>
>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>
>>>>>>>> What do you think?
>>>>>>>>
>>>>>>>> Cheers
>>>>>>>> /Eike
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>
>>>>>>>>> Hi Martin, Eike,
>>>>>>>>
>>>>>>>>> I want to solve a problem I have with custom CDO types. To
>>>>>>>>> summarize my problem, I have an EMF type with an attribute of
>>>>>>>>> type byte[] and using Teneo's annotation, I've mapped it to a
>>>>>>>>> binary blob. When the CDOPropertyGetter returns the value, it
>>>>>>>>> is returning a String and this is causing a
>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do the
>>>>>>>>> following:
>>>>>>>>
>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>> {
>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>> return value;
>>>>>>>>> }
>>>>>>>>
>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>
>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>> statement from my code above.
>>>>>>>>
>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>> all require access to the original EMF type... How can I get it?
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Eric
>>>>>>>>
>>>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>
>>
>>
--
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: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617942 is a reply to message #120433] |
Mon, 28 April 2008 20:30 |
|
Martin Taal schrieb:
> Hi Eike,
> I am not sure if the java class and ecore package are the same. In my
> view the custom types are mostly used for simple types, so for example
> as the instance class in a custom edatatype. These simple instance
> classes don't necessarily have to be explicitly modeled.
I think the generated model package will be needed to deserialize the
string that comes over the wire. whether the instance class is modeled
or not doesn't seem to matter since it must be somewhere in the
dependency tree anyway. Do I miss something?
> For the rest I am ofcourse in favor of adding this, at least I think
> it is a nice extra feature. My opinion is still that it does not need
> to be too flexible, imho many times the types are known at system
> install/startup time. But that's just my opinion.
There are also other users being keen on this feature. They want to be
able to dynamically commit the packages with all the code and distribute
them on demand to the other clients. It's just a fortunate accident that
I come to this issue now ;-)
I have https://bugs.eclipse.org/bugs/show_bug.cgi?id=229126 for that.
Cheers
/Eike
>
> gr. Martin
>
> Eike Stepper wrote:
>> Martin Taal schrieb:
>>> Hi Eike,
>>> See comments below.
>>>
>>> gr. Martin
>>>
>>> Eike Stepper wrote:
>>>> Hi guys,
>>>>
>>>> I think the problem is two-fold:
>>>>
>>>> 1) There seem to be users who don't really care about *how* the
>>>> model is persisted. I call these "model centric". In this case a
>>>> String is appropriate for now. As Eric pointed out, this case must
>>>> be supported by the Hibernate layer. Eric, I suggest that you file
>>>> a Bugzilla.
>>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>>> which types are to be stringized because then it should put
>>> type="string" in the mapping.But how can it know this?
>> I think this should be the fallback approach in case the store is
>> unable to reach the generated code for non-basic EDataTypes via 2.1
>> or 2.2. So whenever the mapping engine encounters EDataTypes with an
>> instance class which it can't access via its ClassLoader it should
>> use String (or something more configurable). Would that be possible?
>>
>>>> 2) The other group of users can be called "db centric". They want
>>>> to control *how* exactly their models get persisted. If we want to
>>>> support this case we won't be able to go without having the
>>>> generated model code on the server side. It should be easy for the
>>>> Hibernate layer to interrogate the global package registry prior
>>>> and falling back to desrerialization from the db only in case a
>>>> certain package is not globally registered. It is also imagineable
>>>> to use a store-local registry that can be configured individually.
>>>> I think a more complex issue is the question how to get the
>>>> desired/needed packages *into* the used package registry. I see two
>>>> ways that should both be supported:
>>>
>>> MT>> Do you mean java package or ecore package? For the hibernate
>>> layer getting access to the required classes is relevant. With
>>> required classes I mean the actual class of the value of the
>>> attribute and the class for the hibernate converter.
>> Aren't Ecore packages and Java packages equivalent here? Since we
>> talk about generated models I really mean the generated model bundles
>> which contain the model itself plus the generated Java packages.
>> Somewhere in this bundle or in its dependency tree the needed
>> instance classes must be found, as well as the serialization code to
>> convert between String (which comes over the wire) and the instance
>> class.
>>
>>> MT>> In my view the required models and the java packages
>>> implementing model specifics (like types and converters) are fairly
>>> static. This means that they can be installed at installation time
>>> (and upgrade time) and are not that dynamic. So would the solution
>>> not just be to allow the developer to add plugins to the server
>>> runtime which provide the value classes and converter and
>>> (de-)serializer to get the value objects over the wire?
>>> Or what do you think?
>> Yes, that's my case 2.1. Case 2.2 would be an additional feature
>> where the clients can commit additional packages which would be
>> dynamically added to the repository.
>>
>> If we want to start work on these features I'd suggest that I start
>> on the configuration issues (of the server and the config negotiation
>> with the client) and then find a way to transfer additional binary
>> data (e.g. bundles) with a CommitTransaction Request.
>>
>> Ok?
>>
>> Cheers
>> /Eike
>>
>>
>>>> 2.1) Administratively provisioning the server with the needed
>>>> models. Depending on the chosen registry approach (direct global or
>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>> global registry is used it will be dynamically configured through
>>>> an extension point. If a store-local approach is chosen the
>>>> registry would have to be configured through the server config file
>>>> which is only read on server startup.
>>>>
>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>> issued by the client (which is the standard in CDO). In this case
>>>> both the calculation of the required bundles at client side and the
>>>> transmission over the wire are comparingly easy to solve. What
>>>> about security concerns?
>>>>
>>>> Any thoughts?
>>>>
>>>> Cheers
>>>> /Eike
>>>>
>>>>
>>>>
>>>> Martin Taal schrieb:
>>>>> Hi Eike,
>>>>> Afaics the only way to solve this is to have the possibility to
>>>>> add custom code server side.
>>>>>
>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>> custom server side code. For example to implement server side
>>>>> actions based on triggers generated by hibernate interceptors or
>>>>> eventlisteners.
>>>>>
>>>>> gr. Martin
>>>>>
>>>>> Eike Stepper wrote:
>>>>>> Martin Taal wrote:
>>>>>>
>>>>>>> Hi All,
>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>> string
>>>>>> representations there is no
>>>>>>> need for extra server side code. For anything more special, for
>>>>>>> example a
>>>>>> rgb color object then at
>>>>>>> server side some client-specific code needs to be installed
>>>>>>> also, otherwise
>>>>>> Teneo/hibernate does not
>>>>>>> know how to instantiate a usertype.
>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>> This requires
>>>>>> a specific hibernate
>>>>>>> usertype which can translate a colour type to these three
>>>>>>> columns. This
>>>>>> usertype is a custom class
>>>>>>> which needs to be stored at the server.
>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>> environment, or
>>>>>> otherwise how can cdo
>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>> wire,
>>>>>> serialized?
>>>>>>
>>>>>> I would expect that at client side the generated (and hand
>>>>>> modified) model code serializes the custom-typed value into a
>>>>>> string and sends it to the server. so far no modification to the
>>>>>> process necessary.
>>>>>>
>>>>>> But arrived at the server side, we need the same generated and
>>>>>> hand-modified model code with all its dependencies so that the
>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>> the wire to whatever is coded into the model.
>>>>>>
>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>
>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>> the ability to dynamically register new models at the client
>>>>>> side. I propose that we start with a static approach where a
>>>>>> deployer is responsible to manually install the needed bundles at
>>>>>> the server side. If we can make it work this way I can later try
>>>>>> to develop some mechanism that transfers bundles from the client
>>>>>> to the server along with the usual CDOPackages (in the run of a
>>>>>> CommitTransactionRequest/Indication).
>>>>>>
>>>>>> Agreed?
>>>>>>
>>>>>> Cheers
>>>>>> /Eike
>>>>>>
>>>>>>
>>>>>>
>>>>>>> gr. Martin
>>>>>>
>>>>>>> Eric wrote:
>>>>>>>> Hi Eike, Martin,
>>>>>>>>
>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>> the "original" type on server-side, you might not have any
>>>>>>>> other choice than have a model dependency. :(
>>>>>>>>
>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>> type on the server. Maybe I'm missing the big picture here,
>>>>>>>> but in my case I was trying to recreate the EMF type in order
>>>>>>>> to store this attribute using Teneo's original mapping (store a
>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>> internal representation of a custom type is a String, as long
>>>>>>>> as I'm accessing it through CDO, I shouldn't care how it is
>>>>>>>> stored in the database. So Teneo could detect (when using CDO
>>>>>>>> only) that the attribute you are trying to persist is in fact a
>>>>>>>> custom type and should generate a "String" representation for
>>>>>>>> the mapping file. This is not fixing the issue where
>>>>>>>> server-side code would like to see the EMF type, but if I get
>>>>>>>> this right, it should never be the case?!?
>>>>>>>>
>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>
>>>>>>>> Any thoughts?
>>>>>>>>
>>>>>>>> Eric
>>>>>>>>
>>>>>>>> Eike Stepper wrote:
>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>
>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require
>>>>>>>>> EMF and your generated models to be deployed at the server
>>>>>>>>> side. The new Hibernate integration layer (HibernateStore
>>>>>>>>> implementation) adds a server-side dependency on EMF but not
>>>>>>>>> on your generated models. The HibernateStore uses the
>>>>>>>>> serialized xml string of your client-side model to recreate
>>>>>>>>> the EPackage instances. WRT the custom EDataTypes there is a
>>>>>>>>> good chance that the dynamic package at the server side
>>>>>>>>> behaves quite different from the generated one. IIRC the
>>>>>>>>> serialization of custom EDataTypes relies on manually written
>>>>>>>>> code in the otherwise generated model and the respective
>>>>>>>>> deserialization code will not be present on the server ;-( Not
>>>>>>>>> to mention the potentially non-standard instance classes that
>>>>>>>>> you used on client side.
>>>>>>>>>
>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>
>>>>>>>>> What do you think?
>>>>>>>>>
>>>>>>>>> Cheers
>>>>>>>>> /Eike
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Eric wrote:
>>>>>>>>>
>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>
>>>>>>>>>> I want to solve a problem I have with custom CDO types.
>>>>>>>>>> To summarize my problem, I have an EMF type with an attribute
>>>>>>>>>> of type byte[] and using Teneo's annotation, I've mapped it
>>>>>>>>>> to a binary blob. When the CDOPropertyGetter returns the
>>>>>>>>>> value, it is returning a String and this is causing a
>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>> the following:
>>>>>>>>>
>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>> {
>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>> return value;
>>>>>>>>>> }
>>>>>>>>>
>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>
>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>> statement from my code above.
>>>>>>>>>
>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>> all require access to the original EMF type... How can I get
>>>>>>>>>> it?
>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>
>>>
>>>
>
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [Teneo][CDO-Hibernate] How to access the EMF type of a CDOFeature server-sid [message #617943 is a reply to message #120473] |
Mon, 28 April 2008 20:52 |
Martin Taal Messages: 5468 Registered: July 2009 |
Senior Member |
|
|
Yes it must be somewhere in the dependency tree so we mean the same thing.
gr. Martin
Eike Stepper wrote:
> Martin Taal schrieb:
>> Hi Eike,
>> I am not sure if the java class and ecore package are the same. In my
>> view the custom types are mostly used for simple types, so for example
>> as the instance class in a custom edatatype. These simple instance
>> classes don't necessarily have to be explicitly modeled.
> I think the generated model package will be needed to deserialize the
> string that comes over the wire. whether the instance class is modeled
> or not doesn't seem to matter since it must be somewhere in the
> dependency tree anyway. Do I miss something?
>
>> For the rest I am ofcourse in favor of adding this, at least I think
>> it is a nice extra feature. My opinion is still that it does not need
>> to be too flexible, imho many times the types are known at system
>> install/startup time. But that's just my opinion.
> There are also other users being keen on this feature. They want to be
> able to dynamically commit the packages with all the code and distribute
> them on demand to the other clients. It's just a fortunate accident that
> I come to this issue now ;-)
> I have https://bugs.eclipse.org/bugs/show_bug.cgi?id=229126 for that.
>
> Cheers
> /Eike
>
>
>>
>> gr. Martin
>>
>> Eike Stepper wrote:
>>> Martin Taal schrieb:
>>>> Hi Eike,
>>>> See comments below.
>>>>
>>>> gr. Martin
>>>>
>>>> Eike Stepper wrote:
>>>>> Hi guys,
>>>>>
>>>>> I think the problem is two-fold:
>>>>>
>>>>> 1) There seem to be users who don't really care about *how* the
>>>>> model is persisted. I call these "model centric". In this case a
>>>>> String is appropriate for now. As Eric pointed out, this case must
>>>>> be supported by the Hibernate layer. Eric, I suggest that you file
>>>>> a Bugzilla.
>>>> MT>> Yes I agree, I am not sure how the hibernate layer would know
>>>> which types are to be stringized because then it should put
>>>> type="string" in the mapping.But how can it know this?
>>> I think this should be the fallback approach in case the store is
>>> unable to reach the generated code for non-basic EDataTypes via 2.1
>>> or 2.2. So whenever the mapping engine encounters EDataTypes with an
>>> instance class which it can't access via its ClassLoader it should
>>> use String (or something more configurable). Would that be possible?
>>>
>>>>> 2) The other group of users can be called "db centric". They want
>>>>> to control *how* exactly their models get persisted. If we want to
>>>>> support this case we won't be able to go without having the
>>>>> generated model code on the server side. It should be easy for the
>>>>> Hibernate layer to interrogate the global package registry prior
>>>>> and falling back to desrerialization from the db only in case a
>>>>> certain package is not globally registered. It is also imagineable
>>>>> to use a store-local registry that can be configured individually.
>>>>> I think a more complex issue is the question how to get the
>>>>> desired/needed packages *into* the used package registry. I see two
>>>>> ways that should both be supported:
>>>>
>>>> MT>> Do you mean java package or ecore package? For the hibernate
>>>> layer getting access to the required classes is relevant. With
>>>> required classes I mean the actual class of the value of the
>>>> attribute and the class for the hibernate converter.
>>> Aren't Ecore packages and Java packages equivalent here? Since we
>>> talk about generated models I really mean the generated model bundles
>>> which contain the model itself plus the generated Java packages.
>>> Somewhere in this bundle or in its dependency tree the needed
>>> instance classes must be found, as well as the serialization code to
>>> convert between String (which comes over the wire) and the instance
>>> class.
>>>
>>>> MT>> In my view the required models and the java packages
>>>> implementing model specifics (like types and converters) are fairly
>>>> static. This means that they can be installed at installation time
>>>> (and upgrade time) and are not that dynamic. So would the solution
>>>> not just be to allow the developer to add plugins to the server
>>>> runtime which provide the value classes and converter and
>>>> (de-)serializer to get the value objects over the wire?
>>>> Or what do you think?
>>> Yes, that's my case 2.1. Case 2.2 would be an additional feature
>>> where the clients can commit additional packages which would be
>>> dynamically added to the repository.
>>>
>>> If we want to start work on these features I'd suggest that I start
>>> on the configuration issues (of the server and the config negotiation
>>> with the client) and then find a way to transfer additional binary
>>> data (e.g. bundles) with a CommitTransaction Request.
>>>
>>> Ok?
>>>
>>> Cheers
>>> /Eike
>>>
>>>
>>>>> 2.1) Administratively provisioning the server with the needed
>>>>> models. Depending on the chosen registry approach (direct global or
>>>>> store-local) we could benefit from OSGi dynamic loading. If the
>>>>> global registry is used it will be dynamically configured through
>>>>> an extension point. If a store-local approach is chosen the
>>>>> registry would have to be configured through the server config file
>>>>> which is only read on server startup.
>>>>>
>>>>> 2.2) Dynamically adding models through CommitTransactionRequests
>>>>> issued by the client (which is the standard in CDO). In this case
>>>>> both the calculation of the required bundles at client side and the
>>>>> transmission over the wire are comparingly easy to solve. What
>>>>> about security concerns?
>>>>>
>>>>> Any thoughts?
>>>>>
>>>>> Cheers
>>>>> /Eike
>>>>>
>>>>>
>>>>>
>>>>> Martin Taal schrieb:
>>>>>> Hi Eike,
>>>>>> Afaics the only way to solve this is to have the possibility to
>>>>>> add custom code server side.
>>>>>>
>>>>>> Btw, I can see also other scenarios were it makes sense to have
>>>>>> custom server side code. For example to implement server side
>>>>>> actions based on triggers generated by hibernate interceptors or
>>>>>> eventlisteners.
>>>>>>
>>>>>> gr. Martin
>>>>>>
>>>>>> Eike Stepper wrote:
>>>>>>> Martin Taal wrote:
>>>>>>>
>>>>>>>> Hi All,
>>>>>>>> I think only for primitive types (byte, string, etc.) and their
>>>>>>>> string
>>>>>>> representations there is no
>>>>>>>> need for extra server side code. For anything more special, for
>>>>>>>> example a
>>>>>>> rgb color object then at
>>>>>>>> server side some client-specific code needs to be installed
>>>>>>>> also, otherwise
>>>>>>> Teneo/hibernate does not
>>>>>>>> know how to instantiate a usertype.
>>>>>>>> Take the example of storing a colour object in 3 int columns.
>>>>>>>> This requires
>>>>>>> a specific hibernate
>>>>>>>> usertype which can translate a colour type to these three
>>>>>>>> columns. This
>>>>>>> usertype is a custom class
>>>>>>>> which needs to be stored at the server.
>>>>>>>> Also the custom colour class needs to be added to the server
>>>>>>>> environment, or
>>>>>>> otherwise how can cdo
>>>>>>>> handle it? Eike how would the colour instance be passed over the
>>>>>>>> wire,
>>>>>>> serialized?
>>>>>>>
>>>>>>> I would expect that at client side the generated (and hand
>>>>>>> modified) model code serializes the custom-typed value into a
>>>>>>> string and sends it to the server. so far no modification to the
>>>>>>> process necessary.
>>>>>>>
>>>>>>> But arrived at the server side, we need the same generated and
>>>>>>> hand-modified model code with all its dependencies so that the
>>>>>>> Hibernate layer is able to deserialize the string that comes from
>>>>>>> the wire to whatever is coded into the model.
>>>>>>>
>>>>>>> Eventually we can look into how to optimize the transfer over the
>>>>>>> wire itself. But I suggest that we go step by step ;-)
>>>>>>>
>>>>>>> The main issue I foresee with the above approach is that we lose
>>>>>>> the ability to dynamically register new models at the client
>>>>>>> side. I propose that we start with a static approach where a
>>>>>>> deployer is responsible to manually install the needed bundles at
>>>>>>> the server side. If we can make it work this way I can later try
>>>>>>> to develop some mechanism that transfers bundles from the client
>>>>>>> to the server along with the usual CDOPackages (in the run of a
>>>>>>> CommitTransactionRequest/Indication).
>>>>>>>
>>>>>>> Agreed?
>>>>>>>
>>>>>>> Cheers
>>>>>>> /Eike
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> gr. Martin
>>>>>>>
>>>>>>>> Eric wrote:
>>>>>>>>> Hi Eike, Martin,
>>>>>>>>>
>>>>>>>>> I did not see that one coming (custom Java code for
>>>>>>>>> serialization)... If this is the case and you want to recreate
>>>>>>>>> the "original" type on server-side, you might not have any
>>>>>>>>> other choice than have a model dependency. :(
>>>>>>>>>
>>>>>>>>> That having been said, maybe we don't need to have the EMF
>>>>>>>>> type on the server. Maybe I'm missing the big picture here,
>>>>>>>>> but in my case I was trying to recreate the EMF type in order
>>>>>>>>> to store this attribute using Teneo's original mapping (store a
>>>>>>>>> byte[] as a binary blob instead of a String). Since CDO's
>>>>>>>>> internal representation of a custom type is a String, as long
>>>>>>>>> as I'm accessing it through CDO, I shouldn't care how it is
>>>>>>>>> stored in the database. So Teneo could detect (when using CDO
>>>>>>>>> only) that the attribute you are trying to persist is in fact a
>>>>>>>>> custom type and should generate a "String" representation for
>>>>>>>>> the mapping file. This is not fixing the issue where
>>>>>>>>> server-side code would like to see the EMF type, but if I get
>>>>>>>>> this right, it should never be the case?!?
>>>>>>>>>
>>>>>>>>> Would there be any other benefits if we have access to the
>>>>>>>>> model on server-side? Is it worthwhile?
>>>>>>>>>
>>>>>>>>> Any thoughts?
>>>>>>>>>
>>>>>>>>> Eric
>>>>>>>>>
>>>>>>>>> Eike Stepper wrote:
>>>>>>>>>> Hi Eric, Martin,
>>>>>>>>>>
>>>>>>>>>> Having read your message I now see a more basic issue with
>>>>>>>>>> custom EDataTypes. As you know, CDO itself does not require
>>>>>>>>>> EMF and your generated models to be deployed at the server
>>>>>>>>>> side. The new Hibernate integration layer (HibernateStore
>>>>>>>>>> implementation) adds a server-side dependency on EMF but not
>>>>>>>>>> on your generated models. The HibernateStore uses the
>>>>>>>>>> serialized xml string of your client-side model to recreate
>>>>>>>>>> the EPackage instances. WRT the custom EDataTypes there is a
>>>>>>>>>> good chance that the dynamic package at the server side
>>>>>>>>>> behaves quite different from the generated one. IIRC the
>>>>>>>>>> serialization of custom EDataTypes relies on manually written
>>>>>>>>>> code in the otherwise generated model and the respective
>>>>>>>>>> deserialization code will not be present on the server ;-( Not
>>>>>>>>>> to mention the potentially non-standard instance classes that
>>>>>>>>>> you used on client side.
>>>>>>>>>>
>>>>>>>>>> If I'm right, I only see that the generated models, along with
>>>>>>>>>> all their dependencies, have to be deployed to the server as
>>>>>>>>>> well. And we will have to make sure that the server side
>>>>>>>>>> EPackage.Registry.INSTANCE is consulted before we attempt to
>>>>>>>>>> deserialize the needed EPackages from the xml string in the db.
>>>>>>>>>>
>>>>>>>>>> What do you think?
>>>>>>>>>>
>>>>>>>>>> Cheers
>>>>>>>>>> /Eike
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Eric wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Martin, Eike,
>>>>>>>>>>
>>>>>>>>>>> I want to solve a problem I have with custom CDO types.
>>>>>>>>>>> To summarize my problem, I have an EMF type with an attribute
>>>>>>>>>>> of type byte[] and using Teneo's annotation, I've mapped it
>>>>>>>>>>> to a binary blob. When the CDOPropertyGetter returns the
>>>>>>>>>>> value, it is returning a String and this is causing a
>>>>>>>>>>> ClassCastException. So to fix this problem, I'd like to do
>>>>>>>>>>> the following:
>>>>>>>>>>
>>>>>>>>>>> In CDOPropertyGetter:
>>>>>>>>>>> public Object get(Object target) throws HibernateException
>>>>>>>>>>> {
>>>>>>>>>>> InternalCDORevision revision = (InternalCDORevision)target;
>>>>>>>>>>> Object value = revision.getValue(getCDOFeature());
>>>>>>>>>>> if(getCDOFeature().getType() == CDOType.CUSTOM)
>>>>>>>>>>> return EcoreUtil.convertFromString(..., value);
>>>>>>>>>>> return value;
>>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>>> where ... would be replaced by the EMF data type.
>>>>>>>>>>
>>>>>>>>>>> Another solution would be to create a CDOCustomPropertyGetter
>>>>>>>>>>> and have the CDORevisionTuplizer instantiate it by passing it
>>>>>>>>>>> the concrete EMF data type and this CDOCustomPropertyGetter
>>>>>>>>>>> would do the conversion. This solution would remove the if
>>>>>>>>>>> statement from my code above.
>>>>>>>>>>
>>>>>>>>>>> Anyhow, there is no unique solution to this problem, but they
>>>>>>>>>>> all require access to the original EMF type... How can I get
>>>>>>>>>>> it?
>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Eric
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>>>
>>
>>
--
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
|
|
|
Goto Forum:
Current Time: Fri Nov 08 22:57:20 GMT 2024
Powered by FUDForum. Page generated in 0.09095 seconds
|