Re: Question regarding metadata handling in ojb 1.0.4

Armin Waibel <[email protected]> Fri, 27 Jul 2007 02:40:02 +0200
Newsgroups gmane.comp.jakarta.ojb.user
Message-ID <[email protected]>
Hi Bernd,

Längerich, Bernd wrote:
> Hi,
> 
> I am trying to find some information regarding metadata merging in
> the following scenario:
> 
> We have a base application with some classes, db tables and a
> repository_user.xml that describes the mapping. Lets say we have a
> base class BasePersistentClassA and some classes that are based which
> are included as extent classes in the xml file. This application is
> running.
> 
> No we develop an optional plugin with a class PluginPersistentClassB
> that is based on BasePersistentClassA of the application. I can now
> write an additional repository.xml and merge it with:
> 
> MetadataManager mm = MetadataManager.getInstance(); 
> DescriptorRepository dr =
> mm.readDescriptorRepository("my/additional/plugin_repository.xml"); 
> mm.mergeDescriptorRepository(dr);
> 
> However I am failing to get the correct contents regarding the
> extent-class definitions of the base class. I tried to include the
> following to plugin_repository.xml:
> 
> <class-descriptor class="BasePersistentClassA " <extent-class
> class-ref="PluginPersistentClassB"/> </class-descriptor>
> 
> <class-descriptor class="PluginPersistentClassB " table="MyTable" ...
>  </class-descriptor>
>

Since ClassB is an "extent" of ClassA the merge of the repositories 
isn't enough. The merge method is intended to merge/add new classes 
without dependencies to already registered classes.
You could try to use the ClassDescriptor.addExtent(...) method to 
register a new "extent":

MetadataManager mm = MetadataManager.getInstance();
DescriptorRepository dr =
mm.readDescriptorRepository("my/additional/plugin_repository.xml");
mm.mergeDescriptorRepository(dr);
//then lookup the repository
DescriptorRepository repo = mm.getRepository();
// lookup the CLD of ClassA
ClassDescriptor cldA = repo.getDescriptorFor(ClassA.class);
// add the new extent
cldA.addExtent(ClassB);

I never tried this ;-)

regards,
Armin

> Something is strange, as the following code fragment does not delete
> anything at the first broker.deleteByQuery() and fails at the second
> one:
> 
> Criteria crit = new Criteria(); 
> crit.addNotEqualTo("ojbConcreteClass",BaseApplicationClassX.class.getName());
>  Query q = QueryFactory.newQuery(Transaction.class,crit); 
> broker.deleteByQuery(q);
> 
> // SELECT DISTINCT ACC_TAID FROM ACC_TA ReportQueryByCriteria
> subquery = new ReportQueryByCriteria(BasePersistentClassA
> .class,null); subquery.setAttributes(new String[] { "id" }); 
> subquery.setDistinct(true);
> 
> Criteria crit = new Criteria(); crit.addNotIn("externalID",subquery);
>  Query q = QueryFactory.newQuery(Another.class,crit); 
> broker.deleteByQuery(q);
> 
> It seems that the extent definitions from dr are not merged and even
> corrupt the existing definitions of the application, as trying to
> access all classes from the database results in an
> NullPointerException:
> 
> 2007.07.26 17:40:33,375
> [0/ServiceRequestDispatcher-P=3/T=7-running:1/1/1] INFO  cleardb:
> start java.lang.NullPointerException at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement$TableAlias.hashCode(Unknown
> Source) at java.util.HashMap.hash(Unknown Source) at
> java.util.HashMap.put(Unknown Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.splitCriteria(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.<init>(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlSelectStatement.<init>(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.getSubQuerySQL(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendSubQuery(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendParameter(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendInCriteria(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendCriteria(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendSQLClause(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.asSQLStatement(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendClause(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.appendWhereClause(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlDeleteByQuery.buildStatement(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement.getStatement(Unknown
> Source) at
> org.apache.ojb.broker.accesslayer.JdbcAccessImpl.executeDelete(Unknown
> Source) at
> org.apache.ojb.broker.core.PersistenceBrokerImpl.deleteByQuery(Unknown
> Source) at
> org.apache.ojb.broker.core.PersistenceBrokerImpl.deleteByQuery(Unknown
> Source) at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.deleteByQuery(Unknown
> Source) at
> org.apache.ojb.broker.core.DelegatingPersistenceBroker.deleteByQuery(Unknown
> Source) [...]
> 
> If I include the table="" part, I get the NullPointerException at:
> 
> so it seems that the existing class definition is not merged with the
> additional data but overwritten.
> 
> Ommiting the extent-class-definitions from the additional xml file, I
> can access all classes of the base application, but not of the
> plugin. As we have several plugins, we dont want any dependencies
> from the base application to the plugins.
> 
> Any hints are appreciated.
> 
> Best regards
> 
> Bernd
> 
> 
> ---------------------------------------------------------------------
>  To unsubscribe, e-mail: [email protected] For
> additional commands, e-mail: [email protected]
> 
>