You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Kevin Meyer - KMZ <ke...@kmz.co.za> on 2011/12/06 07:59:35 UTC

Is it possible/easy to integrate cayenne with other frameworks?

Hi all,

Please point me to the previous message if this has already been 
addressed.. I did a quick search, but couldn't find anything that looked 
directly relevant.

Anyway: I have been maintaining the SQL Objectstore (jdbc) for 
Apache Isis (currently in the incubator), and would like to know if 
Cayenne can be used completely "in the background", with no user 
integration (i.e. no need to run the configuration tool / modeller / etc).

Isis is a complete framework solution for developing and deploying 
POJO / domain objects, and provides hooks for persistence tasks.
For example, the metamodel context provide:
	public ObjectInstantiator getObjectInstantiator();
	public ObjectDirtier getObjectDirtier();
	public ObjectPersistor getObjectPersistor();

where, for example:
public interface ObjectInstantiator extends Injectable {
   /**
     * Provided by the <tt>ObjectFactory</tt> when used by framework.
     * 
     * <p>
     * Called by {@link ObjectSpecificationDefault}.
     */
    Object instantiate(Class<?> cls) throws 
ObjectInstantiationException;
}

Isis requires no annotations, etc, to support persistence, which is 
taken care of via introspection. Some hints can be provided to the 
objectstore via the "isis.properties" file, if required.

So, I would like to know how difficult would it be to "just" hook Cayenne 
into the object "create", "find" and "update" methods of Isis, and let  
Cayenne take care of the ORM / persistence?

Taking a quick browse through the examples, I don't see where I 
configure the database connection, for example.

Regards,
Kevin



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Indeed - The Isis SQL objectstore itself works by making assumptions 
about jdbc type, etc. The defaults can be altered at runtime, but most 
work out-of-the-box against MySQL, PostgreSQL and HSQLDB.


On 8 Dec 2011 at 9:10, John Huss wrote:

> > I was hoping that I could merely require that Cayenne-managed
> > POJOs extend a Cayenne-compatible base class, and no more, and
> > that only getXXX/setXXX methods would be used to map XXX into the
> > ORM. In Isis, a getXXX-only implies a read-only property, and setYYY
> > only is for injecting services. Neither of which are passed to the Isis
> > ORM.
> >
> 
> You could probably reverse-engineer a model by introspecting specific
> classes, but you would have to make assumptions about the database mapping
> information (jdbc type, width, scale precision) unless that is available
> via annotations in your classes.



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by John Huss <jo...@gmail.com>.
On Wed, Dec 7, 2011 at 2:11 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:

> Dear John,
>
> Thanks for your response.
>
> On 6 Dec 2011 at 9:04, John Huss wrote:
>
> > You can use Cayenne without running the modeler, but it would be rather
> > cumbersome since you would have to create the whole model
> programmatically
> > at runtime each time.
>
> So Cayenne does not introspect the POJOs?
>
> I suppose I can work with having to run a config tool every now and
> then, as design changes need to be handled.
>
> > And normally you would generate custom classes for your Entities
> > (objects), but without having a pre-existing model you would just
> > have to use CayenneDataObject directly which will force you to
> > access values by name instead of via getters and setters. If those
> > requirements are acceptable, then it could work.
>
> Isis does not generate code - it uses the users POJOs as is, with extra
> methods or annotations to affect behaviour, visibility etc.
>
> I was hoping that I could merely require that Cayenne-managed
> POJOs extend a Cayenne-compatible base class, and no more, and
> that only getXXX/setXXX methods would be used to map XXX into the
> ORM. In Isis, a getXXX-only implies a read-only property, and setYYY
> only is for injecting services. Neither of which are passed to the Isis
> ORM.
>

You could probably reverse-engineer a model by introspecting specific
classes, but you would have to make assumptions about the database mapping
information (jdbc type, width, scale precision) unless that is available
via annotations in your classes.

>
> > The "update" method might be tricker.  Cayenne saves all changes to the
> > entire object graph at once; you can't just save one object, you save all
> > changes to the related objects that are loaded and modified.  If this is
> > different than the "update" concept in Isis then it may be a problem.
>
> No problem - Isis does something similar. If an object is transient, all
> properties are "walked" and persisted. But objects in the entire graph
> are not persisted if they have not changed.
>
> Regards,
> Kevin
>
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Dear John,

Thanks for your response.

On 6 Dec 2011 at 9:04, John Huss wrote:

> You can use Cayenne without running the modeler, but it would be rather
> cumbersome since you would have to create the whole model programmatically
> at runtime each time.  

So Cayenne does not introspect the POJOs?

I suppose I can work with having to run a config tool every now and 
then, as design changes need to be handled.

> And normally you would generate custom classes for your Entities
> (objects), but without having a pre-existing model you would just
> have to use CayenneDataObject directly which will force you to
> access values by name instead of via getters and setters. If those
> requirements are acceptable, then it could work. 

Isis does not generate code - it uses the users POJOs as is, with extra 
methods or annotations to affect behaviour, visibility etc.

I was hoping that I could merely require that Cayenne-managed 
POJOs extend a Cayenne-compatible base class, and no more, and 
that only getXXX/setXXX methods would be used to map XXX into the 
ORM. In Isis, a getXXX-only implies a read-only property, and setYYY 
only is for injecting services. Neither of which are passed to the Isis 
ORM.

> The "update" method might be tricker.  Cayenne saves all changes to the
> entire object graph at once; you can't just save one object, you save all
> changes to the related objects that are loaded and modified.  If this is
> different than the "update" concept in Isis then it may be a problem.

No problem - Isis does something similar. If an object is transient, all 
properties are "walked" and persisted. But objects in the entire graph 
are not persisted if they have not changed.

Regards,
Kevin


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by John Huss <jo...@gmail.com>.
For the DB connection, if you're using 3.0 there is some info here:
https://cwiki.apache.org/CAY/setting-database-connection.html

For 3.1, you can use a properties file to store the value and load them in
a custom DI module by doing something like:

public class PropertiesModule implements Module {
public void configure(Binder binder) {
MapBuilder<Object> mapBuilder =
binder.bindMap(DefaultRuntimeProperties.PROPERTIES_MAP);
Properties props = ... load properties from a file
for (Object keyObj : props.keySet()) {
String key = (String)keyObj;
                        mapBuilder.put(key, props.get(key));
                }
}
}

Where the properties are set like this:
cayenne.jdbc.driver.MyDomain.MyNode=org.postgresql.Driver
cayenne.jdbc.url.MyDomain.MyNode=jdbc:postgresql://localhost/mydb
cayenne.jdbc.username.MyDomain.MyNode=postgres
cayenne.jdbc.password.MyDomain.MyNode=*******
cayenne.min.connections.MyDomain.MyNode=1
cayenne.max.connections.MyDomain.MyNode=1

You can use Cayenne without running the modeler, but it would be rather
cumbersome since you would have to create the whole model programmatically
at runtime each time.  And normally you would generate custom classes for
your Entities (objects), but without having a pre-existing model you would
just have to use CayenneDataObject directly which will force you to access
values by name instead of via getters and setters.
If those requirements are acceptable, then it could work.

The "update" method might be tricker.  Cayenne saves all changes to the
entire object graph at once; you can't just save one object, you save all
changes to the related objects that are loaded and modified.  If this is
different than the "update" concept in Isis then it may be a problem.

John

On Tue, Dec 6, 2011 at 12:59 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:

> Hi all,
>
> Please point me to the previous message if this has already been
> addressed.. I did a quick search, but couldn't find anything that looked
> directly relevant.
>
> Anyway: I have been maintaining the SQL Objectstore (jdbc) for
> Apache Isis (currently in the incubator), and would like to know if
> Cayenne can be used completely "in the background", with no user
> integration (i.e. no need to run the configuration tool / modeller / etc).
>
> Isis is a complete framework solution for developing and deploying
> POJO / domain objects, and provides hooks for persistence tasks.
> For example, the metamodel context provide:
>        public ObjectInstantiator getObjectInstantiator();
>        public ObjectDirtier getObjectDirtier();
>        public ObjectPersistor getObjectPersistor();
>
> where, for example:
> public interface ObjectInstantiator extends Injectable {
>   /**
>     * Provided by the <tt>ObjectFactory</tt> when used by framework.
>     *
>     * <p>
>     * Called by {@link ObjectSpecificationDefault}.
>     */
>    Object instantiate(Class<?> cls) throws
> ObjectInstantiationException;
> }
>
> Isis requires no annotations, etc, to support persistence, which is
> taken care of via introspection. Some hints can be provided to the
> objectstore via the "isis.properties" file, if required.
>
> So, I would like to know how difficult would it be to "just" hook Cayenne
> into the object "create", "find" and "update" methods of Isis, and let
> Cayenne take care of the ORM / persistence?
>
> Taking a quick browse through the examples, I don't see where I
> configure the database connection, for example.
>
> Regards,
> Kevin
>
>
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Andrus Adamchik <an...@objectstyle.org>.
> At some point, I am supposing I'll want to know: How do I specify that 
> property X of class Y represents a value (e.g. int), and that property A 
> represents an instance of class Z.

Given a finite predefined set of "persistent" classes, it shouldn't be that hard to tell the 2 types of properties apart from each other. Does Isis know all the classes it will be working with upfront, or is it lazily introspecting them one at a time as they are accessed by the app?


> class Customer extends CayenneDataObject {
> 
> public int getNumber(){...}
> 
> public Address getAddress(){...}
> 
> }

BTW, take a note of how typical getters/setters are implemented in CayenneDataObject subclasses (an example from our unit tests). Hope that's ok in the Isis environment:

* Simple properties:

    public void setArtistName(String artistName) {
        writeProperty("artistName", artistName);
    }
    public String getArtistName() {
        return (String)readProperty("artistName");
    }

* To-one relationships:

    public void setToArtist(org.apache.cayenne.testdo.testmap.Artist toArtist) {
        setToOneTarget("toArtist", toArtist, true);
    }

    public org.apache.cayenne.testdo.testmap.Artist getToArtist() {
        return (org.apache.cayenne.testdo.testmap.Artist)readProperty("toArtist");
    } 

* To-many relationships 

    public void addToArtistExhibitArray(ArtistExhibit obj) {
        addToManyTarget("artistExhibitArray", obj, true);
    }
    public void removeFromArtistExhibitArray(ArtistExhibit obj) {
        removeToManyTarget("artistExhibitArray", obj, true);
    }
    @SuppressWarnings("unchecked")
    public List<ArtistExhibit> getArtistExhibitArray() {
        return (List<ArtistExhibit>)readProperty("artistExhibitArray");
    }

Andrus


On Dec 9, 2011, at 6:58 AM, Kevin Meyer - KMZ wrote:

> Hi Andrus,
> 
> Thanks for the details.
> 
> I had an initial read through of the cayenne-guide-08302011.pdf, but 
> I'm not sure what I'm looking for.
> 
> For the most part, I *do* assume that I have total control over the DB, 
> with no legacy support. Or at least, nothing beyond choosing property 
> names to suit matching database table column names and similar.
> 
> 
> I still don't have a good idea how Cayenne works - how it's started, etc.
> More reading required.
> 
> At some point, I am supposing I'll want to know: How do I specify that 
> property X of class Y represents a value (e.g. int), and that property A 
> represents an instance of class Z.
> 
> e.g. (where there's a get, assume there's a set)
> 
> class Customer extends CayenneDataObject {
> 
> public int getNumber(){...}
> 
> public Address getAddress(){...}
> 
> }
> 
> The Isis internals introspects Customer and creates various classes 
> that either represent the *definition* of Customer, or provide access to 
> an actual instance.
> 
> The object store uses this information to support creating tables and 
> mappers (either value mappers or reference mappers).
> 
> This is where I expect to I need to tell Cayenne what user domain 
> objects exist (and need to be persisted), what value properties they 
> have, and what reference properties (pointing to other user domain 
> objects). 
> 
> The subtleties may come into handling polymorphism, etc., but I've 
> gone through this exercise with Isis.
> 
> 
> I've been given a heads-up on how to create a new runtime context for 
> Isis that will use Cayenne - when I get to the point that I need to persist 
> an object, that's when I need to know more about setting up Cayenne 
> programmatically.
> 
> Regards,
> Kevin
> 
> 
> On 8 Dec 2011 at 16:18, Andrus Adamchik wrote:
> 
>> Hi Kevin,
>> 
>> I should say that Cayenne is uniquely suited for creating persistent
>> stack and mapping at runtime, as there's no class enhancement
>> involved. POJO's being subclasses of CayenneDataObject, with set/get
>> implemented the way we do them in Cayenne is the only hard
>> requirement. From there, as John has mentioned, you make some
>> assumptions. The biggest assumption is that you control the DB and
>> there's no chance of a legacy schema that you'd have to support...
>> 
>> Implementation (assuming Cayenne 3.1) may be encapsulated in a
>> custom Cayenne DI module. We are still in the process of writing the
>> docs for 3.1, but most DI features are well documented in this
>> otherwise empty PDF: 
>> 
>> http://people.apache.org/~aadamchik/misc/cayenne-guide-08302011.pdf
>> 
>> In the custom module define DataDomain loading services to
>> reverse-engineer the POJOs instead of loading mapping from XML. This
>> is the biggest task, requiring some understanding of Cayenne APIs.
>> Feel free to ask here if you get stuck with anything. Also map
>> SchemaUpdateStrategy to CreateIfNoSchemaStrategy that will create a
>> DB schema based on your mapping. 
>> 
>> This should be it at the high level, but of course you'll need to
>> write some code here. I used to implement a similar task - going
>> from reverse-engineered DB to a runtime mapping of generic Java
>> classes, and that worked pretty well. 
>> 
>> Good luck, and let us know how this works - maybe some of these new
>> factories that you develop could be of general use to Cayenne users
>> as well as ISIS users. 
>> 
>> Andrus 
> 
> 


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Hi Andrus,

Thanks for the details.

I had an initial read through of the cayenne-guide-08302011.pdf, but 
I'm not sure what I'm looking for.

For the most part, I *do* assume that I have total control over the DB, 
with no legacy support. Or at least, nothing beyond choosing property 
names to suit matching database table column names and similar.


I still don't have a good idea how Cayenne works - how it's started, etc.
More reading required.

At some point, I am supposing I'll want to know: How do I specify that 
property X of class Y represents a value (e.g. int), and that property A 
represents an instance of class Z.

e.g. (where there's a get, assume there's a set)

class Customer extends CayenneDataObject {

 public int getNumber(){...}

 public Address getAddress(){...}
 
}

The Isis internals introspects Customer and creates various classes 
that either represent the *definition* of Customer, or provide access to 
an actual instance.

The object store uses this information to support creating tables and 
mappers (either value mappers or reference mappers).

This is where I expect to I need to tell Cayenne what user domain 
objects exist (and need to be persisted), what value properties they 
have, and what reference properties (pointing to other user domain 
objects). 

The subtleties may come into handling polymorphism, etc., but I've 
gone through this exercise with Isis.


I've been given a heads-up on how to create a new runtime context for 
Isis that will use Cayenne - when I get to the point that I need to persist 
an object, that's when I need to know more about setting up Cayenne 
programmatically.

Regards,
Kevin


On 8 Dec 2011 at 16:18, Andrus Adamchik wrote:

> Hi Kevin,
> 
> I should say that Cayenne is uniquely suited for creating persistent
> stack and mapping at runtime, as there's no class enhancement
> involved. POJO's being subclasses of CayenneDataObject, with set/get
> implemented the way we do them in Cayenne is the only hard
> requirement. From there, as John has mentioned, you make some
> assumptions. The biggest assumption is that you control the DB and
> there's no chance of a legacy schema that you'd have to support...
> 
> Implementation (assuming Cayenne 3.1) may be encapsulated in a
> custom Cayenne DI module. We are still in the process of writing the
> docs for 3.1, but most DI features are well documented in this
> otherwise empty PDF: 
> 
> http://people.apache.org/~aadamchik/misc/cayenne-guide-08302011.pdf
> 
> In the custom module define DataDomain loading services to
> reverse-engineer the POJOs instead of loading mapping from XML. This
> is the biggest task, requiring some understanding of Cayenne APIs.
> Feel free to ask here if you get stuck with anything. Also map
> SchemaUpdateStrategy to CreateIfNoSchemaStrategy that will create a
> DB schema based on your mapping. 
> 
> This should be it at the high level, but of course you'll need to
> write some code here. I used to implement a similar task - going
> from reverse-engineered DB to a runtime mapping of generic Java
> classes, and that worked pretty well. 
> 
> Good luck, and let us know how this works - maybe some of these new
> factories that you develop could be of general use to Cayenne users
> as well as ISIS users. 
> 
> Andrus 


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
What am I missing: In
	DataDomainInsertBucket#createPermIds
the returned node is null in:

        DataNode node = parent.getDomain().lookupDataNode(entity.getDataMap());

Clearly I'm not doing something in my set-up.


On 11 Dec 2011 at 21:05, Andrus Adamchik wrote:

> Great to hear there a workaround. Object structure is a pretty
> fundamental issue, so I was afraid we may get stuck here. 
> 
> Cheers,
> Andrus 
> 


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Enough for tonight.

Thanks to everyone for the help thus far.

When I get back to this project, I'll be looking into starting/ending 
transactions and getting IDs before the object is persisted.

Regards,
Kevin

> Hah! Success!
> 
> It seemed that I did not have a primary key field defined. I define that, 
> and I have just had a successful commit.
> 
> *) newObject
> *) assign
> *) commit
> 
> works.
> 
> Does Cayenne provide a SQL Data type helper? Something that helps 
> Cayenne guess SQL data types for given value types? Or must I 
> implement my own?
> 



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Dec 12, 2011, at 8:37 AM, Kevin Meyer - KMZ wrote:

> Hah! Success!
> 
> It seemed that I did not have a primary key field defined. I define that, 
> and I have just had a successful commit.
> 
> *) newObject
> *) assign
> *) commit
> 
> works.

Congrats! :)

> 
> Does Cayenne provide a SQL Data type helper? Something that helps 
> Cayenne guess SQL data types for given value types? Or must I 
> implement my own?

This class has some static methods that should help you:

http://cayenne.apache.org/doc/api/org/apache/cayenne/dba/TypesMapping.html

Andrus

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Hah! Success!

It seemed that I did not have a primary key field defined. I define that, 
and I have just had a successful commit.

*) newObject
*) assign
*) commit

works.

Does Cayenne provide a SQL Data type helper? Something that helps 
Cayenne guess SQL data types for given value types? Or must I 
implement my own?

Regards,
Kevin


On 12 Dec 2011 at 20:21, Kevin Meyer - KMZ wrote:

> Ah! Next problem.
> 
> Having found the datanode with:
>         DataDomain dataDomain = runtime.getInjector().getInstance(DataDomain.class);
>         DataNode dataNode = dataDomain.getNode("datanode");
> ...
>         dataNode.addDataMap(dataMap);
> 
> 
> I now get the following in the log:
> 20:15:15,961  [CommonsJdbcEventLogger main       INFO ]  +++ Connecting: SUCCESS.
> 20:15:16,071  [CommonsJdbcEventLogger main       INFO ]  Detected and installed adapter: org.apache.cayenne.dba.hsqldb.HSQLDBAdapter
> 20:15:16,075  [CommonsJdbcEventLogger main       INFO ]  --- transaction started.
> 20:15:16,123  [CreateIfNoSchemaStrategy main       INFO ]  No schema detected, will create mapped tables
> 20:15:16,130  [CommonsJdbcEventLogger main       INFO ]  CREATE CACHED TABLE SimpleClassA (number INTEGER NULL, persistent INTEGER NULL)
> 20:15:16,253  [CommonsJdbcEventLogger main       INFO ]  CREATE TABLE AUTO_PK_SUPPORT (  TABLE_NAME CHAR(100) NOT NULL,  NEXT_ID BIGINT NOT NULL,  PRIMARY KEY(TABLE_NAME))
> 20:15:16,254  [CommonsJdbcEventLogger main       INFO ]  DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ()
> 20:15:16,258  [CommonsJdbcEventLogger main       INFO ]  *** error.
> java.sql.SQLException: Unexpected token: ) in statement [DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ()]
> 	at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
> 	at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
> 	at org.hsqldb.jdbc.jdbcStatement.execute(Unknown Source)
> 	at org.apache.cayenne.access.DbGenerator.safeExecute(DbGenerator.java:377)
> 	at org.apache.cayenne.access.DbGenerator.runGenerator(DbGenerator.java:355)
> 	at org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy.generate(CreateIfNoSchemaStrategy.java:79)
> ....
> ....
> 20:15:16,287  [CommonsJdbcEventLogger main       INFO ]  INSERT INTO SimpleClassA (number, persistent) VALUES (?, ?)
> 20:15:16,290  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
> 20:15:16,292  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.
> 20:17:32,778  [CommonsJdbcEventLogger main       INFO ]  --- transaction started.
> 20:17:32,779  [CommonsJdbcEventLogger main       INFO ]  INSERT INTO SimpleClassA (number, persistent) VALUES (?, ?)
> 20:17:32,779  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
> 20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.
> 20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
> 20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.
> 
> 
> Followed by "Temporary ID hasn't been replaced on commit: "
> 
> Any hints?
> 
> 
> 
> On 12 Dec 2011 at 12:02, Mike Kienenberger wrote:
> 
> > How are you creating a DataNode and what are you doing to assign DataMaps to it?
> > 
> > On Mon, Dec 12, 2011 at 11:52 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> > > Ok, thanks, I call
> > >            objAttribute.setDbAttributePath(id);
> > > and I am now back to my previous problem, where
> > >        DataNode node =
> > > parent.getDomain().lookupDataNode(entity.getDataMap());
> > > has node == null in DataDomainInsertBucket#createPermIds.
> > >
> > > Any hints?
> > >
> > > On 12 Dec 2011 at 11:13, Mike Kienenberger wrote:
> > >
> > >> You may not need the prefix, but you at least need this much:
> > >>
> > >>           //  dot-separated path that starts in the root DbEntity
> > >> that maps to this attribute's ObjEntity and spans zero or more
> > >> relationships, always ending in a DbAttribute name.
> > >>           objAttribute.setDbAttributePath(id);
> > >>
> > >> On Mon, Dec 12, 2011 at 11:10 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> > >> > Sorry, you guys are confusing me.
> > >> >
> > >> > I have a datamap (called "isis_map"), to which I have added a DbEntity
> > >> > (named after my class, "simpleclass") and a ObjEntity (with same
> > >> > name).
> > >> >
> > >> > The "id" I refer to is the name of a property of my class (called
> > >> > "number"). The class has methods setNumber and getNumber.
> > >> >
> > >> > That's the id ("number") that I assigned to DbAttribute and
> > >> > ObjAttribute.
> > >> >
> > >> > What is the prefix you refer to?
> > >> >
> > >> > regards,
> > >> > Kevin
> > >> >
> > >> > On 12 Dec 2011 at 9:20, John Huss wrote:
> > >> >
> > >> >> Yes, you need to link the Obj* things to the Db* things by name, both the
> > >> >> entities and the attributes.
> > >> >>
> > >> >> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
> > >> >>
> > >> >> > I can't remember the exact details, but you might need (prefix + "." +
> > >> >> > id) instead of (id)
> > >> >> >
> > >> >> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
> > >> >> > wrote:
> > >> >> > >            DbAttribute dbAttribute = new DbAttribute(id,
> > >> >> > java.sql.Types.INTEGER, dbEntity);
> > >> >> > >            dbEntity.addAttribute(dbAttribute);
> > >> >> >
> > >> >> > +             //  dot-separated path that starts in the root DbEntity
> > >> >> > that maps to this attribute's ObjEntity and spans zero or more
> > >> >> > relationships, always ending in a DbAttribute name.
> > >> >> > +             objAttribute.setDbAttributePath(id);
> > >> >> >
> > >> >> > >
> > >> >> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
> > >> >> > objEntity);
> > >> >> >
> > >> >>
> > >> >
> > >> >
> > >> > --
> > >> > Kevin Meyer, PhD, Pr.Sci.Nat
> > >> > KMZ             P.O. Box 9822, Sharon Park, South Africa.
> > >> > Tel: +27 11 363 2001   Cell: +27 83 346 3045
> > >> >
> > >> >
> > >
> > >
> > > --
> > > Kevin Meyer, PhD, Pr.Sci.Nat
> > > KMZ             P.O. Box 9822, Sharon Park, South Africa.
> > > Tel: +27 11 363 2001   Cell: +27 83 346 3045
> > >
> > >
> 
> 
> --
> Kevin Meyer, PhD, Pr.Sci.Nat
> KMZ		P.O. Box 9822, Sharon Park, South Africa.
> Tel: +27 11 363 2001	Cell: +27 83 346 3045
> 
> 


--
Kevin Meyer, PhD, Pr.Sci.Nat
KMZ		P.O. Box 9822, Sharon Park, South Africa.
Tel: +27 11 363 2001	Cell: +27 83 346 3045



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Ah! Next problem.

Having found the datanode with:
        DataDomain dataDomain = runtime.getInjector().getInstance(DataDomain.class);
        DataNode dataNode = dataDomain.getNode("datanode");
...
        dataNode.addDataMap(dataMap);


I now get the following in the log:
20:15:15,961  [CommonsJdbcEventLogger main       INFO ]  +++ Connecting: SUCCESS.
20:15:16,071  [CommonsJdbcEventLogger main       INFO ]  Detected and installed adapter: org.apache.cayenne.dba.hsqldb.HSQLDBAdapter
20:15:16,075  [CommonsJdbcEventLogger main       INFO ]  --- transaction started.
20:15:16,123  [CreateIfNoSchemaStrategy main       INFO ]  No schema detected, will create mapped tables
20:15:16,130  [CommonsJdbcEventLogger main       INFO ]  CREATE CACHED TABLE SimpleClassA (number INTEGER NULL, persistent INTEGER NULL)
20:15:16,253  [CommonsJdbcEventLogger main       INFO ]  CREATE TABLE AUTO_PK_SUPPORT (  TABLE_NAME CHAR(100) NOT NULL,  NEXT_ID BIGINT NOT NULL,  PRIMARY KEY(TABLE_NAME))
20:15:16,254  [CommonsJdbcEventLogger main       INFO ]  DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ()
20:15:16,258  [CommonsJdbcEventLogger main       INFO ]  *** error.
java.sql.SQLException: Unexpected token: ) in statement [DELETE FROM AUTO_PK_SUPPORT WHERE TABLE_NAME IN ()]
	at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
	at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
	at org.hsqldb.jdbc.jdbcStatement.execute(Unknown Source)
	at org.apache.cayenne.access.DbGenerator.safeExecute(DbGenerator.java:377)
	at org.apache.cayenne.access.DbGenerator.runGenerator(DbGenerator.java:355)
	at org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy.generate(CreateIfNoSchemaStrategy.java:79)
....
....
20:15:16,287  [CommonsJdbcEventLogger main       INFO ]  INSERT INTO SimpleClassA (number, persistent) VALUES (?, ?)
20:15:16,290  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
20:15:16,292  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.
20:17:32,778  [CommonsJdbcEventLogger main       INFO ]  --- transaction started.
20:17:32,779  [CommonsJdbcEventLogger main       INFO ]  INSERT INTO SimpleClassA (number, persistent) VALUES (?, ?)
20:17:32,779  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.
20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  [bind: 1->number:NULL, 2->persistent:NULL]
20:17:32,780  [CommonsJdbcEventLogger main       INFO ]  === updated 1 row.


Followed by "Temporary ID hasn't been replaced on commit: "

Any hints?



On 12 Dec 2011 at 12:02, Mike Kienenberger wrote:

> How are you creating a DataNode and what are you doing to assign DataMaps to it?
> 
> On Mon, Dec 12, 2011 at 11:52 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> > Ok, thanks, I call
> >            objAttribute.setDbAttributePath(id);
> > and I am now back to my previous problem, where
> >        DataNode node =
> > parent.getDomain().lookupDataNode(entity.getDataMap());
> > has node == null in DataDomainInsertBucket#createPermIds.
> >
> > Any hints?
> >
> > On 12 Dec 2011 at 11:13, Mike Kienenberger wrote:
> >
> >> You may not need the prefix, but you at least need this much:
> >>
> >>           //  dot-separated path that starts in the root DbEntity
> >> that maps to this attribute's ObjEntity and spans zero or more
> >> relationships, always ending in a DbAttribute name.
> >>           objAttribute.setDbAttributePath(id);
> >>
> >> On Mon, Dec 12, 2011 at 11:10 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> >> > Sorry, you guys are confusing me.
> >> >
> >> > I have a datamap (called "isis_map"), to which I have added a DbEntity
> >> > (named after my class, "simpleclass") and a ObjEntity (with same
> >> > name).
> >> >
> >> > The "id" I refer to is the name of a property of my class (called
> >> > "number"). The class has methods setNumber and getNumber.
> >> >
> >> > That's the id ("number") that I assigned to DbAttribute and
> >> > ObjAttribute.
> >> >
> >> > What is the prefix you refer to?
> >> >
> >> > regards,
> >> > Kevin
> >> >
> >> > On 12 Dec 2011 at 9:20, John Huss wrote:
> >> >
> >> >> Yes, you need to link the Obj* things to the Db* things by name, both the
> >> >> entities and the attributes.
> >> >>
> >> >> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
> >> >>
> >> >> > I can't remember the exact details, but you might need (prefix + "." +
> >> >> > id) instead of (id)
> >> >> >
> >> >> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
> >> >> > wrote:
> >> >> > >            DbAttribute dbAttribute = new DbAttribute(id,
> >> >> > java.sql.Types.INTEGER, dbEntity);
> >> >> > >            dbEntity.addAttribute(dbAttribute);
> >> >> >
> >> >> > +             //  dot-separated path that starts in the root DbEntity
> >> >> > that maps to this attribute's ObjEntity and spans zero or more
> >> >> > relationships, always ending in a DbAttribute name.
> >> >> > +             objAttribute.setDbAttributePath(id);
> >> >> >
> >> >> > >
> >> >> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
> >> >> > objEntity);
> >> >> >
> >> >>
> >> >
> >> >
> >> > --
> >> > Kevin Meyer, PhD, Pr.Sci.Nat
> >> > KMZ             P.O. Box 9822, Sharon Park, South Africa.
> >> > Tel: +27 11 363 2001   Cell: +27 83 346 3045
> >> >
> >> >
> >
> >
> > --
> > Kevin Meyer, PhD, Pr.Sci.Nat
> > KMZ             P.O. Box 9822, Sharon Park, South Africa.
> > Tel: +27 11 363 2001   Cell: +27 83 346 3045
> >
> >


--
Kevin Meyer, PhD, Pr.Sci.Nat
KMZ		P.O. Box 9822, Sharon Park, South Africa.
Tel: +27 11 363 2001	Cell: +27 83 346 3045



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
I don't believe that I am creating a DataNode...where does this fit in?

My initialisation currently looks like:
        IsisPropertiesModule pm = new IsisPropertiesModule();
        runtime = new ServerRuntime("cayenne-project.xml", pm);
        context = runtime.getContext();

        dataContext = (DataContext) context;

        final EntityResolver entityResolver = dataContext.getEntityResolver();
        dataMap = entityResolver.getDataMap("isis_map");
        if (dataMap == null) {
            dataMap = new DataMap("isis_map");
            entityResolver.addDataMap(dataMap);
        }

where IsisPropertiesModule was an attempt to add a property fetcher 
from the properties file:

    public void configure(Binder binder) {
        MapBuilder<Object> mapBuilder = binder.bindMap(DefaultRuntimeProperties.PROPERTIES_MAP);
        Properties props = new Properties();

        props.put("cayenne.jdbc.driver", "org.hsqldb.jdbcDriver");
        props.put("cayenne.jdbc.connection", "jdbc:hsqldb:file:hsql-db/tests");
        props.put("cayenne.jdbc.user", "sa");
        props.put("cayenne.jdbc.password", "");

        for (Object keyObj : props.keySet()) {
            String key = (String) keyObj;
            mapBuilder.put(key, props.get(key));
        }
    }

but it doesn't have any effect.

My "empty" cayenne-project.xml contains:
<?xml version="1.0" encoding="utf-8"?>
<domain project-version="6">
	<map name="datamap"/>
	<node name="datanode"
		 factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
		 schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy"
		>
		<!-- <map-ref name="datamap"/> --> 
		<data-source>
			<driver value="org.hsqldb.jdbcDriver"/>
			<url value="jdbc:hsqldb:file:hsql-db/tests"/>
			<connectionPool min="1" max="10"/>
			<login userName="sa"/>
		</data-source>
	</node>
</domain>
 
I would like to not have to have this xml file, and reproduce everything 
programmatically.

Regards,
Kevin


On 12 Dec 2011 at 12:02, Mike Kienenberger wrote:

> How are you creating a DataNode and what are you doing to assign DataMaps to it?
> 
> On Mon, Dec 12, 2011 at 11:52 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> > Ok, thanks, I call
> >            objAttribute.setDbAttributePath(id);
> > and I am now back to my previous problem, where
> >        DataNode node =
> > parent.getDomain().lookupDataNode(entity.getDataMap());
> > has node == null in DataDomainInsertBucket#createPermIds.
> >
> > Any hints?
> >


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Mike Kienenberger <mk...@gmail.com>.
How are you creating a DataNode and what are you doing to assign DataMaps to it?

On Mon, Dec 12, 2011 at 11:52 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> Ok, thanks, I call
>            objAttribute.setDbAttributePath(id);
> and I am now back to my previous problem, where
>        DataNode node =
> parent.getDomain().lookupDataNode(entity.getDataMap());
> has node == null in DataDomainInsertBucket#createPermIds.
>
> Any hints?
>
> On 12 Dec 2011 at 11:13, Mike Kienenberger wrote:
>
>> You may not need the prefix, but you at least need this much:
>>
>>           //  dot-separated path that starts in the root DbEntity
>> that maps to this attribute's ObjEntity and spans zero or more
>> relationships, always ending in a DbAttribute name.
>>           objAttribute.setDbAttributePath(id);
>>
>> On Mon, Dec 12, 2011 at 11:10 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
>> > Sorry, you guys are confusing me.
>> >
>> > I have a datamap (called "isis_map"), to which I have added a DbEntity
>> > (named after my class, "simpleclass") and a ObjEntity (with same
>> > name).
>> >
>> > The "id" I refer to is the name of a property of my class (called
>> > "number"). The class has methods setNumber and getNumber.
>> >
>> > That's the id ("number") that I assigned to DbAttribute and
>> > ObjAttribute.
>> >
>> > What is the prefix you refer to?
>> >
>> > regards,
>> > Kevin
>> >
>> > On 12 Dec 2011 at 9:20, John Huss wrote:
>> >
>> >> Yes, you need to link the Obj* things to the Db* things by name, both the
>> >> entities and the attributes.
>> >>
>> >> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
>> >>
>> >> > I can't remember the exact details, but you might need (prefix + "." +
>> >> > id) instead of (id)
>> >> >
>> >> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
>> >> > wrote:
>> >> > >            DbAttribute dbAttribute = new DbAttribute(id,
>> >> > java.sql.Types.INTEGER, dbEntity);
>> >> > >            dbEntity.addAttribute(dbAttribute);
>> >> >
>> >> > +             //  dot-separated path that starts in the root DbEntity
>> >> > that maps to this attribute's ObjEntity and spans zero or more
>> >> > relationships, always ending in a DbAttribute name.
>> >> > +             objAttribute.setDbAttributePath(id);
>> >> >
>> >> > >
>> >> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
>> >> > objEntity);
>> >> >
>> >>
>> >
>> >
>> > --
>> > Kevin Meyer, PhD, Pr.Sci.Nat
>> > KMZ             P.O. Box 9822, Sharon Park, South Africa.
>> > Tel: +27 11 363 2001   Cell: +27 83 346 3045
>> >
>> >
>
>
> --
> Kevin Meyer, PhD, Pr.Sci.Nat
> KMZ             P.O. Box 9822, Sharon Park, South Africa.
> Tel: +27 11 363 2001   Cell: +27 83 346 3045
>
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Ok, thanks, I call 
            objAttribute.setDbAttributePath(id);
and I am now back to my previous problem, where
        DataNode node = 
parent.getDomain().lookupDataNode(entity.getDataMap());
has node == null in DataDomainInsertBucket#createPermIds.

Any hints?

On 12 Dec 2011 at 11:13, Mike Kienenberger wrote:

> You may not need the prefix, but you at least need this much:
> 
>           //  dot-separated path that starts in the root DbEntity
> that maps to this attribute's ObjEntity and spans zero or more
> relationships, always ending in a DbAttribute name.
>           objAttribute.setDbAttributePath(id);
> 
> On Mon, Dec 12, 2011 at 11:10 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> > Sorry, you guys are confusing me.
> >
> > I have a datamap (called "isis_map"), to which I have added a DbEntity
> > (named after my class, "simpleclass") and a ObjEntity (with same
> > name).
> >
> > The "id" I refer to is the name of a property of my class (called
> > "number"). The class has methods setNumber and getNumber.
> >
> > That's the id ("number") that I assigned to DbAttribute and
> > ObjAttribute.
> >
> > What is the prefix you refer to?
> >
> > regards,
> > Kevin
> >
> > On 12 Dec 2011 at 9:20, John Huss wrote:
> >
> >> Yes, you need to link the Obj* things to the Db* things by name, both the
> >> entities and the attributes.
> >>
> >> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
> >>
> >> > I can't remember the exact details, but you might need (prefix + "." +
> >> > id) instead of (id)
> >> >
> >> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
> >> > wrote:
> >> > >            DbAttribute dbAttribute = new DbAttribute(id,
> >> > java.sql.Types.INTEGER, dbEntity);
> >> > >            dbEntity.addAttribute(dbAttribute);
> >> >
> >> > +             //  dot-separated path that starts in the root DbEntity
> >> > that maps to this attribute's ObjEntity and spans zero or more
> >> > relationships, always ending in a DbAttribute name.
> >> > +             objAttribute.setDbAttributePath(id);
> >> >
> >> > >
> >> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
> >> > objEntity);
> >> >
> >>
> >
> >
> > --
> > Kevin Meyer, PhD, Pr.Sci.Nat
> > KMZ             P.O. Box 9822, Sharon Park, South Africa.
> > Tel: +27 11 363 2001   Cell: +27 83 346 3045
> >
> >


--
Kevin Meyer, PhD, Pr.Sci.Nat
KMZ		P.O. Box 9822, Sharon Park, South Africa.
Tel: +27 11 363 2001	Cell: +27 83 346 3045



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Mike Kienenberger <mk...@gmail.com>.
You may not need the prefix, but you at least need this much:

          //  dot-separated path that starts in the root DbEntity
that maps to this attribute's ObjEntity and spans zero or more
relationships, always ending in a DbAttribute name.
          objAttribute.setDbAttributePath(id);

On Mon, Dec 12, 2011 at 11:10 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> Sorry, you guys are confusing me.
>
> I have a datamap (called "isis_map"), to which I have added a DbEntity
> (named after my class, "simpleclass") and a ObjEntity (with same
> name).
>
> The "id" I refer to is the name of a property of my class (called
> "number"). The class has methods setNumber and getNumber.
>
> That's the id ("number") that I assigned to DbAttribute and
> ObjAttribute.
>
> What is the prefix you refer to?
>
> regards,
> Kevin
>
> On 12 Dec 2011 at 9:20, John Huss wrote:
>
>> Yes, you need to link the Obj* things to the Db* things by name, both the
>> entities and the attributes.
>>
>> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
>>
>> > I can't remember the exact details, but you might need (prefix + "." +
>> > id) instead of (id)
>> >
>> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
>> > wrote:
>> > >            DbAttribute dbAttribute = new DbAttribute(id,
>> > java.sql.Types.INTEGER, dbEntity);
>> > >            dbEntity.addAttribute(dbAttribute);
>> >
>> > +             //  dot-separated path that starts in the root DbEntity
>> > that maps to this attribute's ObjEntity and spans zero or more
>> > relationships, always ending in a DbAttribute name.
>> > +             objAttribute.setDbAttributePath(id);
>> >
>> > >
>> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
>> > objEntity);
>> >
>>
>
>
> --
> Kevin Meyer, PhD, Pr.Sci.Nat
> KMZ             P.O. Box 9822, Sharon Park, South Africa.
> Tel: +27 11 363 2001   Cell: +27 83 346 3045
>
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Sorry, you guys are confusing me.

I have a datamap (called "isis_map"), to which I have added a DbEntity 
(named after my class, "simpleclass") and a ObjEntity (with same 
name). 

The "id" I refer to is the name of a property of my class (called 
"number"). The class has methods setNumber and getNumber.

That's the id ("number") that I assigned to DbAttribute and 
ObjAttribute.

What is the prefix you refer to?

regards,
Kevin

On 12 Dec 2011 at 9:20, John Huss wrote:

> Yes, you need to link the Obj* things to the Db* things by name, both the
> entities and the attributes.
> 
> On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:
> 
> > I can't remember the exact details, but you might need (prefix + "." +
> > id) instead of (id)
> >
> > On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
> > wrote:
> > >            DbAttribute dbAttribute = new DbAttribute(id,
> > java.sql.Types.INTEGER, dbEntity);
> > >            dbEntity.addAttribute(dbAttribute);
> >
> > +             //  dot-separated path that starts in the root DbEntity
> > that maps to this attribute's ObjEntity and spans zero or more
> > relationships, always ending in a DbAttribute name.
> > +             objAttribute.setDbAttributePath(id);
> >
> > >
> > >            ObjAttribute objAttribute = new ObjAttribute(id, type,
> > objEntity);
> >
> 


--
Kevin Meyer, PhD, Pr.Sci.Nat
KMZ		P.O. Box 9822, Sharon Park, South Africa.
Tel: +27 11 363 2001	Cell: +27 83 346 3045



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by John Huss <jo...@gmail.com>.
Yes, you need to link the Obj* things to the Db* things by name, both the
entities and the attributes.

On Mon, Dec 12, 2011 at 9:03 AM, Mike Kienenberger <mk...@gmail.com>wrote:

> I can't remember the exact details, but you might need (prefix + "." +
> id) instead of (id)
>
> On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za>
> wrote:
> >            DbAttribute dbAttribute = new DbAttribute(id,
> java.sql.Types.INTEGER, dbEntity);
> >            dbEntity.addAttribute(dbAttribute);
>
> +             //  dot-separated path that starts in the root DbEntity
> that maps to this attribute's ObjEntity and spans zero or more
> relationships, always ending in a DbAttribute name.
> +             objAttribute.setDbAttributePath(id);
>
> >
> >            ObjAttribute objAttribute = new ObjAttribute(id, type,
> objEntity);
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Mike Kienenberger <mk...@gmail.com>.
I can't remember the exact details, but you might need (prefix + "." +
id) instead of (id)

On Mon, Dec 12, 2011 at 2:50 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
>            DbAttribute dbAttribute = new DbAttribute(id, java.sql.Types.INTEGER, dbEntity);
>            dbEntity.addAttribute(dbAttribute);

+             //  dot-separated path that starts in the root DbEntity
that maps to this attribute's ObjEntity and spans zero or more
relationships, always ending in a DbAttribute name.
+	      objAttribute.setDbAttributePath(id);

>
>            ObjAttribute objAttribute = new ObjAttribute(id, type, objEntity);

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Hmm.. curiouser and curiouser:
I'm reorganising the entity setup, and now I get:

org.apache.cayenne.CayenneRuntimeException: [v.3.1M4-SNAPSHOT Dec 11 2011 10:30:28] ObjAttribute 'number' does not have a corresponding DbAttribute

My setup, below, links the two:
id, in this case, is the magic "number" - the name of my POJO value 
field, of type int.

        // represents a database table
        DbEntity dbEntity = new DbEntity(entityName);

        // Represents a domain object
        ObjEntity objEntity = new ObjEntity(entityName);

        dataMap.addDbEntity(dbEntity);
        dataMap.addObjEntity(objEntity);
        // Link the table to the domain object
        objEntity.setDbEntity(dbEntity);
        objEntity.setClassName(className);

        // Create fields
        List<OneToOneAssociation> assocs = specification.getProperties();
        for (OneToOneAssociation assoc : assocs) {
            final String id = assoc.getId(); // number
            final String type = assoc.getSpecification().getFullIdentifier(); // int

            DbAttribute dbAttribute = new DbAttribute(id, java.sql.Types.INTEGER, dbEntity);
            dbEntity.addAttribute(dbAttribute);

            ObjAttribute objAttribute = new ObjAttribute(id, type, objEntity);
            objEntity.addAttribute(objAttribute);
        }

        dataMap.addObjEntity(objEntity);
        dataMap.addDbEntity(dbEntity);


On 11 Dec 2011 at 21:05, Andrus Adamchik wrote:

> Great to hear there a workaround. Object structure is a pretty fundamental issue, so I was afraid we may get stuck here.
> 
> Cheers,
> Andrus 
> 



Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Andrus Adamchik <an...@objectstyle.org>.
Great to hear there a workaround. Object structure is a pretty fundamental issue, so I was afraid we may get stuck here.

Cheers,
Andrus 

On Dec 11, 2011, at 8:49 PM, Kevin Meyer - KMZ wrote:

> On 11 Dec 2011 at 20:28, Andrus Adamchik wrote:
> 
>> 
>> On Dec 11, 2011, at 7:00 PM, Kevin Meyer - KMZ wrote:
>> 
>>> I wish it were this simple. But the problem lies in
>>> 	DataContext#newObject(String entityName)
>>> once it has created an instance of my POJO, it type casts it to 
>>> Persistent:
>>>           object = (Persistent) descriptor.createObject();
>>> 
>>> This *forces* my POJO to implement Persistent.
>> 
>> You may have to do the wrapping on your own after that I guess... If it is at all possible.
>> 
>> IIRC elsewhere in this thread you said you were OK with Isis objects
>> extending CayenneDataObject. CayenneDataObject implements Persistent
>> of course. So maybe there was some misunderstanding earlier in this
>> discussion? If your object really has to be a POJO (as in Java class
>> with no special superclass and data contained in the user-defined
>> fields), we need to backtrack quite a bit and reevaluate the
>> problem. 
> 
> I'm learning as I go along.
> 
> Initially, I did not realise there would be a problem with the Isis 
> introspector and CayenneDataObject.
> 
> Fortunately, Isis provides a mechanism to bypass introspecting certain 
> classes, so I am making my POJO extend CayenneDataObject and 
> am on to the next stage.
> 
> So - to recap: I have my POJO that Isis can introspect. I have 
> examined the fields and created:
> DbEntity, ObjEntity for each POJO.
> For each property, I have created:
> DbAttribute, ObjAttribute
> and set the appropriate setEntity() to the entities created above.
> 
> 
> 
> I can create an instance of my POJO with newInstance().
> 
> I'm now getting a null pointer assignment when I try and commit!
> 
> So far, I have tracked into:
>                createPermIds(descriptor, objects);
> in DataDomainInsertBucket#appendQueriesInternal
> 
>> 
>>> Why doesn't Cayenne support composition over inheritance? I think 
>>> the idea of containing the CayenneDataObject as suggested provides 
>>> much greater flexibility... and you generate these classes, anyway.
>> 
>> In the Isis integration case - maybe. I don't think we've ever
>> considered using a delegate to give persistent objects a semblance
>> of a POJO by removing a requirement for a superclass, but still
>> forcing our own internal structure. So it is probably worth a
>> discussion, although I am cautiously pessimistic about it being done
>> easily at Cayenne level. 
> 
> Indeed - I started putting together something in the DataContext that'll 
> fetch the container via a getPersistent or equivalent, and realised that 
> some additional wrappers will be needed to access the POJO again.
> 
> I'll put that on the back-burner for a while.
> 
> Regards,
> Kevin
> 
> 


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
On 11 Dec 2011 at 20:28, Andrus Adamchik wrote:

> 
> On Dec 11, 2011, at 7:00 PM, Kevin Meyer - KMZ wrote:
> 
> > I wish it were this simple. But the problem lies in
> > 	DataContext#newObject(String entityName)
> > once it has created an instance of my POJO, it type casts it to 
> > Persistent:
> >            object = (Persistent) descriptor.createObject();
> > 
> > This *forces* my POJO to implement Persistent.
> 
> You may have to do the wrapping on your own after that I guess... If it is at all possible.
> 
> IIRC elsewhere in this thread you said you were OK with Isis objects
> extending CayenneDataObject. CayenneDataObject implements Persistent
> of course. So maybe there was some misunderstanding earlier in this
> discussion? If your object really has to be a POJO (as in Java class
> with no special superclass and data contained in the user-defined
> fields), we need to backtrack quite a bit and reevaluate the
> problem. 

I'm learning as I go along.

Initially, I did not realise there would be a problem with the Isis 
introspector and CayenneDataObject.

Fortunately, Isis provides a mechanism to bypass introspecting certain 
classes, so I am making my POJO extend CayenneDataObject and 
am on to the next stage.

So - to recap: I have my POJO that Isis can introspect. I have 
examined the fields and created:
DbEntity, ObjEntity for each POJO.
For each property, I have created:
DbAttribute, ObjAttribute
and set the appropriate setEntity() to the entities created above.



I can create an instance of my POJO with newInstance().

I'm now getting a null pointer assignment when I try and commit!

So far, I have tracked into:
                createPermIds(descriptor, objects);
in DataDomainInsertBucket#appendQueriesInternal

> 
> > Why doesn't Cayenne support composition over inheritance? I think 
> > the idea of containing the CayenneDataObject as suggested provides 
> > much greater flexibility... and you generate these classes, anyway.
> 
> In the Isis integration case - maybe. I don't think we've ever
> considered using a delegate to give persistent objects a semblance
> of a POJO by removing a requirement for a superclass, but still
> forcing our own internal structure. So it is probably worth a
> discussion, although I am cautiously pessimistic about it being done
> easily at Cayenne level. 

Indeed - I started putting together something in the DataContext that'll 
fetch the container via a getPersistent or equivalent, and realised that 
some additional wrappers will be needed to access the POJO again.

I'll put that on the back-burner for a while.

Regards,
Kevin


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Mike Kienenberger <mk...@gmail.com>.
Yes, I'm sorry if I wasn't clear.   The wrapping of CayenneDataObject
would be handled in your own code.

It's definitely possible -- I used this kind of a strategy for a while
with a project that could support either JPA or Cayenne as a back-end.
Generated code was the key for me to keep it manageable -- instead of
generating only CayenneDataObjects, I also generated the JPA classes
as well as the wrapping classes.

On Mon, Dec 12, 2011 at 1:28 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
>
> On Dec 11, 2011, at 7:00 PM, Kevin Meyer - KMZ wrote:
>
>> I wish it were this simple. But the problem lies in
>>       DataContext#newObject(String entityName)
>> once it has created an instance of my POJO, it type casts it to
>> Persistent:
>>            object = (Persistent) descriptor.createObject();
>>
>> This *forces* my POJO to implement Persistent.
>
> You may have to do the wrapping on your own after that I guess... If it is at all possible.
>
> IIRC elsewhere in this thread you said you were OK with Isis objects extending CayenneDataObject. CayenneDataObject implements Persistent of course. So maybe there was some misunderstanding earlier in this discussion? If your object really has to be a POJO (as in Java class with no special superclass and data contained in the user-defined fields), we need to backtrack quite a bit and reevaluate the problem.
>
>> Why doesn't Cayenne support composition over inheritance? I think
>> the idea of containing the CayenneDataObject as suggested provides
>> much greater flexibility... and you generate these classes, anyway.
>
> In the Isis integration case - maybe. I don't think we've ever considered using a delegate to give persistent objects a semblance of a POJO by removing a requirement for a superclass, but still forcing our own internal structure. So it is probably worth a discussion, although I am cautiously pessimistic about it being done easily at Cayenne level.
>
> Andrus
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Dec 11, 2011, at 7:00 PM, Kevin Meyer - KMZ wrote:

> I wish it were this simple. But the problem lies in
> 	DataContext#newObject(String entityName)
> once it has created an instance of my POJO, it type casts it to 
> Persistent:
>            object = (Persistent) descriptor.createObject();
> 
> This *forces* my POJO to implement Persistent.

You may have to do the wrapping on your own after that I guess... If it is at all possible.

IIRC elsewhere in this thread you said you were OK with Isis objects extending CayenneDataObject. CayenneDataObject implements Persistent of course. So maybe there was some misunderstanding earlier in this discussion? If your object really has to be a POJO (as in Java class with no special superclass and data contained in the user-defined fields), we need to backtrack quite a bit and reevaluate the problem.

> Why doesn't Cayenne support composition over inheritance? I think 
> the idea of containing the CayenneDataObject as suggested provides 
> much greater flexibility... and you generate these classes, anyway.

In the Isis integration case - maybe. I don't think we've ever considered using a delegate to give persistent objects a semblance of a POJO by removing a requirement for a superclass, but still forcing our own internal structure. So it is probably worth a discussion, although I am cautiously pessimistic about it being done easily at Cayenne level.

Andrus


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
By the way, I'm using Cayenne 3.1M4-SNAPSHOT.

> I don't really know what you're doing, but what about something like this:
> 
> class POJO {
>     CayenneDataObject delegate;
> 
>     public POJO() {
>     }
> 
>     public setDelegate(CayenneDataObject cdo) {
>          this.delegate = cdo;
>     }
> 

I wish it were this simple. But the problem lies in
 	DataContext#newObject(String entityName)
once it has created an instance of my POJO, it type casts it to 
Persistent:
            object = (Persistent) descriptor.createObject();

This *forces* my POJO to implement Persistent.

Is there another way to create an instance of my POJO ?


Why doesn't Cayenne support composition over inheritance? I think 
the idea of containing the CayenneDataObject as suggested provides 
much greater flexibility... and you generate these classes, anyway.


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Mike Kienenberger <mk...@gmail.com>.
I don't really know what you're doing, but what about something like this:

class POJO {
    CayenneDataObject delegate;

    public POJO() {
    }

    public setDelegate(CayenneDataObject cdo) {
         this.delegate = cdo;
    }

// or

    public POJO(CayenneDataObject cdo) {
         this.delegate = cdo;
    }

// for each attribute (and similar for each relationship)

    public type getX() {
        return delegate.readProperty("x");
    }

    public void setX(type x) {
         writeProperty("x", x);
    }
}



On Sun, Dec 11, 2011 at 11:38 AM, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> Thanks - I've got to the point where Cayenne is trying to instantiate an
> instance of one of my pojos, but I've run into a problem...
>
> Cayenne *requires* the pojo to implement the Persisted interface, but
> this interface kills the Isis introspector (it detects the XMLSerializer,
> which contains a Collections parameter, which is not supported).
>
> I'm looking into how to wrap the Isis user Pojo (which does not *have*
> to implement any interface or extend any class), into something that
> Cayenne can instantiate.
>
> Any ideas?
>
> Regards,
> Kevin
>
>
>
>> So what do your pojos (entity classes) look like?  Like andrus said,
>> typically these have a specific implementation for cayenne.  If you just
>> have plain fields with fetters and setters then you will need some custom
>> logic to make cayenne work with them.
>>
>> For creating the model you need to do new DataMap and then add new DbEntity
>> instances and ObjEntity instances and DbAttribute and ObjAttribute
>> instances need to be added to each and relationships etc. the Db* types
>> need to be connected to the Obj* types.
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
Thanks - I've got to the point where Cayenne is trying to instantiate an 
instance of one of my pojos, but I've run into a problem... 

Cayenne *requires* the pojo to implement the Persisted interface, but 
this interface kills the Isis introspector (it detects the XMLSerializer, 
which contains a Collections parameter, which is not supported).

I'm looking into how to wrap the Isis user Pojo (which does not *have* 
to implement any interface or extend any class), into something that 
Cayenne can instantiate.

Any ideas?

Regards,
Kevin



> So what do your pojos (entity classes) look like?  Like andrus said,
> typically these have a specific implementation for cayenne.  If you just
> have plain fields with fetters and setters then you will need some custom
> logic to make cayenne work with them.
> 
> For creating the model you need to do new DataMap and then add new DbEntity
> instances and ObjEntity instances and DbAttribute and ObjAttribute
> instances need to be added to each and relationships etc. the Db* types
> need to be connected to the Obj* types.


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by John Huss <jo...@gmail.com>.
So what do your pojos (entity classes) look like?  Like andrus said,
typically these have a specific implementation for cayenne.  If you just
have plain fields with fetters and setters then you will need some custom
logic to make cayenne work with them.

For creating the model you need to do new DataMap and then add new DbEntity
instances and ObjEntity instances and DbAttribute and ObjAttribute
instances need to be added to each and relationships etc. the Db* types
need to be connected to the Obj* types.

On Saturday, December 10, 2011, Kevin Meyer - KMZ <ke...@kmz.co.za> wrote:
> On 8 Dec 2011 at 16:18, Andrus Adamchik wrote:
>
>>
>> In the custom module define DataDomain loading services to
>> reverse-engineer the POJOs instead of loading mapping from XML. This
>> is the biggest task, requiring some understanding of Cayenne APIs.
>> Feel free to ask here if you get stuck with anything. Also map
>> SchemaUpdateStrategy to CreateIfNoSchemaStrategy that will create a
>> DB schema based on your mapping.
>
> Ok!
>
> I've decided to first try re-implementing a new Isis ObjectStore (which
> has a bespoke Isis Persistence API) before writing a whole new Isis
> Context which is independent of the Persistence API.
>
> Anyway.
>
> I now have my empty project, Isis has been told about a new
> ObjectStore (CayenneObjectStore), and in the
> CayenneObjectStore#open() method, I have created a runtime and a
> context. I also have a custom Module to inject my helpers.
>
> Of course, when I try create an object:
> Object o = context.newObject(persistentClass);
> I get an exception of:
> Class is not mapped with Cayenne: isis.persistor.SimpleClassA
> which is to be expected.
>
> So!
>
> I expect I need to provide a custom binder for EntityResolver?
>
> I'm trying:
>        binder.bind(EntityResolver.class).toInstance(
>        new IsisEntityResolver());
>
> in my custom module, but its not being picked up in the DataContext.
>
> But I can inject it manually:
>        DataContext dc = (DataContext) context;
>        dc.setEntityResolver(new IsisEntityResolver());
>
> Nevermind.
>
> What are the basics of defining DataDomain loading services to
> reverse-engineer the POJOs ?
>
> I already have the list of domain entities and their properties (from
> Isis)...
>
>
> Regards,
> Kevin
>
>

Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Kevin Meyer - KMZ <ke...@kmz.co.za>.
On 8 Dec 2011 at 16:18, Andrus Adamchik wrote:

> 
> In the custom module define DataDomain loading services to
> reverse-engineer the POJOs instead of loading mapping from XML. This
> is the biggest task, requiring some understanding of Cayenne APIs.
> Feel free to ask here if you get stuck with anything. Also map
> SchemaUpdateStrategy to CreateIfNoSchemaStrategy that will create a
> DB schema based on your mapping. 

Ok!

I've decided to first try re-implementing a new Isis ObjectStore (which 
has a bespoke Isis Persistence API) before writing a whole new Isis 
Context which is independent of the Persistence API.

Anyway.

I now have my empty project, Isis has been told about a new 
ObjectStore (CayenneObjectStore), and in the 
CayenneObjectStore#open() method, I have created a runtime and a 
context. I also have a custom Module to inject my helpers.

Of course, when I try create an object:
Object o = context.newObject(persistentClass);
I get an exception of:
Class is not mapped with Cayenne: isis.persistor.SimpleClassA
which is to be expected.

So!

I expect I need to provide a custom binder for EntityResolver?

I'm trying:
        binder.bind(EntityResolver.class).toInstance(
	new IsisEntityResolver());

in my custom module, but its not being picked up in the DataContext.

But I can inject it manually:
        DataContext dc = (DataContext) context;
        dc.setEntityResolver(new IsisEntityResolver());

Nevermind.

What are the basics of defining DataDomain loading services to 
reverse-engineer the POJOs ?

I already have the list of domain entities and their properties (from 
Isis)...


Regards,
Kevin


Re: Is it possible/easy to integrate cayenne with other frameworks?

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Kevin,

I should say that Cayenne is uniquely suited for creating persistent stack and mapping at runtime, as there's no class enhancement involved. POJO's being subclasses of CayenneDataObject, with set/get implemented the way we do them in Cayenne is the only hard requirement. From there, as John has mentioned, you make some assumptions. The biggest assumption is that you control the DB and there's no chance of a legacy schema that you'd have to support (in which case you will need to create Cayenne mapping by hand to reconcile column naming and type differences between Java and DB). 

Implementation (assuming Cayenne 3.1) may be encapsulated in a custom Cayenne DI module. We are still in the process of writing the docs for 3.1, but most DI features are well documented in this otherwise empty PDF:

http://people.apache.org/~aadamchik/misc/cayenne-guide-08302011.pdf

In the custom module define DataDomain loading services to reverse-engineer the POJOs instead of loading mapping from XML. This is the biggest task, requiring some understanding of Cayenne APIs. Feel free to ask here if you get stuck with anything. Also map SchemaUpdateStrategy to CreateIfNoSchemaStrategy that will create a DB schema based on your mapping.

This should be it at the high level, but of course you'll need to write some code here. I used to implement a similar task - going from reverse-engineered DB to a runtime mapping of generic Java classes, and that worked pretty well.

Good luck, and let us know how this works - maybe some of these new factories that you develop could be of general use to Cayenne users as well as ISIS users.

Andrus 


On Dec 5, 2011, at 8:59 PM, Kevin Meyer - KMZ wrote:

> Hi all,
> 
> Please point me to the previous message if this has already been 
> addressed.. I did a quick search, but couldn't find anything that looked 
> directly relevant.
> 
> Anyway: I have been maintaining the SQL Objectstore (jdbc) for 
> Apache Isis (currently in the incubator), and would like to know if 
> Cayenne can be used completely "in the background", with no user 
> integration (i.e. no need to run the configuration tool / modeller / etc).
> 
> Isis is a complete framework solution for developing and deploying 
> POJO / domain objects, and provides hooks for persistence tasks.
> For example, the metamodel context provide:
> 	public ObjectInstantiator getObjectInstantiator();
> 	public ObjectDirtier getObjectDirtier();
> 	public ObjectPersistor getObjectPersistor();
> 
> where, for example:
> public interface ObjectInstantiator extends Injectable {
>   /**
>     * Provided by the <tt>ObjectFactory</tt> when used by framework.
>     * 
>     * <p>
>     * Called by {@link ObjectSpecificationDefault}.
>     */
>    Object instantiate(Class<?> cls) throws 
> ObjectInstantiationException;
> }
> 
> Isis requires no annotations, etc, to support persistence, which is 
> taken care of via introspection. Some hints can be provided to the 
> objectstore via the "isis.properties" file, if required.
> 
> So, I would like to know how difficult would it be to "just" hook Cayenne 
> into the object "create", "find" and "update" methods of Isis, and let  
> Cayenne take care of the ORM / persistence?
> 
> Taking a quick browse through the examples, I don't see where I 
> configure the database connection, for example.
> 
> Regards,
> Kevin
> 
> 
>