You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de> on 2012/01/18 16:33:38 UTC

Some more concrete questions about Cayenne

Hi,

Cayenne is now getting nearer to "we may actually try this" status here, mostly because Hibernate keeps making things complicated.
Which means I'm going to ask some rather specific and convoluted questions; please feel free to answer just some of them.


1) Does anybody have concrete advice about using Cayenne without Modeler?

Background:
I see Modeler is one of the major sources of "huh?" moments on the list. It's an additional layer of abstraction between what Cayenne does and what the developer sees, meaning it can introduce problems (and occasionally does); I'd want to get my feet wet with Cayenne without that complication.
I also see it's the one part that you actually can avoid using - the XML can be edited by hand.

Now the potential problems I see with hand-editing the XML:

1a) Is there a DTD? Without a DTD, hand editing becomes too cumbersome and error-prone.

1b) Does Cayenne offer a way to check consistency between XML and a database? (I wouldn't object to using Modeler for that limited purpose. That might even be a good way to getting used to Modeler's view of the data model. I guess the answer is "yes", the modeler docs talk about "Validation of created mappings", but it would be nice to confirm I'm not misunderstanding something here.)

1c) If there's a way to check consistency, are inconsistencies reported in a way that a Cayenne newbie would understand? Such error messages can be difficult to generate, they'd need to detail both the involved RDBMS concepts (tables, fields, lengths, precisions, FKs etc.) and the involved Cayenne concepts (class definitions, associations). And since an error means these are out of sync, the error message would need to be as precise as possible about the nature of the inconsistency, which is no mean feat.


2) How would one assign a "field type" with a field in a Cayenne Pojo?

With "field type", I mean things like
123456789012345678901234567890123456789012345678901234567890123456789012
- Associating textual representation with field contents, such as
-- shorthands in the database table, Java enums internally,
   longer texts on display
-- or maybe shorthands in the database table, Java Strings internally,
   longer texts on display
- What Swing controls to use for displaying this data
  ("Renderer" in Swing terminology)
- What Swing controls to use for editing this data
  ("Editor" in Swing terminology)
- Validation info: valid ranges; probably a Java interface with
  implementations that may or may not use RDBMS length/precision info
- Possibly association with more than one field
  (date/time in two fields but merged into one Java property)
  (or still two Java properties, but validation etc. spans all of them)

I see various possible approaches:

2a) The traditional Cayenne approach. Make the entity class a superclass, the business class a subclass. Entity class properties would have private members and protected getters/setters, the business class would then use a FieldType object to delegate public getters/setters to the protected getters/setters. (FieldType objects would be static and accept entity objects as parameters, so memory bloat isn't an issue. I'm using a similar construction in my current Hibernate infrastructure.)
I'm a bit worried about the amount of boilerplate needed in the business class. In particular for the trivial cases where the DB field is simply handed through to the business logic (e.g. address fields where the end user should be able to put in pretty anything they choose as long as it fits the database field).

2b) Use delegation instead of subclassing. The issues are essentially the same, except the getters/setters of the entity class wouldn't have to be package-private or public instead of protected.
Are there other issues that I should be aware of?

2c) Since I'm not too dependent on Modeler, I might merge entity and business class.
I'm not sure that such a merge has any advantages; does anybody have seen this tried? Stories of failure and success equally interesting here.
I have to admit I don't expect success, merging abstractions usually doesn't work well in the long term; losing the option to use Modeler's code generation later when we're more confident in it is a strong point agains that route, too. Still, I'd like to know how much water this assessment holds.

2d) Anything I haven't thought of. Different ways to use Java reflection, a Modeler option I'm not aware of that does all these things out of the box, whatever.


3) How do I do cascading?

I have seen some mention of this in the docs but haven't found a comprehensive description.

3a) Less is more. Abstract is better than concrete.
Hibernate shows how not do do this: theres roughly half a dozen cascale options for each association, each labelled with the name of one database-level operation, but little or no documentation on what high-level operation invokes which database-level cascade.
How's this done in Cayenne?

3b) Is there a way to do a cascading "check for inconsistencies between entity objects in the persistence context and database rows"?
One approach to that might be a full reload of all objects and reporting back if there are inconsistent updates.
Another might be some forced update on the dependent object, so only the master objects "above" a changed object need to be checked, then updated.

The background is that we want to allow the occasional inconsistency introduced via manual updates, but not via the application.
We do have consistency conditions that aren't easily enforced using database constraints or update triggers (besides, an update trigger would require a reload from the application, so now I have to do the are-we-still-in-sync check anyway).


4) Can I do mixed scalar/object queries?

I need to retrieve a list of entities, plus some statistical data.
In SQL terms, this might look like
  SELECT orders.*, SUM(detail.itemprice * detail.quantity), COUNT(detail.id)
  GROUP BY <all fields of table "orders" here>
Yes, I want to keep the detail counting, multiplying and sorting on the database server, to keep network traffic down.
I'd also want to get all fields of the "orders" table in an Orders Pojo.
The result of the query would either be an Object[], or a Javabean with fields for the Orders object, a BigDecimal for the total price and a BigInteger for the detail count.
(I haven't found a way to do this efficiently in Hibernate. I have spent more than a week on this and am approaching the point where switching to Cayenne would have been less work. Presumably ;-/ )
http://cayenne.apache.org/doc30/sqltemplate-result-mapping.html indicates that this is indeed possible - is that correct? Did somebody use it in anger already?


Any feedback welcome :-)

Regards,
Jo

RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
>> Oh... you can write extensions to Modeler?
>> Is there an official interface for that?
> 
> I don't think this made it into the official code.

Ah. Pity.
Unfortunately, it's unlikely that I'll get the time budget to do this.

Ah well. I think I'll go with the script-from-external-sources route anyway.

Assuming Cayenne does indeed make it into our project.
I'm still exploring possibilities... and Hibernate seems to work "well enough" again *sigh*.
Anyway, this has been digging up interesting details, and maybe given the devs some interesting data points, too, so I hope this all is going to do some good in the end :-)

Regards,
Jo

Re: Some more concrete questions about Cayenne

Posted by Mike Kienenberger <mk...@gmail.com>.
On Thu, Jan 19, 2012 at 11:44 AM, Durchholz, Joachim
<Jo...@hennig-fahrzeugteile.de> wrote:
> Oh... you can write extensions to Modeler?
> Is there an official interface for that?

I don't think this made it into the official code.   It was part of
the tail-end of the last active Cayenne project I worked on before
politics changed that project from Cayenne to JPA.

I think I decided not to pursue it because (1) I wouldn't be around to
maintain it, and (2) there was already ongoing discussion about the
best way to allow modeler extensions.

The actual changes to allow extensions is pretty simple and small,
although "detecting" extensions in this version involves specifying an
"org.apache.cayenne.modeler.cayenneActionPluginFactory" System
property and including your extensions in the classpath.

But at the time, it worked well enough for my purposes.

I haven't followed the modeler development closely since then (2007?)
so I am not sure what, if any, extensions points currently exist.   My
guess is that it would be easy for you integrate this into the current
code base -- really, it's a quick easy hack to add menu items to
various modeler menus.


Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/CayenneModelerFrame.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/CayenneModelerFrame.java	(revision
432015)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/CayenneModelerFrame.java	(working
copy)
@@ -60,6 +60,8 @@
 import java.awt.FlowLayout;
 import java.awt.Font;
 import java.awt.event.KeyEvent;
+import java.util.Iterator;
+import java.util.List;

 import javax.swing.Box;
 import javax.swing.JFrame;
@@ -111,6 +113,8 @@
 import org.objectstyle.cayenne.modeler.event.ProcedureDisplayListener;
 import org.objectstyle.cayenne.modeler.event.QueryDisplayEvent;
 import org.objectstyle.cayenne.modeler.event.QueryDisplayListener;
+import org.objectstyle.cayenne.modeler.plugin.CayenneActionPlugin;
+import org.objectstyle.cayenne.modeler.plugin.CayenneActionPluginManager;
 import org.objectstyle.cayenne.modeler.util.CayenneAction;
 import org.objectstyle.cayenne.modeler.util.RecentFileMenu;

@@ -209,6 +213,24 @@
         menuBar.add(fileMenu);
         menuBar.add(projectMenu);
         menuBar.add(toolMenu);
+
+        List cayennePluginActionList =
CayenneActionPluginManager.getInstance().getCayenneActionPluginList();
+        if (null != cayennePluginActionList)
+        {
+            JMenu pluginsMenu = new JMenu("Extensions");
+            if (!SystemUtils.IS_OS_MAC_OSX) {
+                pluginsMenu.setMnemonic(KeyEvent.VK_X);
+            }
+
+            Iterator cayennePluginActionIterator =
cayennePluginActionList.iterator();
+            while (cayennePluginActionIterator.hasNext()) {
+                CayenneActionPlugin cayennePluginAction =
(CayenneActionPlugin) cayennePluginActionIterator.next();
+
pluginsMenu.add(getAction(cayennePluginAction.getActionName()).buildMenu());
+            }
+
+            menuBar.add(pluginsMenu);
+        }
+
         menuBar.add(helpMenu);

         setJMenuBar(menuBar);
Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/ActionManager.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/ActionManager.java	(revision
432015)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/ActionManager.java	(working
copy)
@@ -61,6 +61,7 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;

 import javax.swing.Action;
@@ -100,6 +101,8 @@
 import org.objectstyle.cayenne.modeler.action.SaveAction;
 import org.objectstyle.cayenne.modeler.action.SaveAsAction;
 import org.objectstyle.cayenne.modeler.action.ValidateAction;
+import org.objectstyle.cayenne.modeler.plugin.CayenneActionPlugin;
+import org.objectstyle.cayenne.modeler.plugin.CayenneActionPluginManager;
 import org.objectstyle.cayenne.modeler.util.CayenneAction;

 /**
@@ -167,6 +170,44 @@
     protected Map actionMap;

     public ActionManager(Application application) {
+
+        List cayennePluginActionList =
CayenneActionPluginManager.getInstance().getCayenneActionPluginList();
+        if (null != cayennePluginActionList)
+        {
+            Iterator cayennePluginActionIterator =
cayennePluginActionList.iterator();
+            while (cayennePluginActionIterator.hasNext()) {
+                CayenneActionPlugin cayennePluginAction =
(CayenneActionPlugin) cayennePluginActionIterator.next();
+                if (cayennePluginAction.isSpecialAction())
+                {
+                    SPECIAL_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isProjectAction())
+                {
+                    PROJECT_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isDomainAction())
+                {
+                    DOMAIN_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isDataMapAction())
+                {
+                    DATA_MAP_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isObjEntityAction())
+                {
+
OBJ_ENTITY_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isDbEntityAction())
+                {
+                    DB_ENTITY_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+                if (cayennePluginAction.isProcedureAction())
+                {
+                    PROCEDURE_ACTIONS.add(cayennePluginAction.getActionName());
+                }
+            }
+        }
+
         this.actionMap = new HashMap();

         registerAction(new ProjectAction(application));
@@ -204,6 +245,16 @@
         registerAction(new ExitAction(application)).setAlwaysOn(true);
         registerAction(new
NavigateBackwardAction(application)).setAlwaysOn(true);
         registerAction(new
NavigateForwardAction(application)).setAlwaysOn(true);
+
+        if (null != cayennePluginActionList)
+        {
+            Iterator cayennePluginActionIterator =
cayennePluginActionList.iterator();
+            while (cayennePluginActionIterator.hasNext()) {
+                CayenneActionPlugin cayennePluginAction =
(CayenneActionPlugin) cayennePluginActionIterator.next();
+
registerAction(cayennePluginAction.createCayenneAction(application));
+            }
+        }
+
     }

     private CayenneAction registerAction(CayenneAction action) {
Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPlugin.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPlugin.java	(revision
0)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPlugin.java	(revision
0)
@@ -0,0 +1,72 @@
+/* ====================================================================
+ *
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ *
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ *
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.modeler.plugin;
+
+import org.objectstyle.cayenne.modeler.Application;
+import org.objectstyle.cayenne.modeler.util.CayenneAction;
+
+
+public interface CayenneActionPlugin {
+    public String getActionName();
+    public CayenneAction createCayenneAction(Application application);
+    public boolean isSpecialAction();
+    public boolean isProjectAction();
+    public boolean isDomainAction();
+    public boolean isDataMapAction();
+    public boolean isObjEntityAction();
+    public boolean isDbEntityAction();
+    public boolean isProcedureAction();
+}

Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginFactory.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginFactory.java	(revision
0)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginFactory.java	(revision
0)
@@ -0,0 +1,63 @@
+/* ====================================================================
+ *
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ *
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ *
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.modeler.plugin;
+
+import java.util.List;
+
+
+public interface CayenneActionPluginFactory {
+    public List getCayenneActionPluginList();
+}

Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginManager.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginManager.java	(revision
0)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/CayenneActionPluginManager.java	(revision
0)
@@ -0,0 +1,111 @@
+/* ====================================================================
+ *
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ *
+ * Copyright (c) 2006, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any,
+ *    must include the following acknowlegement:
+ *    "This product includes software developed by independent contributors
+ *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ *    or promote products derived from this software without prior written
+ *    permission. For written permission, email
+ *    "andrus at objectstyle dot org".
+ *
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ *    names without prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site.  For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.modeler.plugin;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+public class CayenneActionPluginManager {
+
+    private static final Logger logObj =
Logger.getLogger(CayenneActionPluginManager.class);
+
+    private CayenneActionPluginFactory cayenneActionPluginFactory = null;
+    public CayenneActionPluginFactory getCayenneActionPluginFactory()
+    {
+        // TODO: retrieve somehow and allow multiple factories.
+        if (null == cayenneActionPluginFactory)
+        {
+            String pluginName =
System.getProperty("org.apache.cayenne.modeler.cayenneActionPluginFactory");
+            if (null != pluginName)
+            {
+                try {
+                    cayenneActionPluginFactory =
(CayenneActionPluginFactory)Class.forName(pluginName).newInstance();
+                }
+                catch (InstantiationException e) {
+                    logObj.error("InstantiationException error
instantiating cayenneActionPluginFactory", e);
+                }
+                catch (IllegalAccessException e) {
+                    logObj.error("IllegalAccessException error
instantiating cayenneActionPluginFactory", e);
+                }
+                catch (ClassNotFoundException e) {
+                    logObj.error("ClassNotFoundException error
instantiating cayenneActionPluginFactory", e);
+                }
+            }
+        }
+        return cayenneActionPluginFactory;
+    }
+
+    private static CayenneActionPluginManager instance = null;
+    public static CayenneActionPluginManager getInstance() {
+        if (null == instance)
+        {
+            instance = new CayenneActionPluginManager();
+        }
+        return instance;
+    }
+
+    public List getCayenneActionPluginList() {
+        CayenneActionPluginFactory cayenneActionPluginFactory =
getCayenneActionPluginFactory();
+        if (null != cayenneActionPluginFactory)
+        {
+            return
getCayenneActionPluginFactory().getCayenneActionPluginList();
+        }
+
+        return null;
+    }
+
+}
\ No newline at end of file

Index: E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/BaseCayenneActionPlugin.java
===================================================================
--- E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/BaseCayenneActionPlugin.java	(revision
0)
+++ E:/workspace311/cayenne-java/src/modeler/java/org/objectstyle/cayenne/modeler/plugin/BaseCayenneActionPlugin.java	(revision
0)
@@ -0,0 +1,34 @@
+package org.objectstyle.cayenne.modeler.plugin;
+
+import org.objectstyle.cayenne.modeler.Application;
+import org.objectstyle.cayenne.modeler.plugin.CayenneActionPlugin;
+import org.objectstyle.cayenne.modeler.util.CayenneAction;
+
+abstract public class BaseCayenneActionPlugin implements CayenneActionPlugin {
+
+    abstract public String getActionName();
+    abstract public CayenneAction createCayenneAction(Application application);
+
+    public boolean isSpecialAction() {
+        return false;
+    }
+    public boolean isProjectAction() {
+        return false;
+    }
+    public boolean isDomainAction() {
+        return false;
+    }
+    public boolean isDataMapAction() {
+        return false;
+    }
+    public boolean isObjEntityAction() {
+        return false;
+    }
+    public boolean isDbEntityAction() {
+        return false;
+    }
+    public boolean isProcedureAction() {
+        return false;
+    }
+
+}

RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
> The same project also worked with an in-house system where all of the
> "authoritative" metadata was stored in a database.   I wrote a simple
> extension to the modeler to automatically "import" from the metadata
> rather than the xml file, and then resave it to a standard cayenne format.

Oh... you can write extensions to Modeler?
Is there an official interface for that?

Thanks for the other infos.

Regards,
Jo

Re: Some more concrete questions about Cayenne

Posted by Mike Kienenberger <mk...@gmail.com>.
On Thu, Jan 19, 2012 at 8:55 AM, Durchholz, Joachim
<Jo...@hennig-fahrzeugteile.de> wrote:
> Delegation would give me more independence from the generated code, at the expense of some memory usage (which could become relevant since some of the things we do are bulk operations on hundreds of thousands of objects; some of the operations haven't been split into reasonably-sized auto-continuing transactions yet).

It's trivial to change the template to generate delegation patterns
instead.   I've done that in a project where either Cayenne or JPA
could be used as the backend.   In fact, I used Cayenne templates to
generate both backends.


The same project also worked with an in-house system where all of the
"authoritative" metadata was stored in a database.   I wrote a simple
extension to the modeler to automatically "import" from the metadata
rather than the xml file, and then resave it to a standard cayenne
format.


> I'm extremely wary of modifying templates. It means I have to revisit them on each and every Cayenne update to see whether the basic machinery has changed and I need to redo my modifications.

The templates are standard velocity templates with a very few number
of cayenne-specific attributes predefined.

I am fairly certain that the templating tasks have only changed once
in the last 8 years -- I did the upgrade -- and when they did change,
full backward compatibility was left in as an option.    I am not
using the 3.x branch yet, but I would expect that Cayenne 1.1
templates created back in 2004 would work just as well today.

Yes, it's always possible that the basic data structure behind the
Cayenne mapping could change, but I don't think that's happened yet,
other than perhaps new additions, which shouldn't affect older models.

RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
> Here are a few answers.

Thanks!
Very much appreciated.

>> 1) Does anybody have concrete advice about using Cayenne without Modeler?
>>
>> Background:
>> I see Modeler is one of the major sources of "huh?" moments on the list.
>> It's an additional layer of abstraction between what Cayenne does and 
>>> what the developer sees, meaning it can introduce problems (and 
>> occasionally does); I'd want to get my feet wet with Cayenne without that complication.
>> I also see it's the one part that you actually can avoid using - the 
>> XML can be edited by hand.
> 
> I don't see this as reducing complexity, rather it increases it since the
> tool is much easier to use and understand than an XML file.

Hm... well, Modeler adds a level of interpretation (if only implicitly) between user and XML.
For example, that "To Dep PK" checkbox doesn't sound quite self-explanatory.

Of course, it essentially depends on what's better documented: the XML or Modeler :-)

>  Having a model representation that is separate from the java files
> (i.e. not using embedded java annotations) is a big strength for Cayenne
> compared to Hibernate/JPA.

I see it the other way round: if the Java code and the specifications that it depends on are in the same file, it's easier to spot problems.
Of course, if the Java code in question is generated anyway, the question is moot.

>  The tool makes it both easier and better.

Noted. Thanks.


> Now the potential problems I see with hand-editing the XML:
>
> 1a) Is there a DTD? Without a DTD, hand editing becomes too cumbersome 
> and error-prone.

There is a schema:

<?xml version="1.0" encoding="utf-8"?>

<data-map xmlns="http://cayenne.apache.org/schema/3.0/modelMap" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://cayenne.apache.org/schema/3.0/modelMap
http://cayenne.apache.org/schema/3.0/modelMap.xsd" project-version="6">

Sweet :-)

>> 1b) Does Cayenne offer a way to check consistency between XML and a 
>> database?
> 
> Yes

Just through modeler, or is it available through an Ant task or its Maven equivalent?
Half a bonus point if it's in the Cayenne runtime jars since it would save me a configuration step :-)

>> 2) How would one assign a "field type" with a field in a Cayenne Pojo?
> 
> The objects in the data map (entites, attributes, etc) aren't extensible
> with arbitrary data currently (webobjects has this with the userInfo
> dictionary / hashmap).

I guess I'll go with the _Entity/Entity split then.
It's not a very big deal anyway.

>> 2d) Anything I haven't thought of. Different ways to use Java 
>> reflection, a Modeler option I'm not aware of that does all these 
>> things out of the box, whatever.
> 
> I'm not sure what you're trying to achieve here.

Just exploring possibilities.
Delegation would give me more independence from the generated code, at the expense of some memory usage (which could become relevant since some of the things we do are bulk operations on hundreds of thousands of objects; some of the operations haven't been split into reasonably-sized auto-continuing transactions yet).

>  Do you want to isolate Cayenne so that it is not "polluting" your business objects?

That is a factor in the back of my mind, but I think that can be handled using private fields and protected getters/setters and should not become a problem.

> Regardless, you will want to use Cayenne's code generation.  The
> templates are totally configurable so you can make it do whatever
> you like.

I'm extremely wary of modifying templates. It means I have to revisit them on each and every Cayenne update to see whether the basic machinery has changed and I need to redo my modifications.

Also, for some reason, templates tend to be hard to modify.
I tend to whince whenever I hear the word :-)
I don't know how it is for Cayenne though; among the problems I have seen elsewhere are:
- 

> The code generation is available via Modeler, ant, or the eclipse plugin.

That's very good.

Regards & thanks,
Jo

Re: Some more concrete questions about Cayenne

Posted by John Huss <jo...@gmail.com>.
Here are a few answers.

On Wed, Jan 18, 2012 at 9:33 AM, Durchholz, Joachim <
Joachim.Durchholz@hennig-fahrzeugteile.de> wrote:

> Hi,
>
> Cayenne is now getting nearer to "we may actually try this" status here,
> mostly because Hibernate keeps making things complicated.
> Which means I'm going to ask some rather specific and convoluted
> questions; please feel free to answer just some of them.
>
>
> 1) Does anybody have concrete advice about using Cayenne without Modeler?
>
> Background:
> I see Modeler is one of the major sources of "huh?" moments on the list.
> It's an additional layer of abstraction between what Cayenne does and what
> the developer sees, meaning it can introduce problems (and occasionally
> does); I'd want to get my feet wet with Cayenne without that complication.
> I also see it's the one part that you actually can avoid using - the XML
> can be edited by hand.
>

I don't see this as reducing complexity, rather it increases it since the
tool is much easier to use and understand than an XML file.  Having a model
representation that is separate from the java files (i.e. not using
embedded java annotations) is a big strength for Cayenne compared to
Hibernate/JPA.  The tool makes it both easier and better.


>
> Now the potential problems I see with hand-editing the XML:
>
> 1a) Is there a DTD? Without a DTD, hand editing becomes too cumbersome and
> error-prone.
>

There is a schema:

<?xml version="1.0" encoding="utf-8"?>

<data-map xmlns="http://cayenne.apache.org/schema/3.0/modelMap" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://cayenne.apache.org/schema/3.0/modelMap
http://cayenne.apache.org/schema/3.0/modelMap.xsd" project-version="6">

>
> 1b) Does Cayenne offer a way to check consistency between XML and a
> database?


Yes


> (I wouldn't object to using Modeler for that limited purpose. That might
> even be a good way to getting used to Modeler's view of the data model. I
> guess the answer is "yes", the modeler docs talk about "Validation of
> created mappings", but it would be nice to confirm I'm not misunderstanding
> something here.)
>
> 1c) If there's a way to check consistency, are inconsistencies reported in
> a way that a Cayenne newbie would understand? Such error messages can be
> difficult to generate, they'd need to detail both the involved RDBMS
> concepts (tables, fields, lengths, precisions, FKs etc.) and the involved
> Cayenne concepts (class definitions, associations). And since an error
> means these are out of sync, the error message would need to be as precise
> as possible about the nature of the inconsistency, which is no mean feat.
>
>
> 2) How would one assign a "field type" with a field in a Cayenne Pojo?
>
> With "field type", I mean things like
> 123456789012345678901234567890123456789012345678901234567890123456789012
> - Associating textual representation with field contents, such as
> -- shorthands in the database table, Java enums internally,
>   longer texts on display
> -- or maybe shorthands in the database table, Java Strings internally,
>   longer texts on display
> - What Swing controls to use for displaying this data
>  ("Renderer" in Swing terminology)
> - What Swing controls to use for editing this data
>  ("Editor" in Swing terminology)
> - Validation info: valid ranges; probably a Java interface with
>  implementations that may or may not use RDBMS length/precision info
> - Possibly association with more than one field
>  (date/time in two fields but merged into one Java property)
>  (or still two Java properties, but validation etc. spans all of them)
>

The objects in the data map (entites, attributes, etc) aren't extensible
with arbitrary data currently (webobjects has this with the userInfo
dictionary / hashmap).  But you could create separate file in your own
format that contains additional model information.


> I see various possible approaches:
>
> 2a) The traditional Cayenne approach. Make the entity class a superclass,
> the business class a subclass. Entity class properties would have private
> members and protected getters/setters, the business class would then use a
> FieldType object to delegate public getters/setters to the protected
> getters/setters. (FieldType objects would be static and accept entity
> objects as parameters, so memory bloat isn't an issue. I'm using a similar
> construction in my current Hibernate infrastructure.)
> I'm a bit worried about the amount of boilerplate needed in the business
> class. In particular for the trivial cases where the DB field is simply
> handed through to the business logic (e.g. address fields where the end
> user should be able to put in pretty anything they choose as long as it
> fits the database field).
>
> 2b) Use delegation instead of subclassing. The issues are essentially the
> same, except the getters/setters of the entity class wouldn't have to be
> package-private or public instead of protected.
> Are there other issues that I should be aware of?
>
> 2c) Since I'm not too dependent on Modeler, I might merge entity and
> business class.
> I'm not sure that such a merge has any advantages; does anybody have seen
> this tried? Stories of failure and success equally interesting here.
> I have to admit I don't expect success, merging abstractions usually
> doesn't work well in the long term; losing the option to use Modeler's code
> generation later when we're more confident in it is a strong point agains
> that route, too. Still, I'd like to know how much water this assessment
> holds.
>

You can combine the _Entity and Entity classes.  These are separated merely
for convenience (this is the Generation Gap pattern) so you can utilize the
code generation without overwriting your custom logic.


> 2d) Anything I haven't thought of. Different ways to use Java reflection,
> a Modeler option I'm not aware of that does all these things out of the
> box, whatever.
>

I'm not sure what you're trying to achieve here.  Do you want to isolate
Cayenne so that it is not "polluting" your business objects?

Regardless, you will want to use Cayenne's code generation.  The templates
are totally configurable so you can make it do whatever you like.  The code
generation is available via Modeler, ant, or the eclipse plugin.


>
>
> 3) How do I do cascading?
>
> I have seen some mention of this in the docs but haven't found a
> comprehensive description.
>
> 3a) Less is more. Abstract is better than concrete.
> Hibernate shows how not do do this: theres roughly half a dozen cascale
> options for each association, each labelled with the name of one
> database-level operation, but little or no documentation on what high-level
> operation invokes which database-level cascade.
> How's this done in Cayenne?
>
> 3b) Is there a way to do a cascading "check for inconsistencies between
> entity objects in the persistence context and database rows"?
> One approach to that might be a full reload of all objects and reporting
> back if there are inconsistent updates.
> Another might be some forced update on the dependent object, so only the
> master objects "above" a changed object need to be checked, then updated.
>
> The background is that we want to allow the occasional inconsistency
> introduced via manual updates, but not via the application.
> We do have consistency conditions that aren't easily enforced using
> database constraints or update triggers (besides, an update trigger would
> require a reload from the application, so now I have to do the
> are-we-still-in-sync check anyway).
>
>
> 4) Can I do mixed scalar/object queries?
>
> I need to retrieve a list of entities, plus some statistical data.
> In SQL terms, this might look like
>  SELECT orders.*, SUM(detail.itemprice * detail.quantity), COUNT(detail.id
> )
>  GROUP BY <all fields of table "orders" here>
> Yes, I want to keep the detail counting, multiplying and sorting on the
> database server, to keep network traffic down.
> I'd also want to get all fields of the "orders" table in an Orders Pojo.
> The result of the query would either be an Object[], or a Javabean with
> fields for the Orders object, a BigDecimal for the total price and a
> BigInteger for the detail count.
> (I haven't found a way to do this efficiently in Hibernate. I have spent
> more than a week on this and am approaching the point where switching to
> Cayenne would have been less work. Presumably ;-/ )
> http://cayenne.apache.org/doc30/sqltemplate-result-mapping.html indicates
> that this is indeed possible - is that correct? Did somebody use it in
> anger already?
>

I haven't done this.  QueryChain (I think that's what it's called) will let
you send multiple queries in one trip to the DB.  But if you want a single
query with diverse results then your suggestion will probably work better.

John

Re: Some more concrete questions about Cayenne

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 19/01/12 2:33 AM, Durchholz, Joachim wrote:


> I see Modeler is one of the major sources of "huh?" moments on the list. It's an additional layer of abstraction between what Cayenne does and what the developer sees, meaning it can introduce problems (and occasionally does); I'd want to get my feet wet with Cayenne without that complication.

I am not sure it introduces problems. Sure you can edit XML by hand, but modeler is a major convenience.

> 1b) Does Cayenne offer a way to check consistency between XML and a database? (I wouldn't object to using Modeler for that limited purpose. That might even be a good way to getting used to Modeler's view of the data model. I guess the answer is "yes", the modeler docs talk about "Validation of created mappings", but it would be nice to confirm I'm not misunderstanding something here.)

Look at the reverse engineering options in modeler.


> 1c) If there's a way to check consistency, are inconsistencies reported in a way that a Cayenne newbie would understand? Such error messages can be difficult to generate, they'd need to detail both the involved RDBMS concepts (tables, fields, lengths, precisions, FKs etc.) and the involved Cayenne concepts (class definitions, associations). And since an error means these are out of sync, the error message would need to be as precise as possible about the nature of the inconsistency, which is no mean feat.

Mainly you will get runtime errors when you try to fetch or save data. Sometimes they are clear and obvious. Sometimes less so.



> 2) How would one assign a "field type" with a field in a Cayenne Pojo?
>
> With "field type", I mean things like
> 123456789012345678901234567890123456789012345678901234567890123456789012
> - Associating textual representation with field contents, such as
> -- shorthands in the database table, Java enums internally,
>     longer texts on display
> -- or maybe shorthands in the database table, Java Strings internally,
>     longer texts on display

Cayenne has very nice support for enums. You can map against enums directly in the model and then define how those enums will be written to the database. This works well.


> - What Swing controls to use for displaying this data
>    ("Renderer" in Swing terminology)
> - What Swing controls to use for editing this data
>    ("Editor" in Swing terminology)

Cayenne isn't going to help you with building your UI. Yes, you can fire events in Swing to fetch and save data back to the entity objects, but you need to wire that all up yourself and wrap it with a controller that knows how to deal with Cayenne contexts.

> - Validation info: valid ranges; probably a Java interface with
>    implementations that may or may not use RDBMS length/precision info

Anything you can validate in Java code can be added to the entity classes.

> - Possibly association with more than one field
>    (date/time in two fields but merged into one Java property)

Sure. You can write any of this easily.


>    (or still two Java properties, but validation etc. spans all of them)

No problem. Validation can easily do this, since you are validating the whole object, not each attribute.


> I see various possible approaches:
>
> 2a) The traditional Cayenne approach. Make the entity class a superclass, the business class a subclass. Entity class properties would have private members and protected getters/setters, the business class would then use a FieldType object to delegate public getters/setters to the protected getters/setters. (FieldType objects would be static and accept entity objects as parameters, so memory bloat isn't an issue. I'm using a similar construction in my current Hibernate infrastructure.)
> I'm a bit worried about the amount of boilerplate needed in the business class. In particular for the trivial cases where the DB field is simply handed through to the business logic (e.g. address fields where the end user should be able to put in pretty anything they choose as long as it fits the database field).

What boilerplate? That class will be almost empty. And as John says, you can customise the velocity templates any way you like.


> 2b) Use delegation instead of subclassing. The issues are essentially the same, except the getters/setters of the entity class wouldn't have to be package-private or public instead of protected.
> Are there other issues that I should be aware of?
>
> 2c) Since I'm not too dependent on Modeler, I might merge entity and business class.
> I'm not sure that such a merge has any advantages; does anybody have seen this tried? Stories of failure and success equally interesting here.
> I have to admit I don't expect success, merging abstractions usually doesn't work well in the long term; losing the option to use Modeler's code generation later when we're more confident in it is a strong point agains that route, too. Still, I'd like to know how much water this assessment holds.

You are making this hard for yourself without any obvious gain.


> 2d) Anything I haven't thought of. Different ways to use Java reflection, a Modeler option I'm not aware of that does all these things out of the box, whatever.




> 3) How do I do cascading?
>
> I have seen some mention of this in the docs but haven't found a comprehensive description.

Do you mean cascading of deletes across relations? Or something else? Perhaps you want to play with the event listeners in the modeler. That might be what you are after.


Cheers
Ari



-- 
-------------------------->
Aristedes Maniatis
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A

RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
Thanks for the answer. 

> I have developed an application for cross country skiing
> competitions, time keeping, handling skiers, result service
> and so on using Cayenne. 
> What I have discovered when it comes to UI I just stuck with
> the generated Entity class and added new getters/setters to
> fit my GUI whenever needed.
> Now in retrospect it looks somewhat ugly because my GUI
> layout now "pollutes" the Entity class. [...]
> It is not my proudest design, but then again I does the job

I can see that :-)

Actually, our current code is in a state that isn't THAT different, but we're getting more and more into maintenance and adapation to different frontends (currently: migrating the stuff from desktop app to webservice). Separation will soon be a necessity.

> For the GUI part, I'n not using Swing. I use Apache Pivot
> which I think works great with Cayenne.

Wow. Pivot looks like a very interesting framework.
I wish I had noticed its release; it covers most if not all hard problems I'm facing right now.

Regards,
Jo

Re: Some more concrete questions about Cayenne

Posted by Tomas Stenlund <to...@telia.com>.
On 01/18/2012 04:33 PM, Durchholz, Joachim wrote:

Well I just do that, answer a few of the questions:
> ...
>
>
> 2) How would one assign a "field type" with a field in a Cayenne Pojo?
>
> With "field type", I mean things like
> 123456789012345678901234567890123456789012345678901234567890123456789012
> - Associating textual representation with field contents, such as
> -- shorthands in the database table, Java enums internally,
>     longer texts on display
> -- or maybe shorthands in the database table, Java Strings internally,
>     longer texts on display
> - What Swing controls to use for displaying this data
>    ("Renderer" in Swing terminology)
> - What Swing controls to use for editing this data
>    ("Editor" in Swing terminology)
> - Validation info: valid ranges; probably a Java interface with
>    implementations that may or may not use RDBMS length/precision info
> - Possibly association with more than one field
>    (date/time in two fields but merged into one Java property)
>    (or still two Java properties, but validation etc. spans all of them)
>
> I see various possible approaches:
>
> 2a) The traditional Cayenne approach. Make the entity class a superclass, the business class a subclass. Entity class properties would have private members and protected getters/setters, the business class would then use a FieldType object to delegate public getters/setters to the protected getters/setters. (FieldType objects would be static and accept entity objects as parameters, so memory bloat isn't an issue. I'm using a similar construction in my current Hibernate infrastructure.)
> I'm a bit worried about the amount of boilerplate needed in the business class. In particular for the trivial cases where the DB field is simply handed through to the business logic (e.g. address fields where the end user should be able to put in pretty anything they choose as long as it fits the database field).
>
> 2b) Use delegation instead of subclassing. The issues are essentially the same, except the getters/setters of the entity class wouldn't have to be package-private or public instead of protected.
> Are there other issues that I should be aware of?
>
> 2c) Since I'm not too dependent on Modeler, I might merge entity and business class.
> I'm not sure that such a merge has any advantages; does anybody have seen this tried? Stories of failure and success equally interesting here.
> I have to admit I don't expect success, merging abstractions usually doesn't work well in the long term; losing the option to use Modeler's code generation later when we're more confident in it is a strong point agains that route, too. Still, I'd like to know how much water this assessment holds.
>
> 2d) Anything I haven't thought of. Different ways to use Java reflection, a Modeler option I'm not aware of that does all these things out of the box, whatever.
I have developed an application for cross country skiing competitions, 
time keeping, handling skiers, result service and so on using Cayenne. 
What I have discovered when it comes to UI I just stuck with the 
generated Entity class and added new getters/setters to fit my GUI 
whenever needed. Now in retrospect it looks somewhat ugly because my GUI 
layout now "pollutes" the Entity class. Either way it works, it is fast 
and works great with Cayenne instead of maybe going with a nicer design 
with inheritance one additional level as suggested in 2a (actually the 
cayenne getters/setters would be visible as well). It gives me both 
benefits and drawbacks. It is not my proudest design, but then again I 
does the job and I learned to use Cayenne and the GUI-frameowork at the 
same time.

Now something completely different, 2d.

For the GUI part, I'n not using Swing. I use Apache Pivot which I think 
works great with Cayenne. It binds the controls to the getters/settes 
directly into a Pojo (e.g. the cayenne entity object) and also have 
support for datamapping, which allows you to move the data conversion 
from the cayenne entity more towards the GUI instead (which I would like 
to have it, instead of in the entities). Your "own" GUI-code is minimal 
in each dialog/window. I think this is a quite a nice approach that you 
could look at. But then again, this is GUI and not Cayenne.

Cheers,

Tomas





RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
> It is also worth noting that Cayenne modeler isn't validating its
> output or input against the schema right now. We didn't want to
> enable that and break XML files which work, but which did not meet
> the schema exactly (for example, XSD is very particular about the
> order of attributes).

I see a potential for Modeler introducing errors which might make other tools choke.
Is this a problem in practice?

Re: Some more concrete questions about Cayenne

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 20/01/12 8:21 PM, Erlend Birkenes wrote:
> 2012/1/20 Aristedes Maniatis<ar...@maniatis.org>
>
>> Not perfect, but this helps...
>>
>> http://cayenne.apache.org/**schema/3.0/indexList.html<http://cayenne.apache.org/schema/3.0/indexList.html>
>>
>> Happy to accept any help with getting better docs into the schema XSD.
>>
>>
> Thanks, I knew about that and it was very useful. It's not always obvious
> what the various tags are for, so it could use more descriptions. I
> generally had to do things in the Modeler and look at the resulting XML to
> figure out how to do things correctly. I have checked out the source, so
> I'll see if I can write some docs when I have some time.

Great. I think it would be terrifically useful to extract docs from javadocs and anywhere else we can, to insert into the XSD file. Then I can regenerate the docs and we'll get much more informative web pages.


> One of the things I wondered about: what is the point of the
> attribute-override? I see the Modeler uses it for flattened attributes, so
> I do too, but the obj-attribute seems to already say the exact same thing
> so I don't see the point.

I am not sure. I generated the html docs and the XSD, but I didn't always understand some of the more obscure bits. Andrus will know.


> Your link is broken btw, it just shows the index and not the content. This
> is the correct URL:
>
> http://cayenne.apache.org/schema/3.0/modelMap.html

Yes, that's better.


It is also worth noting that Cayenne modeler isn't validating its output or input against the schema right now. We didn't want to enable that and break XML files which work, but which did not meet the schema exactly (for example, XSD is very particular about the order of attributes).


Ari



-- 
-------------------------->
Aristedes Maniatis
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A

Re: Some more concrete questions about Cayenne

Posted by Erlend Birkenes <eb...@dataloy.com>.
2012/1/20 Aristedes Maniatis <ar...@maniatis.org>

> Not perfect, but this helps...
>
> http://cayenne.apache.org/**schema/3.0/indexList.html<http://cayenne.apache.org/schema/3.0/indexList.html>
>
> Happy to accept any help with getting better docs into the schema XSD.
>
>
Thanks, I knew about that and it was very useful. It's not always obvious
what the various tags are for, so it could use more descriptions. I
generally had to do things in the Modeler and look at the resulting XML to
figure out how to do things correctly. I have checked out the source, so
I'll see if I can write some docs when I have some time.

One of the things I wondered about: what is the point of the
attribute-override? I see the Modeler uses it for flattened attributes, so
I do too, but the obj-attribute seems to already say the exact same thing
so I don't see the point.

Your link is broken btw, it just shows the index and not the content. This
is the correct URL:

http://cayenne.apache.org/schema/3.0/modelMap.html


-Erlend

Re: Some more concrete questions about Cayenne

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 20/01/12 12:24 AM, Erlend Birkenes wrote:

> As I said, I really like the map.xml file format, which just lists the
> db-entities, obj-entities, db-relationships and obj-relationships. Very
> easy to generate and manipulate.
> It is very poorly documented, but easy enough to figure out based on the
> Schema and by experimenting in the Modeler and see what it produces.

Not perfect, but this helps...

http://cayenne.apache.org/schema/3.0/indexList.html

Happy to accept any help with getting better docs into the schema XSD.


Ari


-- 
-------------------------->
Aristedes Maniatis
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A

Re: Some more concrete questions about Cayenne

Posted by Erlend Birkenes <eb...@dataloy.com>.
2012/1/19 Durchholz, Joachim <Jo...@hennig-fahrzeugteile.de>

> > Writing a generator for this is very simple since everything
> > is in one file
>
> Oh. Is that one XML for all entities?
> Or am I misunderstanding something here?
> I'd really prefer to have one XML per table.
>

Yeah, it's one big file. In our case it's 1.4MB and 17k lines. So I'm not
hand-editing that! ;-)

If you generate it yourself i'm sure it's easy to keep each entity in it's
own file for easier editing and then just build the map.xml from those. The
fact that it is a almost flat xml file is good for this. Actually you could
probably use xml !ENTITY to do it directly, but I haven't tried.


-Erlend

RE: Some more concrete questions about Cayenne

Posted by "Durchholz, Joachim" <Jo...@hennig-fahrzeugteile.de>.
> Writing a generator for this is very simple since everything
> is in one file

Oh. Is that one XML for all entities?
Or am I misunderstanding something here?
I'd really prefer to have one XML per table.

> The reason we did this is because we maintain our own database
> metadata stored in the database and we wanted to use that.

We'll have to go down a similar route. We'll have to interact with an ERP system that declares all fields as NUMBER, and keeps metadata about actual valid ranges, precision and scale partly in tables, partly in text files.
It's going to be fun, of the non-fun type.

> (We also have almost 300 Entities, so modifying them manually
> in the Modeler was out of the question.)

Hmm... that's not a large number.
Seems like Modeler doesn't scale well enough for even medium-sized projects.

We're at just ~50 tables here, so Modeler might still work for us, but I guess we better look for something textfile-based. Either direct XML editing or some simple source from which we can generate the XML.

> So it was very simple for us to get all we needed from there.
> I guess it's relatively simple to get this from JDBC
> DatabaseMetadata and use that instead,

Depends. The metadata is defined as a query result, which a very handwavy explanation what to find in which column.
With the consequence that every RDBMS fills the columns with subtly different kinds of information.
Plus, at least one major vendor (Oracle) is known to return bogus data for many constellations. You need to know these constellations and infer them from the parameter data that you get.

More fun of the non-fun type ;-)

That said, there are reliable ways to get that kind of data, even from Oracle. You just don't want to use the DatabaseMetadata API in JDBC, but something vendor-specific. If you need to get something to work quickly (as opposed to getting it done once and for all), you can manage; the task becomes even easier if the tables have all been defined along the same set of conventions, so you don't hit each and every weird constellation of misreported metadata.

> or define it some other way.

This. It seems the ability to merge metadata from multiple sources is essential.
I find myself wanting to specify metadata beyond what the database can give me. Such as enums and their associations with the strings encoded in the database. Or what kind of formatting to use for a NUMBER - we want different formats depending on whether the number is an ID (no separators), a quantity (decimal and fractional separators), or a monetary amount (as quantity but also a currency symbol). We have DATE fields where 9999-12-31 was defined to be roughly equivalent to NULL, so the display rules for that field are different from ordinary DATE fields. And so on and so on.

> After doing that I'm glad we did, as it gives us MUCH
> more control over the whole thing. It's very simple
> to manipulate things, and lets us do things like add
> flattened attributes on all ObjEntities so they all
> implement a common interface,

Sweet :-)

> something that is very cumbersome in the Modeler. It's
> much easier to get stuff exactly how we want them when
> we can program them (after all we are programmers, not
> mouse clickers, right..?)

Hehe, right :-)

> As I said, I really like the map.xml file format, which
> just lists the db-entities, obj-entities, db-relationships
> and obj-relationships. Very easy to generate and manipulate.
> It is very poorly documented, but easy enough to figure out
> based on the Schema and by experimenting in the Modeler and
> see what it produces.

Good to know.
Thanks.

> When we have the map.xml we just use the cgen ant task to
> generate the classes.

Huh. Somehow I never made it to the page documenting the Ant tasks. Probably because I never properly realized their significance.
Thanks for pointing that out.

> So you don't have to use the modeler, but I wouldn't
> recommend hand-editing.

Okay, I'll keep that in mind.

Regards,
Jo

Re: Some more concrete questions about Cayenne

Posted by Erlend Birkenes <eb...@dataloy.com>.
2012/1/18 Durchholz, Joachim <Jo...@hennig-fahrzeugteile.de>

> 1) Does anybody have concrete advice about using Cayenne without Modeler?
>
> Background:
> I see Modeler is one of the major sources of "huh?" moments on the list.
> It's an additional layer of abstraction between what Cayenne does and what
> the developer sees, meaning it can introduce problems (and occasionally
> does); I'd want to get my feet wet with Cayenne without that complication.
> I also see it's the one part that you actually can avoid using - the XML
> can be edited by hand.
>
>
I'm pretty new at this, but here are our experiences with this so far:

The modeler is pretty nice to work with if you don't have that many and/or
large entities, or don't need much customization, but point and click gets
old pretty fast.

We have written a simple generator to generate the .map.xml file that the
Modeler  produces. It's just a simple Java class (<400 lines) that writes
strings to the file. Writing a generator for this is very simple since
everything is in one file and you can just add all the relationships at the
bottom, no need to go back and forth between entities and stuff like that.

The reason we did this is because we maintain our own database metadata
stored in the database and we wanted to use that. (We also have almost 300
Entities, so modifying them manually in the Modeler was out of the
question.) So it was very simple for us to get all we needed from there. I
guess it's relatively simple to get this from JDBC DatabaseMetadata and use
that instead, or define it some other way.

After doing that I'm glad we did, as it gives us MUCH more control over the
whole thing. It's very simple to manipulate things, and lets us do things
like add flattened attributes on all ObjEntities so they all implement a
common interface, something that is very cumbersome in the Modeler. It's
much easier to get stuff exactly how we want them when we can program them
(after all we are programmers, not mouse clickers, right..?)

As I said, I really like the map.xml file format, which just lists the
db-entities, obj-entities, db-relationships and obj-relationships. Very
easy to generate and manipulate.
It is very poorly documented, but easy enough to figure out based on the
Schema and by experimenting in the Modeler and see what it produces.

When we have the map.xml we just use the cgen ant task to generate the
classes.

So you don't have to use the modeler, but I wouldn't recommend hand-editing.


-Erlend