cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Marcin Skladaniec" <mar...@ish.com.au>
Subject Single table inheritance and field hiding
Date Wed, 07 Jan 2009 09:36:54 GMT
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


Mime
View raw message