FAQ
Where do I begin? :)

I have a few special data types that I've created ExtendedType classes for.
I'm checking out Cayenne 3.0M4 to see if it fixes a problem with an error
I've been getting: "Can't perform lookup. There is more than one ObjEntity
mapped to class ..."

I have multiple cayenne.xml files (is that the right way to describe what
I'm doing?) because there are several project libraries we have created,
and each use and manage their own Cayenne config. We have a framework where
new Cayenne maps get inserted into an existing Cayenne instance if one
already exists. It seems to work well most of the time. Sometimes there IS
some overlap where one library will access a table that the other library
accesses as well. Their classes are in different packages. Their short name
might be the same, though. My application runs under Tomcat, and sometimes
when it comes up it works fine, and sometimes when it comes up, I get the
error. If I restart the app enough, eventually I'll get it to start and run.
That's a scary place to be. This prompted my move to 3.0M4 which has a bug
fix for the EntityResolver, which I'm hoping eliminates this problem.

So, I'm testing my app, and I notice that my extended types are fine until I
try to access a field with an extended type through a relation. At that
point, it ignores the extended type and operates as though there were no
extended type registered. I had a similar problem in 2.0.3 where the IN
operator would ignore the extended data type (
http://www.nabble.com/ExtendedType-and-IN-operator-td13905838.html#a14040290).
I was instructed to upgrade to 3.0M2 to see if the problem still existed. I
opted for a workaround since, at the time, that was less scary than an
upgrade

I would like to work through getting the ExtendedType classes recognised in
3.0M4, unless there a way to fix the 2.0 problem.

TIA!,

CG

Search Discussions

  • Michael Gentry at Jul 31, 2008 at 4:39 pm
    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.

    On Thu, Jul 31, 2008 at 12:24 PM, Chris Gamache wrote:
    Where do I begin? :)

    I have a few special data types that I've created ExtendedType classes for.
    I'm checking out Cayenne 3.0M4 to see if it fixes a problem with an error
    I've been getting: "Can't perform lookup. There is more than one ObjEntity
    mapped to class ..."

    I have multiple cayenne.xml files (is that the right way to describe what
    I'm doing?) because there are several project libraries we have created,
    and each use and manage their own Cayenne config. We have a framework where
    new Cayenne maps get inserted into an existing Cayenne instance if one
    already exists. It seems to work well most of the time. Sometimes there IS
    some overlap where one library will access a table that the other library
    accesses as well. Their classes are in different packages. Their short name
    might be the same, though. My application runs under Tomcat, and sometimes
    when it comes up it works fine, and sometimes when it comes up, I get the
    error. If I restart the app enough, eventually I'll get it to start and run.
    That's a scary place to be. This prompted my move to 3.0M4 which has a bug
    fix for the EntityResolver, which I'm hoping eliminates this problem.

    So, I'm testing my app, and I notice that my extended types are fine until I
    try to access a field with an extended type through a relation. At that
    point, it ignores the extended type and operates as though there were no
    extended type registered. I had a similar problem in 2.0.3 where the IN
    operator would ignore the extended data type (
    http://www.nabble.com/ExtendedType-and-IN-operator-td13905838.html#a14040290).
    I was instructed to upgrade to 3.0M2 to see if the problem still existed. I
    opted for a workaround since, at the time, that was less scary than an
    upgrade

    I would like to work through getting the ExtendedType classes recognised in
    3.0M4, unless there a way to fix the 2.0 problem.

    TIA!,

    CG
  • Chris Gamache at Jul 31, 2008 at 5:14 pm

    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry 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...
  • Michael Gentry at Jul 31, 2008 at 6:35 pm
    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 wrote:
    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry 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...
  • Chris Gamache at Aug 1, 2008 at 3:55 am
    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 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 wrote:
    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
    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...
  • Chris Gamache at Aug 1, 2008 at 5:29 pm
    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 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 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 wrote:
    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
    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...
  • Michael Gentry at Aug 1, 2008 at 5:43 pm
    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 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 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 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 <cgamache@gmail.com>
    wrote:
    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
    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...
  • Chris Gamache at Aug 1, 2008 at 7:18 pm
    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 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 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 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 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 <cgamache@gmail.com>
    wrote:
    On Thu, Jul 31, 2008 at 12:38 PM, Michael Gentry
    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...
  • Chad Smith at Sep 19, 2008 at 10:40 pm
    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
  • Chad Smith at Sep 19, 2008 at 11:24 pm
    Never mind - it wasn't a reverse relationship problem.

    Chad
  • Andrus Adamchik at Aug 1, 2008 at 9:23 pm
    This code looks suspect. I am not sure that after it is run, dc ==
    Configuration.getSharedConfiguration(). Can you do something like this
    instead:

    DefaultConfiguration dc = new DefaultConfiguration(configuration);
    dc.addClassPath(classPath);
    Configuration.initializeSharedConfiguration(dc);

    Andrus
    On Jul 31, 2008, at 1:13 PM, Chris Gamache wrote:

    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();
    }
    }
  • Chris Gamache at Aug 4, 2008 at 7:14 pm

    On Fri, Aug 1, 2008 at 5:23 PM, Andrus Adamchik wrote:

    This code looks suspect. I am not sure that after it is run, dc ==
    Configuration.getSharedConfiguration(). Can you do something like this
    instead:

    DefaultConfiguration dc = new DefaultConfiguration(configuration);
    dc.addClassPath(classPath);
    Configuration.initializeSharedConfiguration(dc);
    That wipes my shared configuration each time a new library tries to
    instantiate Cayenne. I need to add to the already initialized Cayenne if
    Cayenne has been initialized, and the only way to determine if Cayenne has
    already been initialized (at least that I have found...) is to try to obtain
    the shared configuration first. If it hasn't been initialized then an
    exception is thrown and we branch to the initialization routines.

    This is important when library X uses Cayenne data classes mapped in both
    library Y and library Z. We can't have Z re-initalizing Cayenne after Y has
    already initialized and registered its mapped classes.

    Is there a better way to accomplish this task?
    Also, this doesn't address the issue of ExtendedTypes being ignored for
    elements retrieved using a relational fetch in 3.0M4...
  • Andrus Adamchik at Aug 4, 2008 at 7:22 pm

    On Aug 4, 2008, at 3:14 PM, Chris Gamache wrote:
    Also, this doesn't address the issue of ExtendedTypes being ignored
    for
    elements retrieved using a relational fetch in 3.0M4...
    It does if you install them in the COnfiguration instance that is not
    being used downstream. This is what I am trying to figure out.

    Andrus
  • Andrus Adamchik at Aug 4, 2008 at 7:33 pm

    On Aug 4, 2008, at 3:14 PM, Chris Gamache wrote:

    That wipes my shared configuration each time a new library tries to
    instantiate Cayenne. I need to add to the already initialized
    Cayenne if
    Cayenne has been initialized, and the only way to determine if
    Cayenne has
    already been initialized (at least that I have found...) is to try
    to obtain
    the shared configuration first. If it hasn't been initialized then an
    exception is thrown and we branch to the initialization routines.

    This is important when library X uses Cayenne data classes mapped in
    both
    library Y and library Z. We can't have Z re-initalizing Cayenne
    after Y has
    already initialized and registered its mapped classes.

    Sure, but can you doublecheck that the types are loaded in the right
    Configuration? I.e. after all libraries are loaded, can you grab the
    shared configuration and print the contents of the ExtendedTypeMap?

    [BTW, this is the area where Cayenne indeed requires some improvement.
    Support for multi-configuration stack (aka libraries) is coming in 3.0
    - I am working on it now.]

    Andrus
  • Chris Gamache at Aug 4, 2008 at 9:53 pm

    On Mon, Aug 4, 2008 at 3:32 PM, Andrus Adamchik wrote:
    Sure, but can you doublecheck that the types are loaded in the right
    Configuration? I.e. after all libraries are loaded, can you grab the shared
    configuration and print the contents of the ExtendedTypeMap?

    [BTW, this is the area where Cayenne indeed requires some improvement.
    Support for multi-configuration stack (aka libraries) is coming in 3.0 - I
    am working on it now.]
    I double checked the types, and they are indeed loaded. I wanted to create a
    set of test cases to illustrate the problem I'm having, and and in doing
    so I found that my cheese has been moved! :)

    Here are the test cases I created:

    private DataContext context;

    @Test
    public void testUser() {

    if(context == null){
    this.context = ContextCreator.makeContext();
    }
    UserTable user = null;
    Expression exp = ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
    "f7a3f9e2-e94b-4ff7-8b03-4e8549be07cb");
    SelectQuery select = new SelectQuery(UserTable.class, exp);
    user = (UserTable) DataObjectUtils.objectForQuery(context, select);
    if(user == null) throw new IllegalStateException("User not found for user
    f7a3f9e2-e94b-4ff7-8b03-4e8549be07cb");
    try {
    UUID userUuid = user.getUserUuid();
    } catch (ClassCastException e) {
    fail("Failed to retrieve userUuid.");
    return;
    }
    assertTrue(true);

    }
    @Test
    public void testCompany() {

    if(context == null){
    this.context = ContextCreator.makeContext();
    }
    CompanyTable company = null;
    Expression exp =
    ExpressionFactory.matchExp(CompanyTable.COMPANY_UUID_PROPERTY,
    "394fa90e-75a3-4dd1-9205-341409bcba4b");
    SelectQuery select = new SelectQuery(CompanyTable.class, exp);
    company = (CompanyTable) DataObjectUtils.objectForQuery(context, select);
    if(company == null) throw new IllegalStateException("Company not found
    for user 394fa90e-75a3-4dd1-9205-341409bcba4b");
    try {
    UUID companyUuid = company.getCompanyUuid();
    } catch (ClassCastException e) {
    fail("Failed to retrieve companyUuid.");
    return;
    }
    assertTrue(true);

    }

    @Test public void testCompanyFromUser() {
    if(context == null){
    this.context = ContextCreator.makeContext();
    }
    UserTable user = null;
    Expression exp = ExpressionFactory.matchExp(UserTable.USER_UUID_PROPERTY,
    "f7a3f9e2-e94b-4ff7-8b03-4e8549be07cb");
    SelectQuery select = new SelectQuery(UserTable.class, exp);
    user = (UserTable) DataObjectUtils.objectForQuery(context, select);
    if(user == null) throw new IllegalStateException("User not found for user
    f7a3f9e2-e94b-4ff7-8b03-4e8549be07cb");

    try {
    UUID userUuid = user.getUserUuid();
    } catch (ClassCastException e) {
    fail("Failed to retrieve userUuid.");
    return;
    }

    CompanyTable company = user.getToCompanyTable();

    try {
    UUID companyUuid = company.getCompanyUuid();
    } catch (ClassCastException e) {
    fail("Failed to retrieve companyUuid.");
    return;
    }
    assertTrue(true);

    }

    Test #1 and Test #2 fail with the same class cast exception until I remove
    this pair of relations from the config file:

    <db-relationship name="companyTable" source="company_balance_trans_locks"
    target="company_table" toMany="false">
    <db-attribute-pair source="company_uuid" target="company_uuid"/>
    </db-relationship>
    <db-relationship name="creditLocks" source="company_table"
    target="company_balance_trans_locks" toMany="true">
    <db-attribute-pair source="company_uuid" target="company_uuid"/>
    </db-relationship>
    <obj-relationship name="companyTable" source="CompanyBalanceTransLocks"
    target="CompanyTable" db-relationship-path="companyTable"/>
    <obj-relationship name="creditLocks" source="CompanyTable"
    target="CompanyBalanceTransLocks" db-relationship-path="creditLocks"/>
    Then the tests run fine. I'm still baffled, but for a different reason. Why
    would the presence of this relation cause the failure?

    Thank you for continuing to work through this with me.
  • Chris Gamache at Aug 4, 2008 at 9:56 pm

    On Mon, Aug 4, 2008 at 5:52 PM, Chris Gamache wrote:
    Test #1 and Test #2 fail with the same class cast exception until I
    remove this pair of relations from the config file:
    Correction: Test #2 and #3 fail, not #1 and #2. :) Details details!
  • Chris Gamache at Aug 6, 2008 at 5:51 pm
    Just a squeak from the wheel here.

    I'd create a bug report, but I'm not sure how to describe it...

    Join on ExtendedType invalidates ExtendedType when retrieving rows in parent
    table using SelectQuery ??
    That's one idea I have. Please advise.
    On Mon, Aug 4, 2008 at 5:55 PM, Chris Gamache wrote:


    On Mon, Aug 4, 2008 at 5:52 PM, Chris Gamache wrote:


    Test #1 and Test #2 fail with the same class cast exception until I
    remove this pair of relations from the config file:
    Correction: Test #2 and #3 fail, not #1 and #2. :) Details details!
  • Andrus Adamchik at Aug 6, 2008 at 5:54 pm
    Hi Chris,

    Since I haven't got nowhere near the cause yet, I can't suggest a good
    name either. What's important is that you add steps to reproduce it.
    Call it anything you feel like.

    Thanks,
    Andrus
    On Aug 6, 2008, at 1:51 PM, Chris Gamache wrote:

    Just a squeak from the wheel here.

    I'd create a bug report, but I'm not sure how to describe it...

    Join on ExtendedType invalidates ExtendedType when retrieving rows
    in parent
    table using SelectQuery ??
    That's one idea I have. Please advise.
    On Mon, Aug 4, 2008 at 5:55 PM, Chris Gamache wrote:



    On Mon, Aug 4, 2008 at 5:52 PM, Chris Gamache <cgamache@gmail.com>
    wrote:
    Test #1 and Test #2 fail with the same class cast exception until I
    remove this pair of relations from the config file:
    Correction: Test #2 and #3 fail, not #1 and #2. :) Details details!
  • Chris Gamache at Aug 7, 2008 at 2:28 pm
    Okay, I have created the bug with the proposed title. I have a eclipse
    project with a JUnit test which demonstrates the problem which I can send to
    you if that will assist you in finding the problem.
    On Wed, Aug 6, 2008 at 1:54 PM, Andrus Adamchik wrote:

    Hi Chris,

    Since I haven't got nowhere near the cause yet, I can't suggest a good name
    either. What's important is that you add steps to reproduce it. Call it
    anything you feel like.

    Thanks,
    Andrus


    On Aug 6, 2008, at 1:51 PM, Chris Gamache wrote:

    Just a squeak from the wheel here.
    I'd create a bug report, but I'm not sure how to describe it...

    Join on ExtendedType invalidates ExtendedType when retrieving rows in
    parent
    table using SelectQuery ??
    That's one idea I have. Please advise.
    On Mon, Aug 4, 2008 at 5:55 PM, Chris Gamache wrote:

    On Mon, Aug 4, 2008 at 5:52 PM, Chris Gamache <cgamache@gmail.com>
    wrote:

    Test #1 and Test #2 fail with the same class cast exception until I
    remove this pair of relations from the config file:
    Correction: Test #2 and #3 fail, not #1 and #2. :) Details details!
  • Andrus Adamchik at Aug 7, 2008 at 2:30 pm

    On Aug 7, 2008, at 10:27 AM, Chris Gamache wrote:

    Okay, I have created the bug with the proposed title. Thanks!
    I have a eclipse
    project with a JUnit test which demonstrates the problem which I can
    send to
    you if that will assist you in finding the problem.
    That would help. You can either attach it to Jira or send it directly
    to me if you don't want it publicly exposed.

    Andrus
  • Michael Gentry at Aug 7, 2008 at 4:14 pm
    I'd like to see it, too, so if you can attach to Jira, that would be great.
    On Thu, Aug 7, 2008 at 10:29 AM, Andrus Adamchik wrote:
    On Aug 7, 2008, at 10:27 AM, Chris Gamache wrote:

    Okay, I have created the bug with the proposed title. Thanks!
    I have a eclipse
    project with a JUnit test which demonstrates the problem which I can send
    to
    you if that will assist you in finding the problem.
    That would help. You can either attach it to Jira or send it directly to me
    if you don't want it publicly exposed.

    Andrus

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupuser @
categoriescayenne
postedJul 31, '08 at 4:24p
activeSep 19, '08 at 11:24p
posts21
users4
websitecayenne.apache.org

People

Translate

site design / logo © 2022 Grokbase