You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by André Rothe <ar...@phosco.info> on 2011/01/21 10:26:03 UTC

Creating or loading Datamap

Hello,

I try to write a short test program, which can use multiple data  
sources dynamically with Cayenne. At the moment I have finished the  
replacement for the driver.xml and cayenne.xml (I think):

--------------------------------

// init a connection
DataSourceInfo properties = new DataSourceInfo();
properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:play");
properties.setJdbcDriver("oracle.jdbc.OracleDriver");
properties.setMinConnections(1);
properties.setMaxConnections(1);
properties.setUserName("scott");
properties.setPassword("testme");

  PoolManager pmA = new PoolManager(
                     properties.getJdbcDriver(),
                     properties.getDataSourceUrl(),
                     properties.getMinConnections(),
                     properties.getMaxConnections(),
                     properties.getUserName(),
                     properties.getPassword());

DataMap map = new DataMap("test_db");
//??

DataNode node = new DataNode("dev_db");
node.addDataMap(map);
node.setDataSource(pmA);

DataDomain domainA = new DataDomain();
domainA.addNode(node);
domainA.addMap(map);

// get the context ??


// init another connection
properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:test");

PoolManager pmB = new PoolManager(
                     properties.getJdbcDriver(),
                     properties.getDataSourceUrl(),
                     properties.getMinConnections(),
                     properties.getMaxConnections(),
                     properties.getUserName(),
                     properties.getPassword());

map = new DataMap("test_db");
//??

node = new DataNode("test_db");
node.addDataMap(map);
node.setDataSource(pmB);

DataDomain domainB = new DataDomain();
domainB.addNode(node);
domainB.addMap(map);

// get the context ??


---------------------

The questions:

How I can load a predefined data map from a map.xml into my DataMap  
object without affecting the already defined objects (node, domain  
etc.)? Can I define the map dynamically? How I can create a  
DataContext for the domains I have?

I have a lot of different data sources, which are defined by some  
other parts of the application. The DataSourceInfo object must be  
changeable by the user and it can be, that I get changes on the  
database structure, so it must be possible to react on them with a new  
data-map at runtime.

Is it possible with Cayenne?

Tanks
André

Re: Creating or loading Datamap

Posted by André Rothe <ar...@phosco.info>.
It works! I have to define attributes for the ObjEntity too. That's a  
nice feature, I don't longer need any XML file to configure Cayenne.

Thanks a lot
André

Andrus Adamchik <an...@objectstyle.org> wrote:

> Actually this is good result - you are getting there. I think you  
> also need to add attributes for the columns in your table to  
> DbEntity and ObjEntity.
>
> Andrus
>
> On Jan 21, 2011, at 5:09 PM, André Rothe wrote:
>
>> Hm, it doesn't work. I can perform a SQL query, it returns the  
>> correct number of records, but the properties are NULL.
>>
>> SelectQuery q = new SelectQuery("Projects");
>> List projectsTest = this.context.get("test").performQuery(q);
>>
>> for (Object o : projectsTest) {
>>    DataObject dObj = (DataObject) o;
>>    System.out.println(dObj.readProperty("columnname"));
>> }
>>
>> I have defined a DataContext "test" as:
>>
>> DataMap map = new DataMap(mapName + " map");
>>
>> DbEntity entity = new DbEntity("tablename");
>> map.addDbEntity(entity);
>>
>> DbAttribute attr = new CharacterDbAttribute("columnname", 20, true);
>> entity.addAttribute(attr);
>>
>> // more attributes here
>> // ...
>>
>> ObjEntity objEntity = new ObjEntity("Projects");
>> objEntity.setDbEntity(entity);
>> objEntity.setClassName(CayenneDataObject.class.getName());   // default
>> map.addObjEntity(objEntity);
>>
>> DataNode node = new DataNode(mapName + " node");
>> node.addDataMap(map);
>> node.setDataSource(store.getDataSource());
>> node.setAdapter(new AutoAdapter(store.getDataSource()));
>>
>> DataDomain domain = new DataDomain(mapName + " domain");
>> domain.addNode(node);
>> domain.addMap(map);
>>
>> this.context.put(mapName, domain.createDataContext());
>>
>> The class CharacterDbAttribute sets the type to VARCHAR, mandatory  
>> and length properties. The field "store" holds the data sources  
>> (instances of PoolManager). mapName = "test".
>>
>> I think, I don't need a full-defined ObjectEntity, because it is  
>> dynamic. I set only the class name (default) and the DbEntity  
>> instance. So where I have forgotten a call?
>>
>> Thanks a lot
>> André
>>
>> Andrus Adamchik <an...@objectstyle.org> wrote:
>>
>>>
>>> On Jan 21, 2011, at 2:53 PM, André Rothe wrote:
>>>
>>>> Should I set the name explicitly to  
>>>> "org.apache.cayenne.CayenneDataObject" (or subclasses)?
>>>
>>> Setting org.apache.cayenne.CayenneDataObject is optional (this is  
>>> the default). If you want to use your own subclass, definitely  
>>> call objEntity.setClassName(MyClass.class.getName()).
>>>
>>> Andrus
>>
>>
>
>


Re: Creating or loading Datamap

Posted by Andrus Adamchik <an...@objectstyle.org>.
Actually this is good result - you are getting there. I think you also need to add attributes for the columns in your table to DbEntity and ObjEntity.

Andrus

On Jan 21, 2011, at 5:09 PM, André Rothe wrote:

> Hm, it doesn't work. I can perform a SQL query, it returns the correct number of records, but the properties are NULL.
> 
> SelectQuery q = new SelectQuery("Projects");
> List projectsTest = this.context.get("test").performQuery(q);
> 
> for (Object o : projectsTest) {
>    DataObject dObj = (DataObject) o;
>    System.out.println(dObj.readProperty("columnname"));
> }
> 
> I have defined a DataContext "test" as:
> 
> DataMap map = new DataMap(mapName + " map");
> 
> DbEntity entity = new DbEntity("tablename");
> map.addDbEntity(entity);
> 
> DbAttribute attr = new CharacterDbAttribute("columnname", 20, true);
> entity.addAttribute(attr);
> 
> // more attributes here
> // ...
> 
> ObjEntity objEntity = new ObjEntity("Projects");
> objEntity.setDbEntity(entity);
> objEntity.setClassName(CayenneDataObject.class.getName());   // default
> map.addObjEntity(objEntity);
> 
> DataNode node = new DataNode(mapName + " node");
> node.addDataMap(map);
> node.setDataSource(store.getDataSource());
> node.setAdapter(new AutoAdapter(store.getDataSource()));
> 
> DataDomain domain = new DataDomain(mapName + " domain");
> domain.addNode(node);
> domain.addMap(map);
> 
> this.context.put(mapName, domain.createDataContext());
> 
> The class CharacterDbAttribute sets the type to VARCHAR, mandatory and length properties. The field "store" holds the data sources (instances of PoolManager). mapName = "test".
> 
> I think, I don't need a full-defined ObjectEntity, because it is dynamic. I set only the class name (default) and the DbEntity instance. So where I have forgotten a call?
> 
> Thanks a lot
> André
> 
> Andrus Adamchik <an...@objectstyle.org> wrote:
> 
>> 
>> On Jan 21, 2011, at 2:53 PM, André Rothe wrote:
>> 
>>> Should I set the name explicitly to "org.apache.cayenne.CayenneDataObject" (or subclasses)?
>> 
>> Setting org.apache.cayenne.CayenneDataObject is optional (this is the default). If you want to use your own subclass, definitely call objEntity.setClassName(MyClass.class.getName()).
>> 
>> Andrus
> 
> 


Re: Creating or loading Datamap

Posted by André Rothe <ar...@phosco.info>.
Hm, it doesn't work. I can perform a SQL query, it returns the correct  
number of records, but the properties are NULL.

SelectQuery q = new SelectQuery("Projects");
List projectsTest = this.context.get("test").performQuery(q);

for (Object o : projectsTest) {
     DataObject dObj = (DataObject) o;
     System.out.println(dObj.readProperty("columnname"));
}

I have defined a DataContext "test" as:

  DataMap map = new DataMap(mapName + " map");

  DbEntity entity = new DbEntity("tablename");
  map.addDbEntity(entity);

  DbAttribute attr = new CharacterDbAttribute("columnname", 20, true);
  entity.addAttribute(attr);

  // more attributes here
  // ...

  ObjEntity objEntity = new ObjEntity("Projects");
  objEntity.setDbEntity(entity);
  objEntity.setClassName(CayenneDataObject.class.getName());   // default
  map.addObjEntity(objEntity);

  DataNode node = new DataNode(mapName + " node");
  node.addDataMap(map);
  node.setDataSource(store.getDataSource());
  node.setAdapter(new AutoAdapter(store.getDataSource()));

  DataDomain domain = new DataDomain(mapName + " domain");
  domain.addNode(node);
  domain.addMap(map);

  this.context.put(mapName, domain.createDataContext());

The class CharacterDbAttribute sets the type to VARCHAR, mandatory and  
length properties. The field "store" holds the data sources (instances  
of PoolManager). mapName = "test".

I think, I don't need a full-defined ObjectEntity, because it is  
dynamic. I set only the class name (default) and the DbEntity  
instance. So where I have forgotten a call?

Thanks a lot
André

Andrus Adamchik <an...@objectstyle.org> wrote:

>
> On Jan 21, 2011, at 2:53 PM, André Rothe wrote:
>
>> Should I set the name explicitly to  
>> "org.apache.cayenne.CayenneDataObject" (or subclasses)?
>
> Setting org.apache.cayenne.CayenneDataObject is optional (this is  
> the default). If you want to use your own subclass, definitely call  
> objEntity.setClassName(MyClass.class.getName()).
>
> Andrus


Re: Creating or loading Datamap

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jan 21, 2011, at 2:53 PM, André Rothe wrote:

> Should I set the name explicitly to "org.apache.cayenne.CayenneDataObject" (or subclasses)?

Setting org.apache.cayenne.CayenneDataObject is optional (this is the default). If you want to use your own subclass, definitely call objEntity.setClassName(MyClass.class.getName()).

Andrus

Re: Creating or loading Datamap

Posted by André Rothe <ar...@phosco.info>.
Hi Andrus,

when it comes to the generic persistence data objects, how I have to  
define it?

         DataMap map = new DataMap(mapName);

         DbEntity entity = new DbEntity("projects");
         DbAttribute attr = new DbAttribute("ora_uname");
         attr.setMaxLength(20);
         attr.setMandatory(true);
         entity.addAttribute(attr);
         map.addDbEntity(entity);

         ObjEntity objEntity = new ObjEntity("Projects");
         objEntity.setDbEntity(entity);
         objEntity.setClassName(// ??);

Should I set the name explicitly to  
"org.apache.cayenne.CayenneDataObject" (or subclasses)?

Thanks
André


Andrus Adamchik <an...@objectstyle.org> wrote:

> Hi André,
>
> Yes, if you wish you can create the entire Cayenne stack via API,  
> loading parts of it from XML files, etc.
>
> * To load DataMap from XML, use MapLoader:
>
> http://cayenne.apache.org/doc30/api/org/apache/cayenne/map/MapLoader.html
>
> * To create a DataContext, use DataDomain.createDataContext().
>
> * To change loaded DataMap, use DataMap methods to access and  
> manipulate the entities:
>
> http://cayenne.apache.org/doc30/api/org/apache/cayenne/map/DataMap.html
>
> Andrus
>
> On Jan 21, 2011, at 11:26 AM, André Rothe wrote:
>
>> Hello,
>>
>> I try to write a short test program, which can use multiple data  
>> sources dynamically with Cayenne. At the moment I have finished the  
>> replacement for the driver.xml and cayenne.xml (I think):
>>
>> --------------------------------
>>
>> // init a connection
>> DataSourceInfo properties = new DataSourceInfo();
>> properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:play");
>> properties.setJdbcDriver("oracle.jdbc.OracleDriver");
>> properties.setMinConnections(1);
>> properties.setMaxConnections(1);
>> properties.setUserName("scott");
>> properties.setPassword("testme");
>>
>> PoolManager pmA = new PoolManager(
>>                    properties.getJdbcDriver(),
>>                    properties.getDataSourceUrl(),
>>                    properties.getMinConnections(),
>>                    properties.getMaxConnections(),
>>                    properties.getUserName(),
>>                    properties.getPassword());
>>
>> DataMap map = new DataMap("test_db");
>> //??
>>
>> DataNode node = new DataNode("dev_db");
>> node.addDataMap(map);
>> node.setDataSource(pmA);
>>
>> DataDomain domainA = new DataDomain();
>> domainA.addNode(node);
>> domainA.addMap(map);
>>
>> // get the context ??
>>
>>
>> // init another connection
>> properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:test");
>>
>> PoolManager pmB = new PoolManager(
>>                    properties.getJdbcDriver(),
>>                    properties.getDataSourceUrl(),
>>                    properties.getMinConnections(),
>>                    properties.getMaxConnections(),
>>                    properties.getUserName(),
>>                    properties.getPassword());
>>
>> map = new DataMap("test_db");
>> //??
>>
>> node = new DataNode("test_db");
>> node.addDataMap(map);
>> node.setDataSource(pmB);
>>
>> DataDomain domainB = new DataDomain();
>> domainB.addNode(node);
>> domainB.addMap(map);
>>
>> // get the context ??
>>
>>
>> ---------------------
>>
>> The questions:
>>
>> How I can load a predefined data map from a map.xml into my DataMap  
>> object without affecting the already defined objects (node, domain  
>> etc.)? Can I define the map dynamically? How I can create a  
>> DataContext for the domains I have?
>>
>> I have a lot of different data sources, which are defined by some  
>> other parts of the application. The DataSourceInfo object must be  
>> changeable by the user and it can be, that I get changes on the  
>> database structure, so it must be possible to react on them with a  
>> new data-map at runtime.
>>
>> Is it possible with Cayenne?
>>
>> Tanks
>> André
>>
>
>


Re: Creating or loading Datamap

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

Yes, if you wish you can create the entire Cayenne stack via API, loading parts of it from XML files, etc. 

* To load DataMap from XML, use MapLoader:

http://cayenne.apache.org/doc30/api/org/apache/cayenne/map/MapLoader.html

* To create a DataContext, use DataDomain.createDataContext().

* To change loaded DataMap, use DataMap methods to access and manipulate the entities:

http://cayenne.apache.org/doc30/api/org/apache/cayenne/map/DataMap.html

Andrus

On Jan 21, 2011, at 11:26 AM, André Rothe wrote:

> Hello,
> 
> I try to write a short test program, which can use multiple data sources dynamically with Cayenne. At the moment I have finished the replacement for the driver.xml and cayenne.xml (I think):
> 
> --------------------------------
> 
> // init a connection
> DataSourceInfo properties = new DataSourceInfo();
> properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:play");
> properties.setJdbcDriver("oracle.jdbc.OracleDriver");
> properties.setMinConnections(1);
> properties.setMaxConnections(1);
> properties.setUserName("scott");
> properties.setPassword("testme");
> 
> PoolManager pmA = new PoolManager(
>                    properties.getJdbcDriver(),
>                    properties.getDataSourceUrl(),
>                    properties.getMinConnections(),
>                    properties.getMaxConnections(),
>                    properties.getUserName(),
>                    properties.getPassword());
> 
> DataMap map = new DataMap("test_db");
> //??
> 
> DataNode node = new DataNode("dev_db");
> node.addDataMap(map);
> node.setDataSource(pmA);
> 
> DataDomain domainA = new DataDomain();
> domainA.addNode(node);
> domainA.addMap(map);
> 
> // get the context ??
> 
> 
> // init another connection
> properties.setDataSourceUrl("jdbc:oracle:thin:@test:1521:test");
> 
> PoolManager pmB = new PoolManager(
>                    properties.getJdbcDriver(),
>                    properties.getDataSourceUrl(),
>                    properties.getMinConnections(),
>                    properties.getMaxConnections(),
>                    properties.getUserName(),
>                    properties.getPassword());
> 
> map = new DataMap("test_db");
> //??
> 
> node = new DataNode("test_db");
> node.addDataMap(map);
> node.setDataSource(pmB);
> 
> DataDomain domainB = new DataDomain();
> domainB.addNode(node);
> domainB.addMap(map);
> 
> // get the context ??
> 
> 
> ---------------------
> 
> The questions:
> 
> How I can load a predefined data map from a map.xml into my DataMap object without affecting the already defined objects (node, domain etc.)? Can I define the map dynamically? How I can create a DataContext for the domains I have?
> 
> I have a lot of different data sources, which are defined by some other parts of the application. The DataSourceInfo object must be changeable by the user and it can be, that I get changes on the database structure, so it must be possible to react on them with a new data-map at runtime.
> 
> Is it possible with Cayenne?
> 
> Tanks
> André
>