Grokbase Groups Cayenne dev June 2009
FAQ
Here is the scenario ... We have a database with over 121,000 tables
mapped in cayenne running under an out of the box ROP client server
model. After the client creates the connection, it authenticates the
user by querying the user table (that table only currently has about 6
rows in it). The initial query always takes about 30 seconds and then
everything is fine on subsequent queries. I am wondering if something is
going on with the first ROP client query. Is the client trying to cache
the server's entity resolver data set?? Or is it something else? Is
there any way to speed up the initial client query?



Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
Road, Grand Island, New York, 14072, USA
Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
z.trabaris@insysware.com *
www.insysware.com <http://www.insysware.com/>

________________________________

CONFIDENTIALITY: This email (including any attachments) may contain
confidential, proprietary and privileged information, and unauthorized
disclosure or use is prohibited. If you received this email in error,
please notify the sender and delete this email from your system. Thank
you.

Search Discussions

  • Andrus Adamchik at Jun 5, 2009 at 11:48 am
    Correct - the first ROP access causes client to load all the mapping
    metadata from the server. I guess the sheer # of tables in your schema
    causes such a delay. To avoid slow bootstrap theoretically it should
    be possible to persist the mapping on the client with some coding
    effort, however this ability does not exist in Cayenne as of now.

    Another thing is to make sure that the server is "warmed up" when the
    first client connects, as the server overhead of loading mapping for
    121000 entities and then converting them to client counterparts may be
    noticeable. So maybe call something like this on server startup:

    getDomain().getEntityResolver().getClientEntityResolver()

    Andrus

    On Jun 5, 2009, at 12:35 PM, Zissis Trabaris wrote:

    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model. After the client creates the connection, it authenticates the
    user by querying the user table (that table only currently has about 6
    rows in it). The initial query always takes about 30 seconds and then
    everything is fine on subsequent queries. I am wondering if
    something is
    going on with the first ROP client query. Is the client trying to
    cache
    the server's entity resolver data set?? Or is it something else? Is
    there any way to speed up the initial client query?



    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com *
    www.insysware.com <http://www.insysware.com/>

    ________________________________

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.

  • Zissis Trabaris at Jun 5, 2009 at 12:47 pm
    It's too bad we can't extend DispatchHelper. If we could I could define
    a new message called BootstrapZiped and send the client entity resolver
    in a compressed format over the wire and then sub class ClientChannel to
    send a BootstrapZiped message within getEntityResolver. It should not be
    difficult to extend DispatchHelper so that we can register our own
    callbacks and client messages. I wrote a quick and dirty simple example
    below if you want to use it:

    // Interface that must be implemented when creating a dispatch helper
    callback extension
    interface DispatchHelperCallback {

    public Object dispatch(DataChannel channel, ClientMessage message);
    }

    class DispatchHelper {

    private static ConcurrentHashMap<Class, DispatchHelperCallback>
    registeredCallbacks = new ConcurrentHashMap<Class, Class>();

    // Register user defined dispatch helper extensions
    static void registerDispatchHelperCallback(Class messageClass,
    DispatchHelperCallback callback) {
    DispatchHelper.registeredCallbacks.put(messageClass, callback);
    }

    static Object dispatch(DataChannel channel, ClientMessage message) {
    // do most common messages first...
    if (message instanceof QueryMessage) {
    return channel.onQuery(null, ((QueryMessage)
    message).getQuery());
    }
    else if (message instanceof SyncMessage) {
    SyncMessage sync = (SyncMessage) message;
    return channel.onSync(null, sync.getSenderChanges(),
    sync.getType());
    }
    else if (message instanceof BootstrapMessage) {
    return
    channel.getEntityResolver().getClientEntityResolver();
    }
    // check to see if we have a callback for this message and fire
    it if we do.
    else
    if(DispatchHelper.registeredCallbacks.containsKey(message.getClass()) {
    return
    DispatchHelper.registeredCallbacks.get(message.getClass()).dispatch(chan
    nel, message);
    }
    else {
    throw new CayenneRuntimeException(
    "Message dispatch error. Unsupported message: " +
    message);
    }
    }
    }

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 7:49 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    Correct - the first ROP access causes client to load all the mapping
    metadata from the server. I guess the sheer # of tables in your schema
    causes such a delay. To avoid slow bootstrap theoretically it should
    be possible to persist the mapping on the client with some coding
    effort, however this ability does not exist in Cayenne as of now.

    Another thing is to make sure that the server is "warmed up" when the
    first client connects, as the server overhead of loading mapping for
    121000 entities and then converting them to client counterparts may be
    noticeable. So maybe call something like this on server startup:

    getDomain().getEntityResolver().getClientEntityResolver()

    Andrus

    On Jun 5, 2009, at 12:35 PM, Zissis Trabaris wrote:

    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model. After the client creates the connection, it authenticates the
    user by querying the user table (that table only currently has about 6
    rows in it). The initial query always takes about 30 seconds and then
    everything is fine on subsequent queries. I am wondering if
    something is
    going on with the first ROP client query. Is the client trying to
    cache
    the server's entity resolver data set?? Or is it something else? Is
    there any way to speed up the initial client query?



    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com *
    www.insysware.com <http://www.insysware.com/>

    ________________________________

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.

  • Andrus Adamchik at Jun 5, 2009 at 12:59 pm
    You can delegate this task to your container by using HTTP gzip
    compression. E.g. Tomcat can compress the content for you (search for
    "compression" on this page) :

    http://tomcat.apache.org/tomcat-6.0-doc/config/http.html

    Other servers can too... The Java client should just pick it up
    automatically:

    http://www.caucho.com/support/hessian-interest/0506/0003.html

    Andrus
    On Jun 5, 2009, at 4:00 PM, Zissis Trabaris wrote:

    It's too bad we can't extend DispatchHelper. If we could I could
    define
    a new message called BootstrapZiped and send the client entity
    resolver
    in a compressed format over the wire and then sub class
    ClientChannel to
    send a BootstrapZiped message within getEntityResolver. It should
    not be
    difficult to extend DispatchHelper so that we can register our own
    callbacks and client messages. I wrote a quick and dirty simple
    example
    below if you want to use it:

    // Interface that must be implemented when creating a dispatch helper
    callback extension
    interface DispatchHelperCallback {

    public Object dispatch(DataChannel channel, ClientMessage message);
    }

    class DispatchHelper {

    private static ConcurrentHashMap<Class, DispatchHelperCallback>
    registeredCallbacks = new ConcurrentHashMap<Class, Class>();

    // Register user defined dispatch helper extensions
    static void registerDispatchHelperCallback(Class messageClass,
    DispatchHelperCallback callback) {
    DispatchHelper.registeredCallbacks.put(messageClass, callback);
    }

    static Object dispatch(DataChannel channel, ClientMessage
    message) {
    // do most common messages first...
    if (message instanceof QueryMessage) {
    return channel.onQuery(null, ((QueryMessage)
    message).getQuery());
    }
    else if (message instanceof SyncMessage) {
    SyncMessage sync = (SyncMessage) message;
    return channel.onSync(null, sync.getSenderChanges(),
    sync.getType());
    }
    else if (message instanceof BootstrapMessage) {
    return
    channel.getEntityResolver().getClientEntityResolver();
    }
    // check to see if we have a callback for this message and fire
    it if we do.
    else
    if
    (DispatchHelper.registeredCallbacks.containsKey(message.getClass()) {
    return
    DispatchHelper
    .registeredCallbacks.get(message.getClass()).dispatch(chan
    nel, message);
    }
    else {
    throw new CayenneRuntimeException(
    "Message dispatch error. Unsupported message: " +
    message);
    }
    }
    }

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 7:49 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    Correct - the first ROP access causes client to load all the mapping
    metadata from the server. I guess the sheer # of tables in your schema
    causes such a delay. To avoid slow bootstrap theoretically it should
    be possible to persist the mapping on the client with some coding
    effort, however this ability does not exist in Cayenne as of now.

    Another thing is to make sure that the server is "warmed up" when the
    first client connects, as the server overhead of loading mapping for
    121000 entities and then converting them to client counterparts may be
    noticeable. So maybe call something like this on server startup:

    getDomain().getEntityResolver().getClientEntityResolver()

    Andrus

    On Jun 5, 2009, at 12:35 PM, Zissis Trabaris wrote:

    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model. After the client creates the connection, it authenticates the
    user by querying the user table (that table only currently has
    about 6
    rows in it). The initial query always takes about 30 seconds and then
    everything is fine on subsequent queries. I am wondering if
    something is
    going on with the first ROP client query. Is the client trying to
    cache
    the server's entity resolver data set?? Or is it something else? Is
    there any way to speed up the initial client query?



    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com *
    www.insysware.com <http://www.insysware.com/>

    ________________________________

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and
    unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system.
    Thank
    you.

  • Zissis Trabaris at Jun 5, 2009 at 1:08 pm
    We are using HTTPS and I don't believe this will work over SSL
    connections. It would also add a significant overhead since it will
    compress every request and every payload.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 8:59 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    You can delegate this task to your container by using HTTP gzip
    compression. E.g. Tomcat can compress the content for you (search for
    "compression" on this page) :

    http://tomcat.apache.org/tomcat-6.0-doc/config/http.html

    Other servers can too... The Java client should just pick it up
    automatically:

    http://www.caucho.com/support/hessian-interest/0506/0003.html

    Andrus
    On Jun 5, 2009, at 4:00 PM, Zissis Trabaris wrote:

    It's too bad we can't extend DispatchHelper. If we could I could
    define
    a new message called BootstrapZiped and send the client entity
    resolver
    in a compressed format over the wire and then sub class
    ClientChannel to
    send a BootstrapZiped message within getEntityResolver. It should
    not be
    difficult to extend DispatchHelper so that we can register our own
    callbacks and client messages. I wrote a quick and dirty simple
    example
    below if you want to use it:

    // Interface that must be implemented when creating a dispatch helper
    callback extension
    interface DispatchHelperCallback {

    public Object dispatch(DataChannel channel, ClientMessage message);
    }

    class DispatchHelper {

    private static ConcurrentHashMap<Class, DispatchHelperCallback>
    registeredCallbacks = new ConcurrentHashMap<Class, Class>();

    // Register user defined dispatch helper extensions
    static void registerDispatchHelperCallback(Class messageClass,
    DispatchHelperCallback callback) {
    DispatchHelper.registeredCallbacks.put(messageClass, callback);
    }

    static Object dispatch(DataChannel channel, ClientMessage
    message) {
    // do most common messages first...
    if (message instanceof QueryMessage) {
    return channel.onQuery(null, ((QueryMessage)
    message).getQuery());
    }
    else if (message instanceof SyncMessage) {
    SyncMessage sync = (SyncMessage) message;
    return channel.onSync(null, sync.getSenderChanges(),
    sync.getType());
    }
    else if (message instanceof BootstrapMessage) {
    return
    channel.getEntityResolver().getClientEntityResolver();
    }
    // check to see if we have a callback for this message and fire
    it if we do.
    else
    if
    (DispatchHelper.registeredCallbacks.containsKey(message.getClass()) {
    return
    DispatchHelper
    .registeredCallbacks.get(message.getClass()).dispatch(chan
    nel, message);
    }
    else {
    throw new CayenneRuntimeException(
    "Message dispatch error. Unsupported message: " +
    message);
    }
    }
    }

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 7:49 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    Correct - the first ROP access causes client to load all the mapping
    metadata from the server. I guess the sheer # of tables in your schema
    causes such a delay. To avoid slow bootstrap theoretically it should
    be possible to persist the mapping on the client with some coding
    effort, however this ability does not exist in Cayenne as of now.

    Another thing is to make sure that the server is "warmed up" when the
    first client connects, as the server overhead of loading mapping for
    121000 entities and then converting them to client counterparts may be
    noticeable. So maybe call something like this on server startup:

    getDomain().getEntityResolver().getClientEntityResolver()

    Andrus

    On Jun 5, 2009, at 12:35 PM, Zissis Trabaris wrote:

    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model. After the client creates the connection, it authenticates the
    user by querying the user table (that table only currently has
    about 6
    rows in it). The initial query always takes about 30 seconds and then
    everything is fine on subsequent queries. I am wondering if
    something is
    going on with the first ROP client query. Is the client trying to
    cache
    the server's entity resolver data set?? Or is it something else? Is
    there any way to speed up the initial client query?



    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com *
    www.insysware.com <http://www.insysware.com/>

    ________________________________

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and
    unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system.
    Thank
    you.

  • Aristedes Maniatis at Jun 5, 2009 at 1:51 pm

    On 5/6/09 11:20 PM, Zissis Trabaris wrote:
    We are using HTTPS and I don't believe this will work over SSL
    connections. It would also add a significant overhead since it will
    compress every request and every payload.
    The compression happens first and then SSL is applied on top, so it is
    perfectly possible to use both.
    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model.
    I am absolutely stunned. How do you manage such a database structure? I
    can only imagine that Cayenne Modeler runs out of RAM.

    Ari Maniatis
  • Zissis Trabaris at Jun 5, 2009 at 2:08 pm
    The Cayenne Modeler can't handle it. Hence, we created our own MDA
    modeling environment that can :) I have stress tested the environment to
    upwards of 500,000 tables and impressively the cayenne ROP runtime works
    flawlessly. Of course we have to use our own modeler in design time.
    Since we created our own modeler we are also benefiting from a few
    things that the cayenne modeler does not do such as a tree view
    representation of tables so that you can visual manage table and object
    relationships.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Aristedes Maniatis
    Sent: Friday, June 05, 2009 9:52 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long
    On 5/6/09 11:20 PM, Zissis Trabaris wrote:
    We are using HTTPS and I don't believe this will work over SSL
    connections. It would also add a significant overhead since it will
    compress every request and every payload.
    The compression happens first and then SSL is applied on top, so it is
    perfectly possible to use both.
    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model.
    I am absolutely stunned. How do you manage such a database structure? I
    can only imagine that Cayenne Modeler runs out of RAM.

    Ari Maniatis
  • Andrus Adamchik at Jun 5, 2009 at 2:27 pm
    Pretty cool. If your implementation of the visual modeling part were
    at all compatible with CayenneModeler, and if you were willing to
    donate that to Apache and help develop it here... ;-) Anyways, this is
    your IP, so I am only dreaming :-)

    Andrus

    On Jun 5, 2009, at 5:13 PM, Zissis Trabaris wrote:

    The Cayenne Modeler can't handle it. Hence, we created our own MDA
    modeling environment that can :) I have stress tested the
    environment to
    upwards of 500,000 tables and impressively the cayenne ROP runtime
    works
    flawlessly. Of course we have to use our own modeler in design time.
    Since we created our own modeler we are also benefiting from a few
    things that the cayenne modeler does not do such as a tree view
    representation of tables so that you can visual manage table and
    object
    relationships.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Aristedes Maniatis
    Sent: Friday, June 05, 2009 9:52 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long
    On 5/6/09 11:20 PM, Zissis Trabaris wrote:
    We are using HTTPS and I don't believe this will work over SSL
    connections. It would also add a significant overhead since it will
    compress every request and every payload.
    The compression happens first and then SSL is applied on top, so it is
    perfectly possible to use both.
    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model.
    I am absolutely stunned. How do you manage such a database
    structure? I
    can only imagine that Cayenne Modeler runs out of RAM.

    Ari Maniatis
  • Aristedes Maniatis at Jun 5, 2009 at 2:34 pm

    On 6/6/09 12:27 AM, Andrus Adamchik wrote:
    Pretty cool. If your implementation of the visual modeling part were at
    all compatible with CayenneModeler, and if you were willing to donate
    that to Apache and help develop it here... ;-) Anyways, this is your IP,
    so I am only dreaming :-)
    Perhaps, but the donor also gets great benefits in having a whole bunch
    of people helping to improve and maintain the code.

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some cleanup
    on it (mostly naming and style) and some commenting and commit it unless
    anyone has something to say.

    Ari Maniatis
  • Andrus Adamchik at Jun 5, 2009 at 2:48 pm
    [Let's take this to a separate thread.]
    On Jun 5, 2009, at 5:33 PM, Aristedes Maniatis wrote:

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some
    cleanup on it (mostly naming and style) and some commenting and
    commit it unless anyone has something to say.

    Could you please let it sit in Jira for some time. I'd like to review
    it, but can't do it right this second.

    Andrus
  • Andrus Adamchik at Jun 15, 2009 at 8:13 am
    Hi Jack, Ari

    Finally had some time to look at the patch. It is moving in the right
    direction, but there are still some issues we need to address:

    * DataMapElement ... While the name itself sounds ok, this implies
    that the DataMap itself can't be a DataMapElement. In 3.0 we do have
    some simple code generation capabilities for DataMap, so adding
    properties to the DataMap seems appropriate. So maybe come back to the
    idea of MappingObject? (also see the next point).

    * Making AbstractQuery extend from DataMapElement may or may not be
    ok, but note that not all queries that can be mapped extend
    AbstractQuery. In fact I'd like to get rid of this inheritance going
    forward... So looks like the whole DataMapElement/MappingObject should
    be an interface anyways.

    * DataMap: private List<String> propertyKeyList - I don't understand
    this one, and it is encoded in the XML. Before we add that to the
    schema, could you please explain why it should be there?

    * Patch for the schema includes the entire file. It is not clear what
    was changed there.

    * DataMapElement.Property inner class... Why is this an inner class?
    It is exposed via public methods to the end users, so let's make it a
    standalone class. Also if there is a notion of properties order in the
    element (is there?), I guess the property should be stored in the
    list. If there's no notion of

    * Property.getHolder() is not used anywhere. Let's not add API we
    don't need. Also since we have lots of DataMapElements in the DataMap,
    and only some will have properties, let's use lazy initialization of
    the map to save some memory.

    I also have some notes on the Modeler, but I suggest we settle on the
    core framework approach first, and do incremental patches. It is much
    easier to review and discuss things in small manageable pieces.

    Andrus





    On Jun 5, 2009, at 5:48 PM, Andrus Adamchik wrote:

    [Let's take this to a separate thread.]
    On Jun 5, 2009, at 5:33 PM, Aristedes Maniatis wrote:

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some
    cleanup on it (mostly naming and style) and some commenting and
    commit it unless anyone has something to say.

    Could you please let it sit in Jira for some time. I'd like to
    review it, but can't do it right this second.

    Andrus

  • Andrus Adamchik at Jun 15, 2009 at 8:19 am

    On Jun 15, 2009, at 11:12 AM, Andrus Adamchik wrote:
    Also if there is a notion of properties order in the element (is
    there?), I guess the property should be stored in the list. If
    there's no notion of
    Sorry... didn't finish this sentence. This was more of a question - do
    we care about properties ordering or simply displaying them in an
    alphabetic order is ok? I'd say alphabetic is ok. Any scenarios when
    the order might be important?

    Andrus
  • Aristedes Maniatis at Jun 15, 2009 at 8:50 am

    On 15/6/09 6:12 PM, Andrus Adamchik wrote:
    * DataMapElement ... While the name itself sounds ok, this implies that
    the DataMap itself can't be a DataMapElement. In 3.0 we do have some
    simple code generation capabilities for DataMap, so adding properties to
    the DataMap seems appropriate. So maybe come back to the
    idea of MappingObject? (also see the next point).
    I take your point, but I still think "DataMapElement" is more descriptive. Every class in Java is an Object, so using that word as part of the name conveys nothing, except that it is sort of a generic multi-purpose thing. At least DataMapElement is clear and to the point. And there is no reason why an Element can be used to describe theDataMap itself. Slightly odd, but not too confusing.


    * Making AbstractQuery extend from DataMapElement may or may not be ok,
    but note that not all queries that can be mapped extend AbstractQuery.
    Ah, why not? Shouldn't we have a rigorous class hierarchy so that common code can be kept in superclasses where they belong?

    In fact I'd like to get rid of this inheritance going forward... So
    looks like the whole DataMapElement/MappingObject should
    be an interface anyways.
    I don't have the experience you do in creating java libraries meant to be used by lots of people in different ways, but I can't see how moving to interfaces for this one thing will help. If interfaces are to be used, then perhaps the ultimate goal is that every 'data map element' should be only an interface, allowing a user to swap in any implementation they want without having to inherit from our classes. If not, then I think this half way mixture of inheritance and interfaces is confusing. There is already a mixture of the two I find sometimes disconcerting.


    * DataMap: private List<String> propertyKeyList - I don't understand
    this one, and it is encoded in the XML. Before we add that to the
    schema, could you please explain why it should be there?
    I think I see what Jack might have done there. That looks like it was used for the CM and should be removed. I'll take a look before it is committed.

    * Patch for the schema includes the entire file. It is not clear what
    was changed there.
    Most of it :-). The indenting changed because we used XSD inheritance to describe the way the property can be attached to the parent class, matching the Java hierarchy.

    * DataMapElement.Property inner class... Why is this an inner class? It
    is exposed via public methods to the end users, so let's make it a
    standalone class.
    I thought inner class made sense here. The naming is convenient and clearer: "DataMapElement.Property" rather than "DataMapElementProperty" shows the fact that it is intrinsically part of DataMapElement and not relevant as a "Property" outside of that usage. This is just about naming and style, and the decision based on what 'looked' right from the perspective of a user seeing this class. You originally wanted just a Map<String,String> of properties rather than a whole class, but I thought that this was a way to capture more information in the future: properties might have other attributes such as whether they travel to the client in ROP. But really, they are just a slightly enhanced Map, so an inner class seemed to capture that idea.

    Also if there is a notion of properties order in the
    element (is there?), I guess the property should be stored in the
    list. Do we care about properties ordering or simply displaying them in an alphabetic order is ok?
    I'd say alphabetic is ok. Any scenarios when the order might be important?
    I don't think order is important, so the CM can display it in whatever order makes sense.

    * Property.getHolder() is not used anywhere. Let's not add API we don't
    need. Also since we have lots of DataMapElements in the DataMap, and
    only some will have properties, let's use lazy initialization of
    the map to save some memory. Sure.
    I also have some notes on the Modeler, but I suggest we settle on the
    core framework approach first, and do incremental patches. It is much
    easier to review and discuss things in small manageable pieces.
    Fair enough. If Jack is still around he might like to do the tidying up, otherwise I'll look after it.


    Ari Maniatis
  • jackCHEN at Jun 15, 2009 at 9:35 am
    Hi Ari,Andrus:



    2009/6/15 Aristedes Maniatis <ari@maniatis.org>
    On 15/6/09 6:12 PM, Andrus Adamchik wrote:


    * DataMapElement ... While the name itself sounds ok, this implies that
    the DataMap itself can't be a DataMapElement. In 3.0 we do have some
    simple code generation capabilities for DataMap, so adding properties to
    the DataMap seems appropriate. So maybe come back to the
    idea of MappingObject? (also see the next point).
    I take your point, but I still think "DataMapElement" is more descriptive.
    Every class in Java is an Object, so using that word as part of the name
    conveys nothing, except that it is sort of a generic multi-purpose thing. At
    least DataMapElement is clear and to the point. And there is no reason why
    an Element can be used to describe theDataMap itself. Slightly odd, but not
    too confusing.



    * Making AbstractQuery extend from DataMapElement may or may not be ok,
    but note that not all queries that can be mapped extend AbstractQuery.
    Ah, why not? Shouldn't we have a rigorous class hierarchy so that common
    code can be kept in superclasses where they belong?


    In fact I'd like to get rid of this inheritance going forward... So
    looks like the whole DataMapElement/MappingObject should
    be an interface anyways.
    I don't have the experience you do in creating java libraries meant to be
    used by lots of people in different ways, but I can't see how moving to
    interfaces for this one thing will help. If interfaces are to be used, then
    perhaps the ultimate goal is that every 'data map element' should be only an
    interface, allowing a user to swap in any implementation they want without
    having to inherit from our classes. If not, then I think this half way
    mixture of inheritance and interfaces is confusing. There is already a
    mixture of the two I find sometimes disconcerting.



    * DataMap: private List<String> propertyKeyList - I don't understand
    this one, and it is encoded in the XML. Before we add that to the
    schema, could you please explain why it should be there?
    I think I see what Jack might have done there. That looks like it was used
    for the CM and should be removed. I'll take a look before it is committed.

    It is userd for the CM. New added "PropertyPanel" in CM needs a Property Key
    List of the DataMap when "PropertyPanel" is initialized. Before discuss the
    CM, ti should be removed. The old patch had no this change.


    * Patch for the schema includes the entire file. It is not clear what
    was changed there.
    Most of it :-). The indenting changed because we used XSD inheritance to
    describe the way the property can be attached to the parent class, matching
    the Java hierarchy.


    * DataMapElement.Property inner class... Why is this an inner class? It
    is exposed via public methods to the end users, so let's make it a
    standalone class.
    I thought inner class made sense here. The naming is convenient and
    clearer: "DataMapElement.Property" rather than "DataMapElementProperty"
    shows the fact that it is intrinsically part of DataMapElement and not
    relevant as a "Property" outside of that usage. This is just about naming
    and style, and the decision based on what 'looked' right from the
    perspective of a user seeing this class. You originally wanted just a
    Map<String,String> of properties rather than a whole class, but I thought
    that this was a way to capture more information in the future: properties
    might have other attributes such as whether they travel to the client in
    ROP. But really, they are just a slightly enhanced Map, so an inner class
    seemed to capture that idea.


    Also if there is a notion of properties order in the
    element (is there?), I guess the property should be stored in the
    list. Do we care about properties ordering or simply displaying them in an
    alphabetic order is ok?
    I'd say alphabetic is ok. Any scenarios when the order might be important?
    I don't think order is important, so the CM can display it in whatever
    order makes sense.


    * Property.getHolder() is not used anywhere. Let's not add API we don't
    need. Also since we have lots of DataMapElements in the DataMap, and
    only some will have properties, let's use lazy initialization of
    the map to save some memory.
    Sure.

    I also have some notes on the Modeler, but I suggest we settle on the
    core framework approach first, and do incremental patches. It is much
    easier to review and discuss things in small manageable pieces.
    Fair enough. If Jack is still around he might like to do the tidying up,
    otherwise I'll look after it.


    Ari Maniatis
  • Andrus Adamchik at Jun 15, 2009 at 11:13 am

    On Jun 15, 2009, at 12:34 PM, jackCHEN wrote:

    * DataMap: private List<String> propertyKeyList - I don't understand
    this one, and it is encoded in the XML. Before we add that to the
    schema, could you please explain why it should be there?
    I think I see what Jack might have done there. That looks like it
    was used
    for the CM and should be removed. I'll take a look before it is
    committed.

    It is userd for the CM. New added "PropertyPanel" in CM needs a
    Property Key
    List of the DataMap when "PropertyPanel" is initialized. Before
    discuss the
    CM, ti should be removed. The old patch had no this change.
    Great. I guess the new events can be removed as well for now.

    Andrus
  • jackCHEN at Jun 15, 2009 at 12:33 pm
    2009/6/15 Andrus Adamchik <andrus@objectstyle.org>
    On Jun 15, 2009, at 12:34 PM, jackCHEN wrote:

    * DataMap: private List<String> propertyKeyList - I don't understand
    this one, and it is encoded in the XML. Before we add that to the
    schema, could you please explain why it should be there?
    I think I see what Jack might have done there. That looks like it was
    used
    for the CM and should be removed. I'll take a look before it is
    committed.

    It is userd for the CM. New added "PropertyPanel" in CM needs a Property
    Key
    List of the DataMap when "PropertyPanel" is initialized. Before discuss
    the
    CM, ti should be removed. The old patch had no this change.
    Great. I guess the new events can be removed as well for now.


    That's right. "DataMapElementEvent" and "DataMapElementListener" can be
    removed for now.Both support "PropertyPanel" in CM.
    Andrus
  • Andrus Adamchik at Jun 15, 2009 at 11:12 am

    On Jun 15, 2009, at 11:49 AM, Aristedes Maniatis wrote:
    I take your point, but I still think "DataMapElement" is more
    descriptive. Every class in Java is an Object, so using that word as
    part of the name conveys nothing, except that it is sort of a
    generic multi-purpose thing. At least DataMapElement is clear and to
    the point. And there is no reason why an Element can be used to
    describe theDataMap itself. Slightly odd, but not too confusing.
    MappingElement then? Not tied to any particular class name and has no
    implied ownership.
    Shouldn't we have a rigorous class hierarchy so that common code can
    be kept in superclasses where they belong?

    I don't have the experience you do in creating java libraries meant
    to be used by lots of people in different ways, but I can't see how
    moving to interfaces for this one thing will help. If interfaces are
    to be used, then perhaps the ultimate goal is that every 'data map
    element' should be only an interface, allowing a user to swap in any
    implementation they want without having to inherit from our classes.
    I don't insist on using interface here, rather I oppose a common
    superclass for .map and .query. Inheritance hierarchies can be tricky
    - it's way too easy to mix together unrelated things, based on a
    single coincidental shared property (no pun intended with "property
    API" being developed here). So my rule of thumb is that when in doubt,
    don't use a common superclass for the sake of elusive reuse of a few
    lines of code.

    In fact we probably don't need a common interface without code
    reuse: .map and .query can handle properties separately in their own
    hierarchies. For the sake of simplicity initially I would even ignore
    queries completely, and concentrate on the mapping elements.
    If not, then I think this half way mixture of inheritance and
    interfaces is confusing. There is already a mixture of the two I
    find sometimes disconcerting.
    The current state of Cayenne is a result of evolution, not of a one
    time design, so there are some rough edges for sure.
    * DataMapElement.Property inner class... Why is this an inner class?
    It
    is exposed via public methods to the end users, so let's make it a
    standalone class.
    I thought inner class made sense here. The naming is convenient and
    clearer: "DataMapElement.Property" rather than
    "DataMapElementProperty" shows the fact that it is intrinsically
    part of DataMapElement and not relevant as a "Property" outside of
    that usage. This is just about naming and style, and the decision
    based on what 'looked' right from the perspective of a user seeing
    this class. You originally wanted just a Map<String,String> of
    properties rather than a whole class, but I thought that this was a
    way to capture more information in the future: properties might have
    other attributes such as whether they travel to the client in ROP.
    But really, they are just a slightly enhanced Map, so an inner class
    seemed to capture that idea.
    This is just a matter of API style consistency - in Cayenne we do not
    have *public* inner classes at all. So I'd vote for
    org.apache.cayenne.map.Property.

    Also if there is a notion of properties order in the
    element (is there?), I guess the property should be stored in the
    list. Do we care about properties ordering or simply displaying
    them in an alphabetic order is ok?
    I'd say alphabetic is ok. Any scenarios when the order might be
    important?
    I don't think order is important, so the CM can display it in
    whatever order makes sense.
    If order is not important, and we don't have to store properties in a
    list as a result, we may not even need to store Property.key inside
    the property. To me a key is what a holder decided to name the
    property, not something that a property itself knows about.

    Andrus
  • jackCHEN at Jun 15, 2009 at 1:53 pm
    2009/6/15 Andrus Adamchik <andrus@objectstyle.org>
    On Jun 15, 2009, at 11:49 AM, Aristedes Maniatis wrote:

    I take your point, but I still think "DataMapElement" is more descriptive.
    Every class in Java is an Object, so using that word as part of the name
    conveys nothing, except that it is sort of a generic multi-purpose thing. At
    least DataMapElement is clear and to the point. And there is no reason why
    an Element can be used to describe theDataMap itself. Slightly odd, but not
    too confusing.
    MappingElement then? Not tied to any particular class name and has no
    implied ownership.

    Shouldn't we have a rigorous class hierarchy so that common code can be
    kept in superclasses where they belong?

    I don't have the experience you do in creating java libraries meant to be
    used by lots of people in different ways, but I can't see how moving to
    interfaces for this one thing will help. If interfaces are to be used, then
    perhaps the ultimate goal is that every 'data map element' should be only an
    interface, allowing a user to swap in any implementation they want without
    having to inherit from our classes.
    I don't insist on using interface here, rather I oppose a common superclass
    for .map and .query. Inheritance hierarchies can be tricky - it's way too
    easy to mix together unrelated things, based on a single coincidental shared
    property (no pun intended with "property API" being developed here). So my
    rule of thumb is that when in doubt, don't use a common superclass for the
    sake of elusive reuse of a few lines of code.

    In fact we probably don't need a common interface without code reuse: .map
    and .query can handle properties separately in their own hierarchies. For
    the sake of simplicity initially I would even ignore queries completely, and
    concentrate on the mapping elements.

    If not, then I think this half way mixture of inheritance and interfaces is
    confusing. There is already a mixture of the two I find sometimes
    disconcerting.
    The current state of Cayenne is a result of evolution, not of a one time
    design, so there are some rough edges for sure.

    * DataMapElement.Property inner class... Why is this an inner class? It
    is exposed via public methods to the end users, so let's make it a
    standalone class.
    I thought inner class made sense here. The naming is convenient and
    clearer: "DataMapElement.Property" rather than "DataMapElementProperty"
    shows the fact that it is intrinsically part of DataMapElement and not
    relevant as a "Property" outside of that usage. This is just about naming
    and style, and the decision based on what 'looked' right from the
    perspective of a user seeing this class. You originally wanted just a
    Map<String,String> of properties rather than a whole class, but I thought
    that this was a way to capture more information in the future: properties
    might have other attributes such as whether they travel to the client in
    ROP. But really, they are just a slightly enhanced Map, so an inner class
    seemed to capture that idea.
    This is just a matter of API style consistency - in Cayenne we do not have
    *public* inner classes at all. So I'd vote for
    org.apache.cayenne.map.Property.


    Also if there is a notion of properties order in the
    element (is there?), I guess the property should be stored in the
    list. Do we care about properties ordering or simply displaying them in
    an alphabetic order is ok?
    I'd say alphabetic is ok. Any scenarios when the order might be
    important?
    I don't think order is important, so the CM can display it in whatever
    order makes sense.
    If order is not important, and we don't have to store properties in a list
    as a result, we may not even need to store Property.key inside the property.
    To me a key is what a holder decided to name the property, not something
    that a property itself knows about.

    I think that the key is needed inside the property. Function of property may
    be extended in future base on the key. Now, the properties in each
    DataMapElement/MappingElement are stored using SortedMap, just like Entity
    using SortedMap to store its attributes and relationships.

    *Also since we have lots of DataMapElements in the DataMap, and only some
    will have properties, let's use lazy initialization of the map to save some
    memory.*

    You are right, it should be modified to lazy initialization.


    Andrus
  • Andrus Adamchik at Jun 15, 2009 at 2:10 pm

    On Jun 15, 2009, at 4:52 PM, jackCHEN wrote:

    I think that the key is needed inside the property. Function of
    property may be extended in future base on the key.
    Hi Jack,

    This is a possibility, although I can't think of any meaningful
    examples right now. During code generation (the main use of
    properties) the key will be still available - from the Map<String,
    Property> attached to the Element. But until we really need it, I am
    in favor of the "less is better" approach.

    Cheers,
    Andrus
  • Zissis Trabaris at Jun 5, 2009 at 2:50 pm
    You are absolutely correct. Once this product comes out of beta we might
    be inclined to donate the modeling environment code. Since it's a 100%
    embeddable library it should be quite easy to integrate it into the
    Cayenne modeler. I would rather not have to maintain it since it's not
    really part of application runtime IP but just a necessary component of
    the dev environment. Another interesting benefit of this modeler is that
    it is coded as an ROP client component therefore you can use it over
    HTTP.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Aristedes Maniatis
    Sent: Friday, June 05, 2009 10:34 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long
    On 6/6/09 12:27 AM, Andrus Adamchik wrote:
    Pretty cool. If your implementation of the visual modeling part were at
    all compatible with CayenneModeler, and if you were willing to donate
    that to Apache and help develop it here... ;-) Anyways, this is your IP,
    so I am only dreaming :-)
    Perhaps, but the donor also gets great benefits in having a whole bunch
    of people helping to improve and maintain the code.

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some cleanup
    on it (mostly naming and style) and some commenting and commit it unless

    anyone has something to say.

    Ari Maniatis
  • Andrus Adamchik at Jun 5, 2009 at 3:58 pm
    Sounds great :-)

    It is definitely too early to talk about the details, but let me just
    mention one important aspect here. A pure donation of a code rarely
    works out well without a desire of the original authors to at least
    help to integrate it, and ideally lead the development/maintenance
    effort in the open source environment. We had such experience with
    Cayenne DataViews technology which is an excellent piece of
    engineering, but with nobody to lead it, it quietly died and was
    excluded from Cayenne.

    Andrus
    On Jun 5, 2009, at 6:02 PM, Zissis Trabaris wrote:
    You are absolutely correct. Once this product comes out of beta we
    might
    be inclined to donate the modeling environment code. Since it's a 100%
    embeddable library it should be quite easy to integrate it into the
    Cayenne modeler. I would rather not have to maintain it since it's not
    really part of application runtime IP but just a necessary component
    of
    the dev environment. Another interesting benefit of this modeler is
    that
    it is coded as an ROP client component therefore you can use it over
    HTTP.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Aristedes Maniatis
    Sent: Friday, June 05, 2009 10:34 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long
    On 6/6/09 12:27 AM, Andrus Adamchik wrote:
    Pretty cool. If your implementation of the visual modeling part were at
    all compatible with CayenneModeler, and if you were willing to donate
    that to Apache and help develop it here... ;-) Anyways, this is your IP,
    so I am only dreaming :-)
    Perhaps, but the donor also gets great benefits in having a whole
    bunch
    of people helping to improve and maintain the code.

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some
    cleanup
    on it (mostly naming and style) and some commenting and commit it
    unless

    anyone has something to say.

    Ari Maniatis
  • Zissis Trabaris at Jun 5, 2009 at 4:01 pm
    It we choose to donate the code it would be in our best interest as well
    if I lead the maintenance and development of it. We are still a few
    months away from even considering it at this point though.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 11:58 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    Sounds great :-)

    It is definitely too early to talk about the details, but let me just
    mention one important aspect here. A pure donation of a code rarely
    works out well without a desire of the original authors to at least
    help to integrate it, and ideally lead the development/maintenance
    effort in the open source environment. We had such experience with
    Cayenne DataViews technology which is an excellent piece of
    engineering, but with nobody to lead it, it quietly died and was
    excluded from Cayenne.

    Andrus
    On Jun 5, 2009, at 6:02 PM, Zissis Trabaris wrote:
    You are absolutely correct. Once this product comes out of beta we
    might
    be inclined to donate the modeling environment code. Since it's a 100%
    embeddable library it should be quite easy to integrate it into the
    Cayenne modeler. I would rather not have to maintain it since it's not
    really part of application runtime IP but just a necessary component
    of
    the dev environment. Another interesting benefit of this modeler is
    that
    it is coded as an ROP client component therefore you can use it over
    HTTP.

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Aristedes Maniatis
    Sent: Friday, June 05, 2009 10:34 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long
    On 6/6/09 12:27 AM, Andrus Adamchik wrote:
    Pretty cool. If your implementation of the visual modeling part were at
    all compatible with CayenneModeler, and if you were willing to donate
    that to Apache and help develop it here... ;-) Anyways, this is your IP,
    so I am only dreaming :-)
    Perhaps, but the donor also gets great benefits in having a whole
    bunch
    of people helping to improve and maintain the code.

    Back on dev topics, Jack has finished his secondment at ish now and
    posted his DataMapElement.Property implementation. I'll do some
    cleanup
    on it (mostly naming and style) and some commenting and commit it
    unless

    anyone has something to say.

    Ari Maniatis
  • Zissis Trabaris at Jun 5, 2009 at 1:02 pm
    Formatting got lost in the transition.
    // Interface that must be implemented when creating a dispatch helper
    callback extension
    interface DispatchHelperCallback {

    public Object dispatch(DataChannel channel, ClientMessage message);
    }

    class DispatchHelper {

    private static ConcurrentHashMap<Class, DispatchHelperCallback>
    registeredCallbacks = new ConcurrentHashMap<Class, Class>();

    // Register user defined dispatch helper extensions
    static void registerDispatchHelperCallback(Class messageClass,
    DispatchHelperCallback callback) {
    DispatchHelper.registeredCallbacks.put(messageClass, callback);
    }

    static Object dispatch(DataChannel channel, ClientMessage message) {
    // do most common messages first...
    if (message instanceof QueryMessage) {
    return channel.onQuery(null,
    ((QueryMessage)message).getQuery());
    }
    else if (message instanceof SyncMessage) {
    SyncMessage sync = (SyncMessage) message;
    return channel.onSync(null, sync.getSenderChanges(),
    sync.getType());
    }
    else if (message instanceof BootstrapMessage) {
    return
    channel.getEntityResolver().getClientEntityResolver();
    }
    // check to see if we have a callback for this message and fire
    it if we do.
    else if
    (DispatchHelper.registeredCallbacks.containsKey(message.getClass()) {
    return
    DispatchHelper.registeredCallbacks.get(message.getClass()).dispatch(chan
    nel, message);
    }
    else {
    throw new CayenneRuntimeException("Message dispatch error.
    Unsupported message: " + message);
    }
    }
    }


    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Zissis Trabaris
    Sent: Friday, June 05, 2009 9:00 AM
    To: dev@cayenne.apache.org
    Subject: RE: Initial ROP client query takes way to long

    It's too bad we can't extend DispatchHelper. If we could I could define
    a new message called BootstrapZiped and send the client entity resolver
    in a compressed format over the wire and then sub class ClientChannel to
    send a BootstrapZiped message within getEntityResolver. It should not be
    difficult to extend DispatchHelper so that we can register our own
    callbacks and client messages. I wrote a quick and dirty simple example
    below if you want to use it:

    // Interface that must be implemented when creating a dispatch helper
    callback extension
    interface DispatchHelperCallback {

    public Object dispatch(DataChannel channel, ClientMessage message);
    }

    class DispatchHelper {

    private static ConcurrentHashMap<Class, DispatchHelperCallback>
    registeredCallbacks = new ConcurrentHashMap<Class, Class>();

    // Register user defined dispatch helper extensions
    static void registerDispatchHelperCallback(Class messageClass,
    DispatchHelperCallback callback) {
    DispatchHelper.registeredCallbacks.put(messageClass, callback);
    }

    static Object dispatch(DataChannel channel, ClientMessage message) {
    // do most common messages first...
    if (message instanceof QueryMessage) {
    return channel.onQuery(null, ((QueryMessage)
    message).getQuery());
    }
    else if (message instanceof SyncMessage) {
    SyncMessage sync = (SyncMessage) message;
    return channel.onSync(null, sync.getSenderChanges(),
    sync.getType());
    }
    else if (message instanceof BootstrapMessage) {
    return
    channel.getEntityResolver().getClientEntityResolver();
    }
    // check to see if we have a callback for this message and fire
    it if we do.
    else
    if(DispatchHelper.registeredCallbacks.containsKey(message.getClass()) {
    return
    DispatchHelper.registeredCallbacks.get(message.getClass()).dispatch(chan
    nel, message);
    }
    else {
    throw new CayenneRuntimeException(
    "Message dispatch error. Unsupported message: " +
    message);
    }
    }
    }

    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com * www.insysware.com

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.


    -----Original Message-----
    From: Andrus Adamchik
    Sent: Friday, June 05, 2009 7:49 AM
    To: dev@cayenne.apache.org
    Subject: Re: Initial ROP client query takes way to long

    Correct - the first ROP access causes client to load all the mapping
    metadata from the server. I guess the sheer # of tables in your schema
    causes such a delay. To avoid slow bootstrap theoretically it should
    be possible to persist the mapping on the client with some coding
    effort, however this ability does not exist in Cayenne as of now.

    Another thing is to make sure that the server is "warmed up" when the
    first client connects, as the server overhead of loading mapping for
    121000 entities and then converting them to client counterparts may be
    noticeable. So maybe call something like this on server startup:

    getDomain().getEntityResolver().getClientEntityResolver()

    Andrus

    On Jun 5, 2009, at 12:35 PM, Zissis Trabaris wrote:

    Here is the scenario ... We have a database with over 121,000 tables
    mapped in cayenne running under an out of the box ROP client server
    model. After the client creates the connection, it authenticates the
    user by querying the user table (that table only currently has about 6
    rows in it). The initial query always takes about 30 seconds and then
    everything is fine on subsequent queries. I am wondering if
    something is
    going on with the first ROP client query. Is the client trying to
    cache
    the server's entity resolver data set?? Or is it something else? Is
    there any way to speed up the initial client query?



    Zissis Trabaris * Chief Technology Officer * INSYSWARE * 3235 West
    River
    Road, Grand Island, New York, 14072, USA
    Mobile (716) 930-5654 * Office (518) 636-4118 * Fax (716) 625-1305 *
    z.trabaris@insysware.com *
    www.insysware.com <http://www.insysware.com/>

    ________________________________

    CONFIDENTIALITY: This email (including any attachments) may contain
    confidential, proprietary and privileged information, and unauthorized
    disclosure or use is prohibited. If you received this email in error,
    please notify the sender and delete this email from your system. Thank
    you.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdev @
categoriescayenne
postedJun 5, '09 at 9:23a
activeJun 15, '09 at 2:10p
posts23
users4
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase