You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Chris Gamache <cg...@gmail.com> on 2008/08/01 05:55:16 UTC

Re: Cayenne 3.0M4 ignoring extended data types

Every time I create a DataContext, it gets created with makeContext. I
pass in different the config locations.

I didn't post the code for PostgresUniqueidentifier or PostgresMoney
because I didn't think the guts of those classes really mattered, but
more that they existed in the first place. PostgresUniqueidentifier
will take a java.util.UUID and allow it to be treated as a JDBC string
with no explicit typecasting when using PostgreSQL. PostgresMoney
wraps itself aroung the PGmoney class from the PgJDBC library and
allows seamless access to that datatype. I don't  set them up in the
XML. Should I? Is there a 3.0 feature I'm missing? I'll be glad to
post those classes if you'd like to see them. It's just a whole lot
for a listserv. Just say the word...

They themselves function properly (at least in 2.0 they did) ...

On 7/31/08, Michael Gentry <bl...@gmail.com> wrote:
> It is a lot to dig through ... :-)
>
> Some more questions:
>
> You show regsitering PostgresUniqueIdentifier and PostgresMoney in the
> code, but they are not in the XML.  Is this a red herring or an
> omission?  Do you have the full class name, including package name, in
> the XML for your types?
>
> Also, are you registering your ExtendedTypes in ALL DataNodes?  You
> mentioned having having multiple cayenne.xml files and the
> ExtendedTypes need to be registered in ALL DataNodes because each
> DataNode is responsible for doing type translation processing.
>
> And, do your ExtendedTypes implement ExtendedType?  Or subclass
> something which does?
>
> Thanks.
>
>
> On Thu, Jul 31, 2008 at 1:13 PM, Chris Gamache <cg...@gmail.com> wrote:
>> On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
>> <bl...@gmail.com>wrote:
>>
>>> Could you give an example of how you are using and declaring the
>>> extended types?  A lot of work has been done in that department since
>>> 2.x, including adding enumeration support.
>>
>>
>> Sure!
>>
>>  public DataContext makeContext(final String configuration, final String
>> classPath, final String nodeName ) {
>>
>>  if (!initialized) {
>>   DefaultConfiguration dc = new DefaultConfiguration(configuration);
>>   dc.addClassPath(classPath);
>>   boolean cayenneNotInitialized = false;
>>   try {
>>    Configuration conf = Configuration.getSharedConfiguration();
>>   } catch (Exception e) {
>>    cayenneNotInitialized = true;
>>   }
>>
>>   if (cayenneNotInitialized) {
>>    dc.initializeSharedConfiguration(dc);
>>   } else {
>>    try{
>>     dc.initialize();
>>    }catch(Exception e){
>>     throw new ConfigurationException();
>>    }
>>   }
>>
>>   for (Object d : dc.getDomain().getDataMaps().toArray()) {
>>    DataMap dm = (DataMap)d;
>>   }
>>   for (Object d : dc.getDomain().getDataNodes().toArray()) {
>>    DataNode dn = (DataNode)d;
>>   }
>> *  //Heres where I'm registering the types...*
>>
>>
>> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
>> PostgresUniqueIdentifier());
>>
>> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
>> PostgresMoney());
>>   Configuration sharedConfig = null;
>>   try {
>>     sharedConfig = Configuration.getSharedConfiguration();
>>    Iterator<DataMap> dcDataMapItr =
>> dc.getDomain().getDataMaps().iterator();
>>    while (dcDataMapItr.hasNext()) {
>>     sharedConfig.getDomain().addMap(dcDataMapItr.next());
>>    }
>>    Iterator<DataNode> dcDataNodeItr =
>> dc.getDomain().getDataNodes().iterator();
>>    while(dcDataNodeItr.hasNext()) {
>>     sharedConfig.getDomain().addNode(dcDataNodeItr.next());
>>    }
>>   } catch (Exception e) {
>>    Configuration.initializeSharedConfiguration(dc);
>>   }
>>
>>   initialized = true;
>>  }
>>  for (Object d :
>> Configuration.getSharedConfiguration().getDomain().getDataMaps().toArray())
>> {
>>   DataMap dm = (DataMap)d;
>>  }
>>  for (Object d :
>> Configuration.getSharedConfiguration().getDomain().getDataNodes().toArray())
>> {
>>   DataNode dn = (DataNode)d;
>>  }
>>
>>  return DataContext.createDataContext();
>>  }
>>
>> And here's some XML for declaring the fields...
>>  <obj-entity name="CompanyTable" className="com.user.rdbms.CompanyTable"
>> dbEntityName="company_table">
>>  <obj-attribute name="code" type="java.lang.Integer"
>> db-attribute-path="code"/>
>>  <obj-attribute name="comment" type="java.lang.String"
>> db-attribute-path="comment"/>
>>  <obj-attribute name="companyName" type="java.lang.String"
>> db-attribute-path="company_name"/>
>>  <obj-attribute name="companyUuid" type="java.util.UUID"
>> db-attribute-path="company_uuid"/>
>>  ....and so on
>>
>>  <db-entity name="company_table">
>>  <db-attribute name="code" type="INTEGER" length="10"/>
>>  <db-attribute name="comment" type="CLOB" length="2147483647"/>
>>  <db-attribute name="company_name" type="VARCHAR" length="50"/>
>>  <db-attribute name="company_uuid" type="OTHER" length="2147483647"/>
>>  ....and so on
>>
>>  <db-relationship name="toCompanyTable" source="user_table"
>> target="company_table" toMany="false">
>>  <db-attribute-pair source="company_name" target="company_name"/>
>>  </db-relationship>
>>
>> and user_table has a company_name which is used as the unqiue key to
>> retrieve the relevant company from the user.
>>
>> So then....
>>
>>  protected UserTable getUser() {
>>  if(context == null){
>>   this.context = ContextCreator.makeContext(..., ..., ...); //with
>> real values for "..."
>>  }
>>  if(user == null){
>>   Expression exp =
>> ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
>> userUUID);
>>   SelectQuery select = new SelectQuery(UserTable.class, exp);
>>   user = (UserTable) DataObjectUtils.objectForQuery(context, select);
>>   if(user == null)  throw new IllegalStateException("user " + userUUID + "
>> not found);
>>  }
>>  return user;
>>  }
>>
>> And then...
>>
>> protected CompanyTable getCompany() {
>>  if(company == null){
>>   company = getUser().getToCompanyTable();
>>   if(company == null) throw new IllegalStateException("Company not found
>> for user " + getUser().getUserUuid());
>>  }
>>  return company;
>>  }
>>
>>
>> And I can use user.getUserUuid() with no problems, but if I try to do
>> company.getCompanyUuid() where company was retrieved using
>> user.getToCompanyTable() it bombs as though the ExtendedTypes aren't
>> there.
>>
>> I hope this isn't too much to dig through....
>>
>> Thanks again for taking a peek...
>>
>

Re: Cayenne 2.0.4 are reverse relationships required

Posted by Chad Smith <ch...@gmail.com>.
Never mind - it wasn't a reverse relationship problem.

Chad

Re: Cayenne 2.0.4 are reverse relationships required

Posted by Chad Smith <ch...@gmail.com>.
I need to provide some background: I have a web app (Spring+Cayenne) 
which has been modularized so that functionality can be added or removed 
w/ as little effort as possible. 

Lets say for example, that I have a module called core that has an 
address table which I would like to make available to all the other 
modules but I don't want the address table or its domain object to know 
anything about the other modules.  So here is the address table ...


Address
------------------------
adress_id
street_1
street_2
city
state
postal_code
country

... and here is a table in another module that would like to use the 
"core" Address functionality ...

Customer
-----------------------
customer_id
first_name
last_name
...
shipping_address_id
billing_address_is


So that I don't have a dependency from the core module you can see that 
the relationship will only be one way from customerToAddress.  
(address.address_id -> customer.shipping_address_id, etc).  I don't want 
the reverse relationship b/c then there will be a reference (in the 
mapping xml) from core to an addon module.

This seems to work OK when I store the object.  The 
customer.shipping_address_id (and billing_address_id) fields are 
populated in the database.  However, when I try to access the billing 
address (via customer.getCustomerToBillingAddress()) method, an address 
object is returned, however, all the values are null.  I'm wondering if 
this due to the lack of a reverse relationship?

TIA
Chad




Re: Cayenne 3.0M4 ignoring extended data types

Posted by Chris Gamache <cg...@gmail.com>.
Here's the code for my extended type which works fine in 2.0, and for data
objects of type uniqueidentifier obtained from a first generation query, and
not from a relational fetcher.

public class PostgresUniqueIdentifier implements ExtendedType {
 public String getClassName() {
  return "java.util.UUID";
 }
 public Object materializeObject(CallableStatement rs, int index, int type)
   throws Exception {
  if (type == Types.NULL) {
   return null;
  } else {
   return UUID.fromString(rs.getString(index));
  }

 }
 public Object materializeObject(ResultSet rs, int index, int type) throws
Exception {
  if (type == Types.NULL) {
   return null;
  } else {
   if(rs.getString(index) != null){
    return UUID.fromString(rs.getString(index));
   }else{
    return(null);
   }
  }
 }
 public void setJdbcObject(PreparedStatement statement, Object value,
   int pos, int type, int precision) throws Exception {
  if (value == null) {
   statement.setNull(pos, Types.NULL);
  } else if (value instanceof UUID) {
   statement.setObject(pos,((UUID)value).toString());
  } else if (value instanceof String) {
   statement.setObject(pos,(String)value);
  }

 }


    public boolean validateProperty(
            Object source,
            String property,
            Object value,
            DbAttribute dbAttribute,
            ValidationResult validationResult) {
     String message = "";

     if (value == null) {
      return true;
     }

        if (value instanceof UUID) {
         return true;
        } else if (value instanceof String) {
      try {
       UUID uuid = UUID.fromString((String)value);
       return true;
      } catch (Exception e) {
                message = "\""
                    + property
                    + "\" does not match UUID format";
                return false;
      }
        } else {
         message = "\""
                + property
                + "\" is not a UUID";
        }
        validationResult.addFailure(new BeanValidationFailure(
                source,
                property,
                message));

        return false;
    }


}
I still contentend that the behavior I'm experiencing is buggy behavior on
Cayenne 3.0's part.


On Fri, Aug 1, 2008 at 1:43 PM, Michael Gentry <bl...@gmail.com> wrote:

> My best guess at the moment is you are not registering it in your
> DataNode or you have a class path issue or you haven't implemented an
> ExtendedType for Cayenne to know how to deal with it.  Actually,
> java.util.UUID is not a Cayenne ExtendedType and you probably need a
> wrapper around it for Cayenne to be able to read/write the type and
> work with the data.
>
> Take a look at:
>
>
> http://cayenne.apache.org/doc/api/org/apache/cayenne/access/types/ExtendedType.html
>
>
> On Fri, Aug 1, 2008 at 1:29 PM, Chris Gamache <cg...@gmail.com> wrote:
> > I've been looking around, stepping through the code execution, trying to
> > find where Cayenne goes digging into the ExtendedTypeMap, and to see if
> that
> > step gets omitted when dealing with referenced tables. I'm still looking,
> > but I did find one odd thing so far:
> >
> > In org.apache.cayenne.access.jdbc.ColumnDescriptor, the javaClass for the
> > column with the extended type is null. It should most definitely be
> > java.util.UUID as evidenced by the entry in the XML file. No other column
> > (at least none that I've looked at) has a null for the javaClass. Is this
> > normal, or a symptom of the type of problem that exists?
> > On Thu, Jul 31, 2008 at 11:55 PM, Chris Gamache <cg...@gmail.com>
> wrote:
> >
> >> Every time I create a DataContext, it gets created with makeContext. I
> >> pass in different the config locations.
> >>
> >> I didn't post the code for PostgresUniqueidentifier or PostgresMoney
> >> because I didn't think the guts of those classes really mattered, but
> >> more that they existed in the first place. PostgresUniqueidentifier
> >> will take a java.util.UUID and allow it to be treated as a JDBC string
> >> with no explicit typecasting when using PostgreSQL. PostgresMoney
> >> wraps itself aroung the PGmoney class from the PgJDBC library and
> >> allows seamless access to that datatype. I don't  set them up in the
> >> XML. Should I? Is there a 3.0 feature I'm missing? I'll be glad to
> >> post those classes if you'd like to see them. It's just a whole lot
> >> for a listserv. Just say the word...
> >>
> >> They themselves function properly (at least in 2.0 they did) ...
> >>
> >> On 7/31/08, Michael Gentry <bl...@gmail.com> wrote:
> >> > It is a lot to dig through ... :-)
> >> >
> >> > Some more questions:
> >> >
> >> > You show regsitering PostgresUniqueIdentifier and PostgresMoney in the
> >> > code, but they are not in the XML.  Is this a red herring or an
> >> > omission?  Do you have the full class name, including package name, in
> >> > the XML for your types?
> >> >
> >> > Also, are you registering your ExtendedTypes in ALL DataNodes?  You
> >> > mentioned having having multiple cayenne.xml files and the
> >> > ExtendedTypes need to be registered in ALL DataNodes because each
> >> > DataNode is responsible for doing type translation processing.
> >> >
> >> > And, do your ExtendedTypes implement ExtendedType?  Or subclass
> >> > something which does?
> >> >
> >> > Thanks.
> >> >
> >> >
> >> > On Thu, Jul 31, 2008 at 1:13 PM, Chris Gamache <cg...@gmail.com>
> >> wrote:
> >> >> On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
> >> >> <bl...@gmail.com>wrote:
> >> >>
> >> >>> Could you give an example of how you are using and declaring the
> >> >>> extended types?  A lot of work has been done in that department
> since
> >> >>> 2.x, including adding enumeration support.
> >> >>
> >> >>
> >> >> Sure!
> >> >>
> >> >>  public DataContext makeContext(final String configuration, final
> String
> >> >> classPath, final String nodeName ) {
> >> >>
> >> >>  if (!initialized) {
> >> >>   DefaultConfiguration dc = new DefaultConfiguration(configuration);
> >> >>   dc.addClassPath(classPath);
> >> >>   boolean cayenneNotInitialized = false;
> >> >>   try {
> >> >>    Configuration conf = Configuration.getSharedConfiguration();
> >> >>   } catch (Exception e) {
> >> >>    cayenneNotInitialized = true;
> >> >>   }
> >> >>
> >> >>   if (cayenneNotInitialized) {
> >> >>    dc.initializeSharedConfiguration(dc);
> >> >>   } else {
> >> >>    try{
> >> >>     dc.initialize();
> >> >>    }catch(Exception e){
> >> >>     throw new ConfigurationException();
> >> >>    }
> >> >>   }
> >> >>
> >> >>   for (Object d : dc.getDomain().getDataMaps().toArray()) {
> >> >>    DataMap dm = (DataMap)d;
> >> >>   }
> >> >>   for (Object d : dc.getDomain().getDataNodes().toArray()) {
> >> >>    DataNode dn = (DataNode)d;
> >> >>   }
> >> >> *  //Heres where I'm registering the types...*
> >> >>
> >> >>
> >> >>
> >>
> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
> >> >> PostgresUniqueIdentifier());
> >> >>
> >> >>
> >>
> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
> >> >> PostgresMoney());
> >> >>   Configuration sharedConfig = null;
> >> >>   try {
> >> >>     sharedConfig = Configuration.getSharedConfiguration();
> >> >>    Iterator<DataMap> dcDataMapItr =
> >> >> dc.getDomain().getDataMaps().iterator();
> >> >>    while (dcDataMapItr.hasNext()) {
> >> >>     sharedConfig.getDomain().addMap(dcDataMapItr.next());
> >> >>    }
> >> >>    Iterator<DataNode> dcDataNodeItr =
> >> >> dc.getDomain().getDataNodes().iterator();
> >> >>    while(dcDataNodeItr.hasNext()) {
> >> >>     sharedConfig.getDomain().addNode(dcDataNodeItr.next());
> >> >>    }
> >> >>   } catch (Exception e) {
> >> >>    Configuration.initializeSharedConfiguration(dc);
> >> >>   }
> >> >>
> >> >>   initialized = true;
> >> >>  }
> >> >>  for (Object d :
> >> >>
> >>
> Configuration.getSharedConfiguration().getDomain().getDataMaps().toArray())
> >> >> {
> >> >>   DataMap dm = (DataMap)d;
> >> >>  }
> >> >>  for (Object d :
> >> >>
> >>
> Configuration.getSharedConfiguration().getDomain().getDataNodes().toArray())
> >> >> {
> >> >>   DataNode dn = (DataNode)d;
> >> >>  }
> >> >>
> >> >>  return DataContext.createDataContext();
> >> >>  }
> >> >>
> >> >> And here's some XML for declaring the fields...
> >> >>  <obj-entity name="CompanyTable"
> className="com.user.rdbms.CompanyTable"
> >> >> dbEntityName="company_table">
> >> >>  <obj-attribute name="code" type="java.lang.Integer"
> >> >> db-attribute-path="code"/>
> >> >>  <obj-attribute name="comment" type="java.lang.String"
> >> >> db-attribute-path="comment"/>
> >> >>  <obj-attribute name="companyName" type="java.lang.String"
> >> >> db-attribute-path="company_name"/>
> >> >>  <obj-attribute name="companyUuid" type="java.util.UUID"
> >> >> db-attribute-path="company_uuid"/>
> >> >>  ....and so on
> >> >>
> >> >>  <db-entity name="company_table">
> >> >>  <db-attribute name="code" type="INTEGER" length="10"/>
> >> >>  <db-attribute name="comment" type="CLOB" length="2147483647"/>
> >> >>  <db-attribute name="company_name" type="VARCHAR" length="50"/>
> >> >>  <db-attribute name="company_uuid" type="OTHER" length="2147483647"/>
> >> >>  ....and so on
> >> >>
> >> >>  <db-relationship name="toCompanyTable" source="user_table"
> >> >> target="company_table" toMany="false">
> >> >>  <db-attribute-pair source="company_name" target="company_name"/>
> >> >>  </db-relationship>
> >> >>
> >> >> and user_table has a company_name which is used as the unqiue key to
> >> >> retrieve the relevant company from the user.
> >> >>
> >> >> So then....
> >> >>
> >> >>  protected UserTable getUser() {
> >> >>  if(context == null){
> >> >>   this.context = ContextCreator.makeContext(..., ..., ...); //with
> >> >> real values for "..."
> >> >>  }
> >> >>  if(user == null){
> >> >>   Expression exp =
> >> >> ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
> >> >> userUUID);
> >> >>   SelectQuery select = new SelectQuery(UserTable.class, exp);
> >> >>   user = (UserTable) DataObjectUtils.objectForQuery(context, select);
> >> >>   if(user == null)  throw new IllegalStateException("user " +
> userUUID +
> >> "
> >> >> not found);
> >> >>  }
> >> >>  return user;
> >> >>  }
> >> >>
> >> >> And then...
> >> >>
> >> >> protected CompanyTable getCompany() {
> >> >>  if(company == null){
> >> >>   company = getUser().getToCompanyTable();
> >> >>   if(company == null) throw new IllegalStateException("Company not
> found
> >> >> for user " + getUser().getUserUuid());
> >> >>  }
> >> >>  return company;
> >> >>  }
> >> >>
> >> >>
> >> >> And I can use user.getUserUuid() with no problems, but if I try to do
> >> >> company.getCompanyUuid() where company was retrieved using
> >> >> user.getToCompanyTable() it bombs as though the ExtendedTypes aren't
> >> >> there.
> >> >>
> >> >> I hope this isn't too much to dig through....
> >> >>
> >> >> Thanks again for taking a peek...
> >> >>
> >> >
> >>
> >
>

Re: Cayenne 3.0M4 ignoring extended data types

Posted by Michael Gentry <bl...@gmail.com>.
My best guess at the moment is you are not registering it in your
DataNode or you have a class path issue or you haven't implemented an
ExtendedType for Cayenne to know how to deal with it.  Actually,
java.util.UUID is not a Cayenne ExtendedType and you probably need a
wrapper around it for Cayenne to be able to read/write the type and
work with the data.

Take a look at:

http://cayenne.apache.org/doc/api/org/apache/cayenne/access/types/ExtendedType.html


On Fri, Aug 1, 2008 at 1:29 PM, Chris Gamache <cg...@gmail.com> wrote:
> I've been looking around, stepping through the code execution, trying to
> find where Cayenne goes digging into the ExtendedTypeMap, and to see if that
> step gets omitted when dealing with referenced tables. I'm still looking,
> but I did find one odd thing so far:
>
> In org.apache.cayenne.access.jdbc.ColumnDescriptor, the javaClass for the
> column with the extended type is null. It should most definitely be
> java.util.UUID as evidenced by the entry in the XML file. No other column
> (at least none that I've looked at) has a null for the javaClass. Is this
> normal, or a symptom of the type of problem that exists?
> On Thu, Jul 31, 2008 at 11:55 PM, Chris Gamache <cg...@gmail.com> wrote:
>
>> Every time I create a DataContext, it gets created with makeContext. I
>> pass in different the config locations.
>>
>> I didn't post the code for PostgresUniqueidentifier or PostgresMoney
>> because I didn't think the guts of those classes really mattered, but
>> more that they existed in the first place. PostgresUniqueidentifier
>> will take a java.util.UUID and allow it to be treated as a JDBC string
>> with no explicit typecasting when using PostgreSQL. PostgresMoney
>> wraps itself aroung the PGmoney class from the PgJDBC library and
>> allows seamless access to that datatype. I don't  set them up in the
>> XML. Should I? Is there a 3.0 feature I'm missing? I'll be glad to
>> post those classes if you'd like to see them. It's just a whole lot
>> for a listserv. Just say the word...
>>
>> They themselves function properly (at least in 2.0 they did) ...
>>
>> On 7/31/08, Michael Gentry <bl...@gmail.com> wrote:
>> > It is a lot to dig through ... :-)
>> >
>> > Some more questions:
>> >
>> > You show regsitering PostgresUniqueIdentifier and PostgresMoney in the
>> > code, but they are not in the XML.  Is this a red herring or an
>> > omission?  Do you have the full class name, including package name, in
>> > the XML for your types?
>> >
>> > Also, are you registering your ExtendedTypes in ALL DataNodes?  You
>> > mentioned having having multiple cayenne.xml files and the
>> > ExtendedTypes need to be registered in ALL DataNodes because each
>> > DataNode is responsible for doing type translation processing.
>> >
>> > And, do your ExtendedTypes implement ExtendedType?  Or subclass
>> > something which does?
>> >
>> > Thanks.
>> >
>> >
>> > On Thu, Jul 31, 2008 at 1:13 PM, Chris Gamache <cg...@gmail.com>
>> wrote:
>> >> On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
>> >> <bl...@gmail.com>wrote:
>> >>
>> >>> Could you give an example of how you are using and declaring the
>> >>> extended types?  A lot of work has been done in that department since
>> >>> 2.x, including adding enumeration support.
>> >>
>> >>
>> >> Sure!
>> >>
>> >>  public DataContext makeContext(final String configuration, final String
>> >> classPath, final String nodeName ) {
>> >>
>> >>  if (!initialized) {
>> >>   DefaultConfiguration dc = new DefaultConfiguration(configuration);
>> >>   dc.addClassPath(classPath);
>> >>   boolean cayenneNotInitialized = false;
>> >>   try {
>> >>    Configuration conf = Configuration.getSharedConfiguration();
>> >>   } catch (Exception e) {
>> >>    cayenneNotInitialized = true;
>> >>   }
>> >>
>> >>   if (cayenneNotInitialized) {
>> >>    dc.initializeSharedConfiguration(dc);
>> >>   } else {
>> >>    try{
>> >>     dc.initialize();
>> >>    }catch(Exception e){
>> >>     throw new ConfigurationException();
>> >>    }
>> >>   }
>> >>
>> >>   for (Object d : dc.getDomain().getDataMaps().toArray()) {
>> >>    DataMap dm = (DataMap)d;
>> >>   }
>> >>   for (Object d : dc.getDomain().getDataNodes().toArray()) {
>> >>    DataNode dn = (DataNode)d;
>> >>   }
>> >> *  //Heres where I'm registering the types...*
>> >>
>> >>
>> >>
>> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
>> >> PostgresUniqueIdentifier());
>> >>
>> >>
>> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
>> >> PostgresMoney());
>> >>   Configuration sharedConfig = null;
>> >>   try {
>> >>     sharedConfig = Configuration.getSharedConfiguration();
>> >>    Iterator<DataMap> dcDataMapItr =
>> >> dc.getDomain().getDataMaps().iterator();
>> >>    while (dcDataMapItr.hasNext()) {
>> >>     sharedConfig.getDomain().addMap(dcDataMapItr.next());
>> >>    }
>> >>    Iterator<DataNode> dcDataNodeItr =
>> >> dc.getDomain().getDataNodes().iterator();
>> >>    while(dcDataNodeItr.hasNext()) {
>> >>     sharedConfig.getDomain().addNode(dcDataNodeItr.next());
>> >>    }
>> >>   } catch (Exception e) {
>> >>    Configuration.initializeSharedConfiguration(dc);
>> >>   }
>> >>
>> >>   initialized = true;
>> >>  }
>> >>  for (Object d :
>> >>
>> Configuration.getSharedConfiguration().getDomain().getDataMaps().toArray())
>> >> {
>> >>   DataMap dm = (DataMap)d;
>> >>  }
>> >>  for (Object d :
>> >>
>> Configuration.getSharedConfiguration().getDomain().getDataNodes().toArray())
>> >> {
>> >>   DataNode dn = (DataNode)d;
>> >>  }
>> >>
>> >>  return DataContext.createDataContext();
>> >>  }
>> >>
>> >> And here's some XML for declaring the fields...
>> >>  <obj-entity name="CompanyTable" className="com.user.rdbms.CompanyTable"
>> >> dbEntityName="company_table">
>> >>  <obj-attribute name="code" type="java.lang.Integer"
>> >> db-attribute-path="code"/>
>> >>  <obj-attribute name="comment" type="java.lang.String"
>> >> db-attribute-path="comment"/>
>> >>  <obj-attribute name="companyName" type="java.lang.String"
>> >> db-attribute-path="company_name"/>
>> >>  <obj-attribute name="companyUuid" type="java.util.UUID"
>> >> db-attribute-path="company_uuid"/>
>> >>  ....and so on
>> >>
>> >>  <db-entity name="company_table">
>> >>  <db-attribute name="code" type="INTEGER" length="10"/>
>> >>  <db-attribute name="comment" type="CLOB" length="2147483647"/>
>> >>  <db-attribute name="company_name" type="VARCHAR" length="50"/>
>> >>  <db-attribute name="company_uuid" type="OTHER" length="2147483647"/>
>> >>  ....and so on
>> >>
>> >>  <db-relationship name="toCompanyTable" source="user_table"
>> >> target="company_table" toMany="false">
>> >>  <db-attribute-pair source="company_name" target="company_name"/>
>> >>  </db-relationship>
>> >>
>> >> and user_table has a company_name which is used as the unqiue key to
>> >> retrieve the relevant company from the user.
>> >>
>> >> So then....
>> >>
>> >>  protected UserTable getUser() {
>> >>  if(context == null){
>> >>   this.context = ContextCreator.makeContext(..., ..., ...); //with
>> >> real values for "..."
>> >>  }
>> >>  if(user == null){
>> >>   Expression exp =
>> >> ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
>> >> userUUID);
>> >>   SelectQuery select = new SelectQuery(UserTable.class, exp);
>> >>   user = (UserTable) DataObjectUtils.objectForQuery(context, select);
>> >>   if(user == null)  throw new IllegalStateException("user " + userUUID +
>> "
>> >> not found);
>> >>  }
>> >>  return user;
>> >>  }
>> >>
>> >> And then...
>> >>
>> >> protected CompanyTable getCompany() {
>> >>  if(company == null){
>> >>   company = getUser().getToCompanyTable();
>> >>   if(company == null) throw new IllegalStateException("Company not found
>> >> for user " + getUser().getUserUuid());
>> >>  }
>> >>  return company;
>> >>  }
>> >>
>> >>
>> >> And I can use user.getUserUuid() with no problems, but if I try to do
>> >> company.getCompanyUuid() where company was retrieved using
>> >> user.getToCompanyTable() it bombs as though the ExtendedTypes aren't
>> >> there.
>> >>
>> >> I hope this isn't too much to dig through....
>> >>
>> >> Thanks again for taking a peek...
>> >>
>> >
>>
>

Re: Cayenne 3.0M4 ignoring extended data types

Posted by Chris Gamache <cg...@gmail.com>.
I've been looking around, stepping through the code execution, trying to
find where Cayenne goes digging into the ExtendedTypeMap, and to see if that
step gets omitted when dealing with referenced tables. I'm still looking,
but I did find one odd thing so far:

In org.apache.cayenne.access.jdbc.ColumnDescriptor, the javaClass for the
column with the extended type is null. It should most definitely be
java.util.UUID as evidenced by the entry in the XML file. No other column
(at least none that I've looked at) has a null for the javaClass. Is this
normal, or a symptom of the type of problem that exists?
On Thu, Jul 31, 2008 at 11:55 PM, Chris Gamache <cg...@gmail.com> wrote:

> Every time I create a DataContext, it gets created with makeContext. I
> pass in different the config locations.
>
> I didn't post the code for PostgresUniqueidentifier or PostgresMoney
> because I didn't think the guts of those classes really mattered, but
> more that they existed in the first place. PostgresUniqueidentifier
> will take a java.util.UUID and allow it to be treated as a JDBC string
> with no explicit typecasting when using PostgreSQL. PostgresMoney
> wraps itself aroung the PGmoney class from the PgJDBC library and
> allows seamless access to that datatype. I don't  set them up in the
> XML. Should I? Is there a 3.0 feature I'm missing? I'll be glad to
> post those classes if you'd like to see them. It's just a whole lot
> for a listserv. Just say the word...
>
> They themselves function properly (at least in 2.0 they did) ...
>
> On 7/31/08, Michael Gentry <bl...@gmail.com> wrote:
> > It is a lot to dig through ... :-)
> >
> > Some more questions:
> >
> > You show regsitering PostgresUniqueIdentifier and PostgresMoney in the
> > code, but they are not in the XML.  Is this a red herring or an
> > omission?  Do you have the full class name, including package name, in
> > the XML for your types?
> >
> > Also, are you registering your ExtendedTypes in ALL DataNodes?  You
> > mentioned having having multiple cayenne.xml files and the
> > ExtendedTypes need to be registered in ALL DataNodes because each
> > DataNode is responsible for doing type translation processing.
> >
> > And, do your ExtendedTypes implement ExtendedType?  Or subclass
> > something which does?
> >
> > Thanks.
> >
> >
> > On Thu, Jul 31, 2008 at 1:13 PM, Chris Gamache <cg...@gmail.com>
> wrote:
> >> On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
> >> <bl...@gmail.com>wrote:
> >>
> >>> Could you give an example of how you are using and declaring the
> >>> extended types?  A lot of work has been done in that department since
> >>> 2.x, including adding enumeration support.
> >>
> >>
> >> Sure!
> >>
> >>  public DataContext makeContext(final String configuration, final String
> >> classPath, final String nodeName ) {
> >>
> >>  if (!initialized) {
> >>   DefaultConfiguration dc = new DefaultConfiguration(configuration);
> >>   dc.addClassPath(classPath);
> >>   boolean cayenneNotInitialized = false;
> >>   try {
> >>    Configuration conf = Configuration.getSharedConfiguration();
> >>   } catch (Exception e) {
> >>    cayenneNotInitialized = true;
> >>   }
> >>
> >>   if (cayenneNotInitialized) {
> >>    dc.initializeSharedConfiguration(dc);
> >>   } else {
> >>    try{
> >>     dc.initialize();
> >>    }catch(Exception e){
> >>     throw new ConfigurationException();
> >>    }
> >>   }
> >>
> >>   for (Object d : dc.getDomain().getDataMaps().toArray()) {
> >>    DataMap dm = (DataMap)d;
> >>   }
> >>   for (Object d : dc.getDomain().getDataNodes().toArray()) {
> >>    DataNode dn = (DataNode)d;
> >>   }
> >> *  //Heres where I'm registering the types...*
> >>
> >>
> >>
> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
> >> PostgresUniqueIdentifier());
> >>
> >>
> dc.getDomain().getNode(nodeName).getAdapter().getExtendedTypes().registerType(new
> >> PostgresMoney());
> >>   Configuration sharedConfig = null;
> >>   try {
> >>     sharedConfig = Configuration.getSharedConfiguration();
> >>    Iterator<DataMap> dcDataMapItr =
> >> dc.getDomain().getDataMaps().iterator();
> >>    while (dcDataMapItr.hasNext()) {
> >>     sharedConfig.getDomain().addMap(dcDataMapItr.next());
> >>    }
> >>    Iterator<DataNode> dcDataNodeItr =
> >> dc.getDomain().getDataNodes().iterator();
> >>    while(dcDataNodeItr.hasNext()) {
> >>     sharedConfig.getDomain().addNode(dcDataNodeItr.next());
> >>    }
> >>   } catch (Exception e) {
> >>    Configuration.initializeSharedConfiguration(dc);
> >>   }
> >>
> >>   initialized = true;
> >>  }
> >>  for (Object d :
> >>
> Configuration.getSharedConfiguration().getDomain().getDataMaps().toArray())
> >> {
> >>   DataMap dm = (DataMap)d;
> >>  }
> >>  for (Object d :
> >>
> Configuration.getSharedConfiguration().getDomain().getDataNodes().toArray())
> >> {
> >>   DataNode dn = (DataNode)d;
> >>  }
> >>
> >>  return DataContext.createDataContext();
> >>  }
> >>
> >> And here's some XML for declaring the fields...
> >>  <obj-entity name="CompanyTable" className="com.user.rdbms.CompanyTable"
> >> dbEntityName="company_table">
> >>  <obj-attribute name="code" type="java.lang.Integer"
> >> db-attribute-path="code"/>
> >>  <obj-attribute name="comment" type="java.lang.String"
> >> db-attribute-path="comment"/>
> >>  <obj-attribute name="companyName" type="java.lang.String"
> >> db-attribute-path="company_name"/>
> >>  <obj-attribute name="companyUuid" type="java.util.UUID"
> >> db-attribute-path="company_uuid"/>
> >>  ....and so on
> >>
> >>  <db-entity name="company_table">
> >>  <db-attribute name="code" type="INTEGER" length="10"/>
> >>  <db-attribute name="comment" type="CLOB" length="2147483647"/>
> >>  <db-attribute name="company_name" type="VARCHAR" length="50"/>
> >>  <db-attribute name="company_uuid" type="OTHER" length="2147483647"/>
> >>  ....and so on
> >>
> >>  <db-relationship name="toCompanyTable" source="user_table"
> >> target="company_table" toMany="false">
> >>  <db-attribute-pair source="company_name" target="company_name"/>
> >>  </db-relationship>
> >>
> >> and user_table has a company_name which is used as the unqiue key to
> >> retrieve the relevant company from the user.
> >>
> >> So then....
> >>
> >>  protected UserTable getUser() {
> >>  if(context == null){
> >>   this.context = ContextCreator.makeContext(..., ..., ...); //with
> >> real values for "..."
> >>  }
> >>  if(user == null){
> >>   Expression exp =
> >> ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
> >> userUUID);
> >>   SelectQuery select = new SelectQuery(UserTable.class, exp);
> >>   user = (UserTable) DataObjectUtils.objectForQuery(context, select);
> >>   if(user == null)  throw new IllegalStateException("user " + userUUID +
> "
> >> not found);
> >>  }
> >>  return user;
> >>  }
> >>
> >> And then...
> >>
> >> protected CompanyTable getCompany() {
> >>  if(company == null){
> >>   company = getUser().getToCompanyTable();
> >>   if(company == null) throw new IllegalStateException("Company not found
> >> for user " + getUser().getUserUuid());
> >>  }
> >>  return company;
> >>  }
> >>
> >>
> >> And I can use user.getUserUuid() with no problems, but if I try to do
> >> company.getCompanyUuid() where company was retrieved using
> >> user.getToCompanyTable() it bombs as though the ExtendedTypes aren't
> >> there.
> >>
> >> I hope this isn't too much to dig through....
> >>
> >> Thanks again for taking a peek...
> >>
> >
>