You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Lawrence Gerstley <la...@gmail.com> on 2009/01/06 02:57:25 UTC
Changing database schemas at runtime
Hello,
I've been using Cayenne and allowing for changing backends at runtime--
representing the same schema in MySQL, Oracle, Apache Derby, and have
had success changing the backend with:
DataSource dataSource = new PoolManager(
jdbcDriverDetails.getDriverClass(),
myURL,
1,
5,
myUser,
myPassword);
Configuration config =
Configuration.getSharedConfiguration();
DataDomain domain = config.getDomain();
DataNode node = domain.getNode("MyDomain");
node.setDataSource(dataSource);
My problem is that I need to also allow a user to select the schema
that the datamap should be applied to. For example, in Oracle, the
same schema design might be in multiple instances (in my example,
KTMI3D, KTMI3M, KTMI3X, etc.). I can change these with the modeler and
have it work, but I need to change it at runtime. I've tried changing
it with:
dataMap.setDefaultSchema(schema);
But haven't had much luck changing at runtime. Is there some way to do
this with my approach, or is there a better approach to take if you
want to switch back-ends multiple time at runtime?
Thanks for reading,
Lawrence
Single table inheritance and field hiding
Posted by Marcin Skladaniec <ma...@ish.com.au>.
Hi
I have created a schema with single table inheritance.
It looks something like this: 'Product' is the table,
database entity, and abstract object entity. There are few
subclasses of the Product, each has its own unique
attributes and relationships.
Product:
id
name
description
type (Article, Membership etc.)
Article
weight
Membership:
expiryDays
since all the attributes are defined in the same DbEntity
CayenneModeller by default put them all into Product
ObjEntity. I wanted to hide them in the superclass, so I
moved to relevant ObjEntities. Cayenne does not complain
when creating records.
If I then execute a simple paged query it works properly:
[java] 07 Jan 2009 19:15:40,619 [btpool0-0 ] INFO
org.apache.cayenne.access.QueryLogger :357 - SELECT t0.id
FROM Product t0 WHERE (t0.isDeleted IS NULL) OR
(t0.isDeleted = ?) OR (t0.type = ?) OR (t0.type = ?) OR
(t0.type = ?) ORDER BY t0.name [bind: 1->isDeleted:0,
2->type:1, 3->type:2, 4->type:3]
[java] 07 Jan 2009 19:15:40,629 [btpool0-0 ]
INFO org.apache.cayenne.access.QueryLogger :401 - ===
returned 1 row. - took 16 ms.
[java] 07 Jan 2009 19:15:40,629 [btpool0-0 ]
INFO org.apache.cayenne.access.QueryLogger :434 - +++
transaction committed.
but once the record is about to be faulted it fails
[java] 07 Jan 2009 19:15:40,635 [btpool0-0 ]
INFO org.apache.cayenne.access.QueryLogger :357 - SELECT
t0.id, t0.modifiedOn, t0.type, t0.notes, t0.isDeleted,
t0.isWebVisible, t0.willowId, t0.incomeAccountId,
t0.description, t0.taxId, t0.isOnSale, t0.priceExTax,
t0.createdOn, t0.name, t0.SKU, t0.weight, t0.expiryDays,
t0.expiryType, t0.value, t0.liabilityAccountId FROM
Product t0 WHERE (t0.id = ?) AND ((t0.isDeleted IS NULL)
OR (t0.isDeleted = ?) OR (t0.type = ?) OR (t0.type = ?) OR
(t0.type = ?)) [bind: 1->id:200, 2->isDeleted:0,
3->type:1, 4->type:2, 5->type:3]
[java] 07 Jan 2009 19:15:40,666 [btpool0-0 ]
INFO org.apache.cayenne.access.QueryLogger :453 - ***
error.
[java] java.lang.NullPointerException
[java] at
org.apache.cayenne.exp.parser.SimpleNode.evaluateChild(SimpleNode.java:315)
[java] at
org.apache.cayenne.exp.parser.ASTEqual.evaluateNode(ASTEqual.java:61)
[java] at
org.apache.cayenne.exp.parser.SimpleNode.evaluate(SimpleNode.java:327)
[java] at
org.apache.cayenne.exp.parser.SimpleNode.evaluateChild(SimpleNode.java:315)
[java] at
org.apache.cayenne.exp.parser.ASTOr.evaluateNode(ASTOr.java:69)
[java] at
org.apache.cayenne.exp.parser.SimpleNode.evaluate(SimpleNode.java:327)
[java] at
org.apache.cayenne.exp.Expression.match(Expression.java:367)
[java] at
org.apache.cayenne.map.EntityInheritanceTree.entityMatchingRow(EntityInheritanceTree.java:92)
[java] at
org.apache.cayenne.access.jdbc.DataRowPostProcessor.getOverrides(DataRowPostProcessor.java:147)
[java] at
org.apache.cayenne.access.jdbc.DataRowPostProcessor.postprocessRow(DataRowPostProcessor.java:128)
[java] at
org.apache.cayenne.access.jdbc.InheritanceAwareRowReader.postprocessRow(InheritanceAwareRowReader.java:45)
[java] at
org.apache.cayenne.access.jdbc.FullRowReader.readRow(FullRowReader.java:54)
[java] at
org.apache.cayenne.access.jdbc.FullRowReader.readRow(FullRowReader.java:31)
[java] at
org.apache.cayenne.access.jdbc.JDBCResultIterator.nextRow(JDBCResultIterator.java:194)
[java] at
org.apache.cayenne.access.jdbc.JDBCResultIterator.allRows(JDBCResultIterator.java:171)
[java] at
org.apache.cayenne.access.jdbc.SelectAction.performAction(SelectAction.java:155)
[java] at
org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:87)
[java] at
org.apache.cayenne.access.DataNode.performQueries(DataNode.java:236)
[java] at
org.apache.cayenne.access.DataDomainQueryAction.runQuery(DataDomainQueryAction.java:422)
[java] at
org.apache.cayenne.access.DataDomainQueryAction.access$000(DataDomainQueryAction.java:66)
[java] at
org.apache.cayenne.access.DataDomainQueryAction$2.transform(DataDomainQueryAction.java:395)
[java] at
org.apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java:846)
[java] at
org.apache.cayenne.access.DataDomainQueryAction.runQueryInTransaction(DataDomainQueryAction.java:392)
[java] at
org.apache.cayenne.access.DataDomainQueryAction.execute(DataDomainQueryAction.java:118)
[java] at
org.apache.cayenne.access.DataDomain.onQuery(DataDomain.java:739)
[java] at
org.apache.cayenne.util.ObjectContextQueryAction.runQuery(ObjectContextQueryAction.java:316)
[java] at
org.apache.cayenne.util.ObjectContextQueryAction.execute(ObjectContextQueryAction.java:95)
[java] at
org.apache.cayenne.access.DataContext.onQuery(DataContext.java:1267)
[java] at
org.apache.cayenne.access.DataContext.performQuery(DataContext.java:1256)
[java] at
org.apache.cayenne.access.IncrementalFaultList.resolveInterval(IncrementalFaultList.java:295)
[java] at
org.apache.cayenne.access.IncrementalFaultList.get(IncrementalFaultList.java:550)
[java] at
org.apache.cayenne.access.IncrementalFaultList$1.next(IncrementalFaultList.java:467)
[java] at
org.apache.cayenne.access.ClientServerChannelQueryAction.toClientObjects(ClientServerChannelQueryAction.java:187)
Is my design correct? can I hide the attributes from the
superclass and expose them only in the subclass?
Thanks
Marcin
Re: Changing database schemas at runtime
Posted by Lawrence Gerstley <la...@gmail.com>.
This worked great. Thanks for the tip.
public boolean setDataMapSchema(DataMap dataMap, String schema) {
try {
for (DbEntity dbEntity : dataMap.getDbEntities()) {
dbEntity.setSchema(schema);
}
} catch (Exception e) {
System.out.println(e.toString());
return false;
}
return true;
}
Lawrence
On Jan 5, 2009, at 11:11 PM, Andrus Adamchik wrote:
> Hi Lawrence,
>
> Yeah, the "default schema" is ignored in runtime, and only per
> DbEntity schema is consulted. Looking back, it would've been better
> to use the default if DbEntity schema is not set, and we may change
> the behavior at some point, but for now "default schema" is only
> used by the Modeler.
>
> So to change schema you would need to iterate through all DbEntities
> and set it per entity.
>
> Andrus
>
> On Jan 6, 2009, at 3:57 AM, Lawrence Gerstley wrote:
>
>> Hello,
>>
>> I've been using Cayenne and allowing for changing backends at
>> runtime--representing the same schema in MySQL, Oracle, Apache
>> Derby, and have had success changing the backend with:
>>
>> DataSource dataSource = new PoolManager(
>> jdbcDriverDetails.getDriverClass(),
>> myURL,
>> 1,
>> 5,
>> myUser,
>> myPassword);
>> Configuration config =
>> Configuration.getSharedConfiguration();
>> DataDomain domain = config.getDomain();
>> DataNode node = domain.getNode("MyDomain");
>> node.setDataSource(dataSource);
>>
>> My problem is that I need to also allow a user to select the schema
>> that the datamap should be applied to. For example, in Oracle, the
>> same schema design might be in multiple instances (in my example,
>> KTMI3D, KTMI3M, KTMI3X, etc.). I can change these with the modeler
>> and have it work, but I need to change it at runtime. I've tried
>> changing it with:
>>
>> dataMap.setDefaultSchema(schema);
>>
>> But haven't had much luck changing at runtime. Is there some way to
>> do this with my approach, or is there a better approach to take if
>> you want to switch back-ends multiple time at runtime?
>>
>> Thanks for reading,
>>
>> Lawrence
>>
>>
>
Re: Changing database schemas at runtime
Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Lawrence,
Yeah, the "default schema" is ignored in runtime, and only per
DbEntity schema is consulted. Looking back, it would've been better to
use the default if DbEntity schema is not set, and we may change the
behavior at some point, but for now "default schema" is only used by
the Modeler.
So to change schema you would need to iterate through all DbEntities
and set it per entity.
Andrus
On Jan 6, 2009, at 3:57 AM, Lawrence Gerstley wrote:
> Hello,
>
> I've been using Cayenne and allowing for changing backends at
> runtime--representing the same schema in MySQL, Oracle, Apache
> Derby, and have had success changing the backend with:
>
> DataSource dataSource = new PoolManager(
> jdbcDriverDetails.getDriverClass(),
> myURL,
> 1,
> 5,
> myUser,
> myPassword);
> Configuration config =
> Configuration.getSharedConfiguration();
> DataDomain domain = config.getDomain();
> DataNode node = domain.getNode("MyDomain");
> node.setDataSource(dataSource);
>
> My problem is that I need to also allow a user to select the schema
> that the datamap should be applied to. For example, in Oracle, the
> same schema design might be in multiple instances (in my example,
> KTMI3D, KTMI3M, KTMI3X, etc.). I can change these with the modeler
> and have it work, but I need to change it at runtime. I've tried
> changing it with:
>
> dataMap.setDefaultSchema(schema);
>
> But haven't had much luck changing at runtime. Is there some way to
> do this with my approach, or is there a better approach to take if
> you want to switch back-ends multiple time at runtime?
>
> Thanks for reading,
>
> Lawrence
>
>