cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dougan Stuart <d...@swarmbox.com>
Subject Re: Extended class issues
Date Thu, 28 Jul 2016 23:47:52 GMT
Sure, here’s the relevant parts:

<db-entity name="company" schema="public">

	<db-attribute name="name" type="VARCHAR" length="50”/>

	<db-attribute name="uuid" type="OTHER" isPrimaryKey="true" isMandatory="true" length="2147483647"/>

</db-entity>
<db-entity name="entity" schema="public”>

	<db-attribute name="audit_uuid" type="OTHER" length="2147483647”/>

	<db-attribute name="reference" type="VARCHAR" length="30"/>

	<db-attribute name="type" type="CHAR" isMandatory="true" length="1”/>

	<db-attribute name="uuid" type="OTHER" isPrimaryKey="true" isMandatory="true" length="2147483647”/>

	<db-attribute name="parent_entity_uuid" type="OTHER" length="2147483647"/>

</db-entity>

<obj-entity name="Company" superEntityName="Entity" className=“...data.models.Company”>

	<qualifier><![CDATA[type = "C"]]></qualifier>

	<obj-attribute name="name" type="java.lang.String" db-attribute-path="company.name”/>

</obj-entity>
<obj-entity name="Entity" abstract="true" className=“...data.models.Entity" dbEntityName="entity"
superClassName=“...data.CayenneBaseDataObject">

	<obj-attribute name="reference" type="java.lang.String" db-attribute-path="reference”/>

	<obj-attribute name="type" type=“...data.util.EntityType" db-attribute-path="type”/>

</obj-entity>

<db-relationship name="entity" source="company" target="entity" toMany="false”>

	<db-attribute-pair source="uuid" target="uuid"/>

</db-relationship>
<db-relationship name="company" source="entity" target="company" toDependentPK="true" toMany="false">

	<db-attribute-pair source="uuid" target="uuid"/>

</db-relationship>

<db-relationship name="parentEntity" source="entity" target="entity" toMany="false”>

	<db-attribute-pair source="parent_entity_uuid" target="uuid”/>

</db-relationship>

<db-relationship name="subEntities" source="entity" target="entity" toMany="true”>

	<db-attribute-pair source="uuid" target="parent_entity_uuid”/>

</db-relationship>


<obj-relationship name="parentCompany" source="Company" target="Company" deleteRule="Nullify"
db-relationship-path="parentEntity"/>

<obj-relationship name="subCompanies" source="Company" target="Company" deleteRule="Deny"
db-relationship-path="subEntities"/>


I’ve created a fix for this issue in DataDomainDBDiffBuilder.appendForeignKeys on line 133
(within the nested loop):

String joinSourceName = join.getSourceName();
if (dbDiff.get(joinSourceName) == null && dbEntity.getAttribute(joinSourceName) !=
null) {
	dbDiff.put(joinSourceName, value);
}

The only change is that I’m checking if the dbEntity actually has the attribute it’s trying
to add from the join. If it doesn’t have the attribute, then it doesn’t make sense to
put it on the dbDiff. In DataDomainUpdateBucket.updatedAttribtues (mentioned in my prior message),
it expects everything in the dbDiff to be an attribute that exists on the dbEntity. The fix
passed Cayenne’s tests and didn’t appear to cause any side effects. Of course, this is
all moot if I just botched the data map. Let me know what you think.

Thanks,
Doug





> On Jul 28, 2016, at 3:47 AM, Andrus Adamchik <andrus@objectstyle.org> wrote:
> 
> Would you mind posting a relevant part of your DataMap XML?
> 
> Andrus
> 
>> On Jul 13, 2016, at 8:40 PM, Dougan Stuart <doug@swarmbox.com> wrote:
>> 
>> I have a class Company with a one-to-many relationship to other Companies (parentCompany
<- subCompanies). I’m able to set a Company’s parent when creating one, but upon update
I’m getting a NullPointerException in DefaultQuotingStrategy.quotedName because it’s been
sent a null attribute. Company extends the abstract class Entity; on the DB side Entity and
Company have a one-to-one relationship, and Entity has a parentEntity reference (which is
modeled as parentCompany). The obj-relationship parentCompany is set up with the target Company
and path parentEntity.
>> 
>> The null attribute is being added in org.apache.cayenne.access.DataDomainUpdateBucket.updatedAttributes.
The method is called first with the dbEntity Entity and the an updatedSnapshot containing
parentEntity, which is what I would expect. However, after this updatedAttributes is called
with Company and an updatedSnapshot containing parentEntity, so the following line
>> 
>> attributes.add(entityAttributes.get(name))
>> 
>> will return a null attribute when trying to get the name “parentEntity” off Company’s
attributes; that attribute only exists on Entity. I’d appreciate any help on preventing
it from trying to add invalid attributes.
>> 
>> I’m not sure if this is the root cause, but  DataDomainUpdateBucket.appendQueriesInternal
calls updatedAttributes based off the bucket’s dbEntities, which in this case are set in
DataDomainSyncBucket.groupObjEntitiesBySpannedDbEntities; this method is only adding Company
as a “secondary DbEntity” (as referred to in the comments) because Company has a flattened
attribute “name" that does not exist on the Entity.
>> 
>> Here’s the stack trace:
>> 
>> java.lang.NullPointerException
>> 	at org.apache.cayenne.dba.DefaultQuotingStrategy.quotedName(DefaultQuotingStrategy.java:62)
>> 	at org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.createSql(UpdateBatchTranslator.java:60)
>> 	at org.apache.cayenne.access.translator.batch.DefaultBatchTranslator.ensureTranslated(DefaultBatchTranslator.java:52)
>> 	at org.apache.cayenne.access.translator.batch.DefaultBatchTranslator.getSql(DefaultBatchTranslator.java:64)
>> 	at org.apache.cayenne.access.jdbc.BatchAction.runAsBatch(BatchAction.java:103)
>> 	at org.apache.cayenne.access.jdbc.BatchAction.performAction(BatchAction.java:90)
>> 	at org.apache.cayenne.access.DataNodeQueryAction.runQuery(DataNodeQueryAction.java:97)
>> 	at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:293)
>> 	at org.apache.cayenne.access.DataDomainFlushAction.runQueries(DataDomainFlushAction.java:233)
>> 	at org.apache.cayenne.access.DataDomainFlushAction.flush(DataDomainFlushAction.java:154)
>> 	at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:693)
>> 	at org.apache.cayenne.access.DataDomain$2.transform(DataDomain.java:659)
>> 	at org.apache.cayenne.access.DataDomain.runInTransaction(DataDomain.java:720)
>> 	at org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:655)
>> 	at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(DataDomain.java:863)
>> 	at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:636)
>> 	at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:727)
>> 	at org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:676)
>> 
>> Thanks,
>> Doug
>> 
> 


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message