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 <blacknex..mail.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 <cgamach..mail.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 <cgamach..mail.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 <blacknex..mail.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 <cgamach..mail.com>
> >> wrote:
> >> >> On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
> >> >> <blacknex..mail.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...
> >> >>
> >> >
> >>
> >
>
This archive was generated by hypermail 2.0.0 : Fri Aug 01 2008 - 15:18:23 EDT