Return-Path: X-Original-To: apmail-db-general-archive@www.apache.org Delivered-To: apmail-db-general-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 641E610ACD for ; Sun, 5 Jan 2014 10:11:05 +0000 (UTC) Received: (qmail 34682 invoked by uid 500); 5 Jan 2014 10:09:44 -0000 Delivered-To: apmail-db-general-archive@db.apache.org Received: (qmail 34380 invoked by uid 500); 5 Jan 2014 10:09:27 -0000 Mailing-List: contact general-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: general@db.apache.org List-Id: Delivered-To: mailing list general@db.apache.org Received: (qmail 34309 invoked by uid 99); 5 Jan 2014 10:09:16 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 05 Jan 2014 10:09:16 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 05 Jan 2014 10:09:09 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7C3DF23889E3 for ; Sun, 5 Jan 2014 10:08:49 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r892842 [3/15] - in /websites/production/db/content/jdo: ./ guides/ releases/ Date: Sun, 05 Jan 2014 10:08:46 -0000 To: general@db.apache.org From: andyj@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140105100849.7C3DF23889E3@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: websites/production/db/content/jdo/attach_detach.html ============================================================================== --- websites/production/db/content/jdo/attach_detach.html (original) +++ websites/production/db/content/jdo/attach_detach.html Sun Jan 5 10:08:45 2014 @@ -1,5 +1,5 @@ - + @@ -11,7 +11,7 @@ @import url("./css/site.css"); - + @@ -101,7 +101,7 @@
  • Types of Fields
  • -
  • @@ -209,235 +209,235 @@
    - - -

    JDO Attach/Detach

    -

    - JDO provides an interface to the persistence of objects. JDO 1.0 doesn't provide a way of taking - an object that was just persisted and just work on it and update the persisted object later. - The user has to copy the fields manually and copy them back to the persisted object later. - JDO 2.0 introduces a new way of handling this situation, by detaching an object from the - persistence graph, allowing it to be worked on in the users application. It can then be - attached to the persistence graph later. - Please refer to Object Lifecycle for where this fits in. - The first thing to do to use a class with this facility is to tag it as "detachable". - This is done by adding the attribute -

    -
    <class name="MyClass" detachable="true">
    -

    - This acts as an instruction to the enhancement process to add - methods necessary to utilise the attach/detach process. -

    - -

    - The following code fragment highlights how to use the attach/detach mechanism -

    -
    -Product working_product=null;
    -Transaction tx=pm.currentTransaction();
    -try
    -{
    -    tx.begin();
    -
    -    Product prod=new Product(name,description,price);
    -    pm.makePersistent(prod);
    -
    -    // Detach the product for use
    -    working_product = (Product)pm.detachCopy(prod);
    -
    -    tx.commit();
    -}
    -catch (Exception e)
    -{
    -    // Handle the exception
    -}
    -finally
    -{
    -    if (tx.isActive())
    -    {
    -        tx.rollback();
    -    }
    -}
    -
    -// Work on the detached object in our application
    -working_product.setPrice(new_price);
    -
    -...
    -
    -// Reattach the updated object
    -tx = pm.currentTransaction();
    -try
    -{
    -    tx.begin();
    -
    -    Product attached_product = pm.makePersistent(working_product);
    -
    -    tx.commit();
    -}
    -catch (Exception e)
    -{
    -    // Handle the exception
    -}
    -finally
    -{
    -    if (tx.isActive())
    -    {
    -        tx.rollback();
    -    }
    -}
    -

    - So we now don't need to do any manual copying of object fields just using a simple call to - detach the object, and then attach it again later. Here are a few things to note with - attach/detach :- -

    -
      -
    • Calling detachCopy on an object that is not detachable will return a transient - instance that is a COPY of the original, so use the COPY thereafter.
    • -
    • Calling detachCopy on an object that is detachable will return a detached - instance that is a COPY of the original, so use this COPY thereafter
    • -
    • A detached object retain the id of its datastore entity. Detached objects should be used - where you want to update the objects and attach them later (updating the associated object in the - datastore. If you want to create copies of the objects in the datastore with their own identities - you should use makeTransient instead of detachCopy.
    • -
    • Calling detachCopy will detach all fields of that object that are in the current - Fetch Group for that class for that PersistenceManager.
    • -
    • By default the fields of the object that will be detached are those in the Default Fetch Group.
    • -
    • You should choose your Fetch Group carefully, bearing in mind which - object(s) you want to access whilst detached. Detaching a relation field will detach the related object - as well.
    • -
    • If you don't detach a field of an object, you cannot access the value for that field while - the object is detached.
    • -
    • If you don't detach a field of an object, you can update the value for that field while detached, - and thereafter you can access the value for that field.
    • -
    • Calling makePersistent will return an (attached) copy of the detached object. It will attach all fields that - were originally detached, and will also attach any other fields that were modified whilst detached.
    • -
    - - -

    Detach All On Commit

    -

    - JDO2 also provides a mechanism whereby all objects that were enlisted in a transaction are - automatically detached when the transaction is committed. You can enable this in one of 3 ways. - If you want to use this mode globally for all PersistenceManagers (PMs) from a - PersistenceManagerFactory (PMF) you could either set the PMF property - "datanucleus.DetachAllOnCommit", or you could create your PMF and call the PMF method - setDetachAllOnCommit(true). If instead you wanted to use this mode only for a particular - PM, or only for a particular transaction for a particular PM, then you can call the PM method - setDetachAllOnCommit(true) before the commit of the transaction, and it will apply for all - transaction commits thereafter, until turned off (setDetachAllOnCommit(false). - Here's an example -

    -
    -// Create a PMF
    -...
    -
    -// Create an object
    -MyObject my = new MyObject();
    -
    -PersistenceManager pm = pmf.getPersistenceManager();
    -Transaction tx = pm.currentTransaction();
    -try
    -{
    -    tx.begin();
    -
    -    // We want our object to be detached when it's been persisted
    -    pm.setDetachAllOnCommit(true);
    -
    -    // Persist the object that we created earlier
    -    pm.makePersistent(my);
    -
    -    tx.commit();
    -    // The object "my" is now in detached state and can be used further
    -}
    -finally
    -{
    -    if (tx.isActive)
    -    {
    -        tx.rollback();
    -    }
    -}
    -
    -
    - - -

    Copy On Attach

    -

    - By default when you are attaching a detached object it will return an attached copy - of the detached object. JDO2.1 provides a new feature that allows this attachment to - just migrate the existing detached object into attached state. -

    -

    - You enable this by setting the PersistenceManagerFactory (PMF) property - datanucleus.CopyOnAttach to false. Alternatively you can use the methods - PersistenceManagerFactory.setCopyOnAttach(boolean flag) or - PersistenceManager.setCopyOnAttach(boolean flag). - If we return to the example at the start of this page, this now becomes -

    -
    -// Reattach the updated object
    -pm.setCopyOnAttach(false);
    -tx = pm.currentTransaction();
    -try
    -{
    -    tx.begin();
    -
    -    // working product is currently in detached state
    -
    -    pm.makePersistent(working_product);
    -    // working_product is now in persistent (attached) state
    -
    -    tx.commit();
    -}
    -catch (Exception e)
    -{
    -    // Handle the exception
    -}
    -finally
    -{
    -    if (tx.isActive())
    -    {
    -        tx.rollback();
    -    }
    -}
    -

    - Please note that if you try to attach two detached objects representing the same underlying - persistent object within the same transaction (i.e a persistent object with the same identity - already exists in the level 1 cache), then a JDOUserException will be thrown. -

    -
    -
    - -

    Serialization of Detachable classes

    -

    - During enhancement of Detachable classes, a field called jdoDetachedState is added to - the class definition. This field allows reading and changing tracking of detached objects - while they are not managed by a PersistenceManager. -

    -

    - When serialization occurs on a Detachable object, the jdoDetachedState field is written - to the serialized object stream. On deserialize, this field is written back to the new - deserialized instance. This process occurs transparently to the application. However, if - deserialization occurs with an un-enhanced version of the class, the detached state is lost. -

    -

    - Serialization and deserialization of Detachable classes and un-enhanced versions of the same - class is only possible if the field serialVersionUID is added. It's recommended during - development of the class, to define the serialVersionUID and make the class to implement - the java.io.Serializable interface, as the following example: -

    -
    -class MyClass implements java.io.Serializable
    -{
    -    private static final long serialVersionUID = 2765740961462495537L; // any random value here
    -    
    -    //.... other fields
    -}
    -
    -
    -
    -
    - - + + +

    JDO Attach/Detach

    +

    + JDO provides an interface to the persistence of objects. JDO 1.0 doesn't provide a way of taking + an object that was just persisted and just work on it and update the persisted object later. + The user has to copy the fields manually and copy them back to the persisted object later. + JDO 2.0 introduces a new way of handling this situation, by detaching an object from the + persistence graph, allowing it to be worked on in the users application. It can then be + attached to the persistence graph later. + Please refer to Object Lifecycle for where this fits in. + The first thing to do to use a class with this facility is to tag it as "detachable". + This is done by adding the attribute +

    +
    <class name="MyClass" detachable="true">
    +

    + This acts as an instruction to the enhancement process to add + methods necessary to utilise the attach/detach process. +

    + +

    + The following code fragment highlights how to use the attach/detach mechanism +

    +
    +Product working_product=null;
    +Transaction tx=pm.currentTransaction();
    +try
    +{
    +    tx.begin();
    +
    +    Product prod=new Product(name,description,price);
    +    pm.makePersistent(prod);
    +
    +    // Detach the product for use
    +    working_product = (Product)pm.detachCopy(prod);
    +
    +    tx.commit();
    +}
    +catch (Exception e)
    +{
    +    // Handle the exception
    +}
    +finally
    +{
    +    if (tx.isActive())
    +    {
    +        tx.rollback();
    +    }
    +}
    +
    +// Work on the detached object in our application
    +working_product.setPrice(new_price);
    +
    +...
    +
    +// Reattach the updated object
    +tx = pm.currentTransaction();
    +try
    +{
    +    tx.begin();
    +
    +    Product attached_product = pm.makePersistent(working_product);
    +
    +    tx.commit();
    +}
    +catch (Exception e)
    +{
    +    // Handle the exception
    +}
    +finally
    +{
    +    if (tx.isActive())
    +    {
    +        tx.rollback();
    +    }
    +}
    +

    + So we now don't need to do any manual copying of object fields just using a simple call to + detach the object, and then attach it again later. Here are a few things to note with + attach/detach :- +

    +
      +
    • Calling detachCopy on an object that is not detachable will return a transient + instance that is a COPY of the original, so use the COPY thereafter.
    • +
    • Calling detachCopy on an object that is detachable will return a detached + instance that is a COPY of the original, so use this COPY thereafter
    • +
    • A detached object retain the id of its datastore entity. Detached objects should be used + where you want to update the objects and attach them later (updating the associated object in the + datastore. If you want to create copies of the objects in the datastore with their own identities + you should use makeTransient instead of detachCopy.
    • +
    • Calling detachCopy will detach all fields of that object that are in the current + Fetch Group for that class for that PersistenceManager.
    • +
    • By default the fields of the object that will be detached are those in the Default Fetch Group.
    • +
    • You should choose your Fetch Group carefully, bearing in mind which + object(s) you want to access whilst detached. Detaching a relation field will detach the related object + as well.
    • +
    • If you don't detach a field of an object, you cannot access the value for that field while + the object is detached.
    • +
    • If you don't detach a field of an object, you can update the value for that field while detached, + and thereafter you can access the value for that field.
    • +
    • Calling makePersistent will return an (attached) copy of the detached object. It will attach all fields that + were originally detached, and will also attach any other fields that were modified whilst detached.
    • +
    + + +

    Detach All On Commit

    +

    + JDO2 also provides a mechanism whereby all objects that were enlisted in a transaction are + automatically detached when the transaction is committed. You can enable this in one of 3 ways. + If you want to use this mode globally for all PersistenceManagers (PMs) from a + PersistenceManagerFactory (PMF) you could either set the PMF property + "datanucleus.DetachAllOnCommit", or you could create your PMF and call the PMF method + setDetachAllOnCommit(true). If instead you wanted to use this mode only for a particular + PM, or only for a particular transaction for a particular PM, then you can call the PM method + setDetachAllOnCommit(true) before the commit of the transaction, and it will apply for all + transaction commits thereafter, until turned off (setDetachAllOnCommit(false). + Here's an example +

    +
    +// Create a PMF
    +...
    +
    +// Create an object
    +MyObject my = new MyObject();
    +
    +PersistenceManager pm = pmf.getPersistenceManager();
    +Transaction tx = pm.currentTransaction();
    +try
    +{
    +    tx.begin();
    +
    +    // We want our object to be detached when it's been persisted
    +    pm.setDetachAllOnCommit(true);
    +
    +    // Persist the object that we created earlier
    +    pm.makePersistent(my);
    +
    +    tx.commit();
    +    // The object "my" is now in detached state and can be used further
    +}
    +finally
    +{
    +    if (tx.isActive)
    +    {
    +        tx.rollback();
    +    }
    +}
    +
    +
    + + +

    Copy On Attach

    +

    + By default when you are attaching a detached object it will return an attached copy + of the detached object. JDO2.1 provides a new feature that allows this attachment to + just migrate the existing detached object into attached state. +

    +

    + You enable this by setting the PersistenceManagerFactory (PMF) property + datanucleus.CopyOnAttach to false. Alternatively you can use the methods + PersistenceManagerFactory.setCopyOnAttach(boolean flag) or + PersistenceManager.setCopyOnAttach(boolean flag). + If we return to the example at the start of this page, this now becomes +

    +
    +// Reattach the updated object
    +pm.setCopyOnAttach(false);
    +tx = pm.currentTransaction();
    +try
    +{
    +    tx.begin();
    +
    +    // working product is currently in detached state
    +
    +    pm.makePersistent(working_product);
    +    // working_product is now in persistent (attached) state
    +
    +    tx.commit();
    +}
    +catch (Exception e)
    +{
    +    // Handle the exception
    +}
    +finally
    +{
    +    if (tx.isActive())
    +    {
    +        tx.rollback();
    +    }
    +}
    +

    + Please note that if you try to attach two detached objects representing the same underlying + persistent object within the same transaction (i.e a persistent object with the same identity + already exists in the level 1 cache), then a JDOUserException will be thrown. +

    +
    +
    + +

    Serialization of Detachable classes

    +

    + During enhancement of Detachable classes, a field called jdoDetachedState is added to + the class definition. This field allows reading and changing tracking of detached objects + while they are not managed by a PersistenceManager. +

    +

    + When serialization occurs on a Detachable object, the jdoDetachedState field is written + to the serialized object stream. On deserialize, this field is written back to the new + deserialized instance. This process occurs transparently to the application. However, if + deserialization occurs with an un-enhanced version of the class, the detached state is lost. +

    +

    + Serialization and deserialization of Detachable classes and un-enhanced versions of the same + class is only possible if the field serialVersionUID is added. It's recommended during + development of the class, to define the serialVersionUID and make the class to implement + the java.io.Serializable interface, as the following example: +

    +
    +class MyClass implements java.io.Serializable
    +{
    +    private static final long serialVersionUID = 2765740961462495537L; // any random value here
    +    
    +    //.... other fields
    +}
    +
    +
    +
    +
    + +
    @@ -446,7 +446,7 @@ class MyClass implements java.io.Seriali
  • Types of Fields
  • -
  • @@ -209,64 +209,64 @@
    - - -

    JDO Class Types

    -

    - JDO provides a means of transparent persistence of objects of user defined classes. With JDO there are actually - 3 types of classes. -

    -
      -
    • Persistence Capable classes are classes whose instances can be persisted to a datastore. JDO provide the - mechanism for persisting these instances, and they are core to JDO. These classes need to be enhanced - according to a JDO Meta-Data specification before use within a JDO environment.
    • -
    • Persistence Aware classes are classes that manipulate Persistence Capable instances through direct attribute - manipulation. These classes are typically enhanced with very minimal JDO Meta-Data. The enhancement process performs very - little changes to these classes.
    • -
    • Normal classes are classes that aren't themselves persistable, and have no knowledge of persistence either. - These classes are totally unchanged in JDO, and require no JDO Meta-Data whatsoever.
    • -
    - -

    PersistenceCapable

    -

    - Classes are defined as PersistenceCapable either by XML MetaData, like this -

    -
    -<class name="MyClass">
    -    ...
    -</class>
    -

    - or, in JDO2.1, using Annotations. Like this -

    -
    -@PersistenceCapable
    -public class MyClass
    -{
    -    ...
    -}
    -
    -
    - -

    PersistenceAware

    -

    - Classes are defined as PersistenceAware either by XML MetaData, like this -

    -
    -<class name="MyClass" persistence-modifier="persistence-aware"/>
    -

    - or, in JDO2.1, using Annotations. Like this -

    -
    -@PersistenceAware
    -public class MyClass
    -{
    -    ...
    -}
    -
    -
    -
    - - + + +

    JDO Class Types

    +

    + JDO provides a means of transparent persistence of objects of user defined classes. With JDO there are actually + 3 types of classes. +

    +
      +
    • Persistence Capable classes are classes whose instances can be persisted to a datastore. JDO provide the + mechanism for persisting these instances, and they are core to JDO. These classes need to be enhanced + according to a JDO Meta-Data specification before use within a JDO environment.
    • +
    • Persistence Aware classes are classes that manipulate Persistence Capable instances through direct attribute + manipulation. These classes are typically enhanced with very minimal JDO Meta-Data. The enhancement process performs very + little changes to these classes.
    • +
    • Normal classes are classes that aren't themselves persistable, and have no knowledge of persistence either. + These classes are totally unchanged in JDO, and require no JDO Meta-Data whatsoever.
    • +
    + +

    PersistenceCapable

    +

    + Classes are defined as PersistenceCapable either by XML MetaData, like this +

    +
    +<class name="MyClass">
    +    ...
    +</class>
    +

    + or, in JDO2.1, using Annotations. Like this +

    +
    +@PersistenceCapable
    +public class MyClass
    +{
    +    ...
    +}
    +
    +
    + +

    PersistenceAware

    +

    + Classes are defined as PersistenceAware either by XML MetaData, like this +

    +
    +<class name="MyClass" persistence-modifier="persistence-aware"/>
    +

    + or, in JDO2.1, using Annotations. Like this +

    +
    +@PersistenceAware
    +public class MyClass
    +{
    +    ...
    +}
    +
    +
    +
    + +
    @@ -275,7 +275,7 @@ public class MyClass
  • Types of Fields
  • -
  • @@ -210,80 +210,80 @@
    - - -

    The Apache JDO Project

    - -

    - Apache JDO is a sub-project of the Apache DB TLP. It includes two major areas: -

    -
      -
    • -JDO 1, Java Specification Request 12, API, Reference Implementation, and -Technology Compatibility Kit. -
    • -
    • -JDO 2, Java Specification Request 243, API, and Technology Compatibility Kit. -The Reference Implementation is being developed in parallel by JPOX. -
    • -
    - -

    - The common external dependencies of JDO include the tools used to build and test it: -

    - -
      -
    • Subversion
    • -
    • Maven
    • -
    • Ant
    • -
    • JUnit
    • -
    - -

    - Other external dependencies of JDO are subproject-specific: -

    - -
      -
    • JDO 2.0 API -
        -
      • Java Transaction API
      • -
      -
    • -
    • JDO 2.0 TCK -
        -
      • Java Transaction API
      • -
      • Jakarta Commons Logging
      • -
      • Log4j
      • -
      • Apache Derby
      • -
      • Spring Framework Core
      • -
      • JPOX -
          -
        • ASM
        • -
        • Source Forge c3p0
        • -
        • Commons DBCP
        • -
        • Commons Pool
        • -
        • Commons Collections
        • -
        -
      • -
      -
    • -
    -
    - - + + +

    The Apache JDO Project

    + +

    + Apache JDO is a sub-project of the Apache DB TLP. It includes two major areas: +

    +
      +
    • +JDO 1, Java Specification Request 12, API, Reference Implementation, and +Technology Compatibility Kit. +
    • +
    • +JDO 2, Java Specification Request 243, API, and Technology Compatibility Kit. +The Reference Implementation is being developed in parallel by JPOX. +
    • +
    + +

    + The common external dependencies of JDO include the tools used to build and test it: +

    + +
      +
    • Subversion
    • +
    • Maven
    • +
    • Ant
    • +
    • JUnit
    • +
    + +

    + Other external dependencies of JDO are subproject-specific: +

    + +
      +
    • JDO 2.0 API +
        +
      • Java Transaction API
      • +
      +
    • +
    • JDO 2.0 TCK +
        +
      • Java Transaction API
      • +
      • Jakarta Commons Logging
      • +
      • Log4j
      • +
      • Apache Derby
      • +
      • Spring Framework Core
      • +
      • JPOX +
          +
        • ASM
        • +
        • Source Forge c3p0
        • +
        • Commons DBCP
        • +
        • Commons Pool
        • +
        • Commons Collections
        • +
        +
      • +
      +
    • +
    +
    + +
    @@ -292,7 +292,7 @@ The Reference Implementation is being de
  • Types of Fields
  • -
  • @@ -210,116 +210,116 @@
    - - -

    Latest Official Release

    -

    - JDO 3.1-rc1 - - September 22, 2013 -

    -
    - -

    Previous Official Releases

    -

    - JDO 3.0.1 - - November 13, 2011 -

    -

    - JDO 3.0 - - July 23, 2010 -

    -

    - JDO 2.2 - - October 24, 2008 -

    -

    - JDO 2.1.1 - - August 29, 2008 -

    -

    - JDO 2.1 - - March 17, 2008 -

    -

    - JDO 2.0 - - May 1, 2006 -

    - -
    - -

    About JDO Releases

    -

    - A release of JDO includes the JDO API and the - Technology Compatibility Kit (TCK). - The TCK is available only in source form. The API - project is available as source and binary, and as raw jar files. -

    -
      -
    • - The api project contains source to build jdo-api.jar. - The jar file is the only artifact needed for users who wish to compile - their programs using the JDO API. - It can be downloaded automatically by maven and placed into the local - maven repository if you include the - proper dependency in your maven project definition. - Use groupId javax.jdo, artifactId jdo-api, version 3.0, - and define your remote repository as - http://www.ibiblio.org/maven. - Alternatively, it can be downloaded manually and put into a location - of your choice. -
    • -
    • - The tck project contains the JDO Technology Compatibility Kit. - The source distribution is the only artifact needed to be downloaded - by the user. -
    • -
    -

    - All are available for download as source, but if you wish - to run the TCK you need only download the TCK project. - The dependencies will be automatically downloaded by maven - as jar files. -

    -

    - For information on running the TCK, see TCK. - If downloading multiple source packages, extract them all - into the same directory. This will preserve the source - dependencies among the projects. -

    -

    - See Source Code Version Control for information about downloading the latest source code for all of the JDO projects. -

    -
    - + + +

    Latest Official Release

    +

    + JDO 3.1-rc1 + + September 22, 2013 +

    +
    + +

    Previous Official Releases

    +

    + JDO 3.0.1 + + November 13, 2011 +

    +

    + JDO 3.0 + + July 23, 2010 +

    +

    + JDO 2.2 + + October 24, 2008 +

    +

    + JDO 2.1.1 + + August 29, 2008 +

    +

    + JDO 2.1 + + March 17, 2008 +

    +

    + JDO 2.0 + + May 1, 2006 +

    + +
    + +

    About JDO Releases

    +

    + A release of JDO includes the JDO API and the + Technology Compatibility Kit (TCK). + The TCK is available only in source form. The API + project is available as source and binary, and as raw jar files. +

    +
      +
    • + The api project contains source to build jdo-api.jar. + The jar file is the only artifact needed for users who wish to compile + their programs using the JDO API. + It can be downloaded automatically by maven and placed into the local + maven repository if you include the + proper dependency in your maven project definition. + Use groupId javax.jdo, artifactId jdo-api, version 3.0, + and define your remote repository as + http://www.ibiblio.org/maven. + Alternatively, it can be downloaded manually and put into a location + of your choice. +
    • +
    • + The tck project contains the JDO Technology Compatibility Kit. + The source distribution is the only artifact needed to be downloaded + by the user. +
    • +
    +

    + All are available for download as source, but if you wish + to run the TCK you need only download the TCK project. + The dependencies will be automatically downloaded by maven + as jar files. +

    +

    + For information on running the TCK, see TCK. + If downloading multiple source packages, extract them all + into the same directory. This will preserve the source + dependencies among the projects. +

    +

    + See Source Code Version Control for information about downloading the latest source code for all of the JDO projects. +

    +
    +
    @@ -328,7 +328,7 @@ Jan 24, 2006
  • Types of Fields
  • -
  • @@ -209,558 +209,558 @@
    - - -

    JDO Enhancement

    -

    - JDO defines a byte-code enhancement process that provides for dirty detection of fields. - Before a class is used at runtime it is compiled and then "enhanced" to implement the interface - PersistenceCapable, and optionally also Detachable. -

    -

    - We can demonstrate this by taking a sample class, and seeing it before and after enhancement. - We start with the following class -

    -
    -package org.apache.jdo.test;
    -
    -public class A
    -{
    -    long id;
    -    String name;
    -    B b;
    -
    -    public A(String name)
    -    {
    -        this.name = name;
    -    }
    -
    -    public void setId(long id)
    -    {
    -        this.id = id;
    -    }
    -
    -    public void setB(B b)
    -    {
    -        this.b = b;
    -    }
    -
    -    public String getName()
    -    {
    -        return name;
    -    }
    -
    -    public B getB()
    -    {
    -        return b;
    -    }
    -
    -    public long getId()
    -    {
    -        return id;
    -    }
    -
    -    public String toString()
    -    {
    -        return "A : id=" + id + " [" + name + "] b=\"" + b + "\"";
    -    }
    -}
    -

    - and require it to be PersistenceCapable and Detachable. - The enhancement process needs to intercept all updates of the fields of the class (id, name, b) as well - as add on the necessary PersistenceCapable, Detachable methods. - After "enhancement" it becomes -

    -
    -package org.apache.jdo.test;
    -import java.util.BitSet;
    -
    -import javax.jdo.JDODetachedFieldAccessException;
    -import javax.jdo.JDOFatalInternalException;
    -import javax.jdo.PersistenceManager;
    -import javax.jdo.identity.LongIdentity;
    -import javax.jdo.spi.Detachable;
    -import javax.jdo.spi.JDOImplHelper;
    -import javax.jdo.spi.JDOPermission;
    -import javax.jdo.spi.PersistenceCapable;
    -import javax.jdo.spi.StateManager;
    -
    -public class A implements PersistenceCapable, Detachable
    -{
    -    long id;
    -    String name;
    -    B b;
    -    protected transient StateManager jdoStateManager;
    -    protected transient byte jdoFlags;
    -    protected Object[] jdoDetachedState;
    -    private static final byte[] jdoFieldFlags;
    -    private static final Class jdoPersistenceCapableSuperclass;
    -    private static final Class[] jdoFieldTypes;
    -    private static final String[] jdoFieldNames = __jdoFieldNamesInit();
    -    private static final int jdoInheritedFieldCount;
    -
    -    static
    -    {
    -        jdoFieldTypes = __jdoFieldTypesInit();
    -        jdoFieldFlags = __jdoFieldFlagsInit();
    -        jdoInheritedFieldCount = __jdoGetInheritedFieldCount();
    -        jdoPersistenceCapableSuperclass = __jdoPersistenceCapableSuperclassInit();
    -        JDOImplHelper.registerClass(___jdo$loadClass("org.apache.jdo.test.A"),
    -                    jdoFieldNames, jdoFieldTypes,
    -                    jdoFieldFlags,
    -                    jdoPersistenceCapableSuperclass, new A());
    -    }
    -    
    -    public void setId(long id)
    -    {
    -        jdoSetid(this, id);
    -    }
    -    
    -    public void setB(B b)
    -    {
    -        jdoSetb(this, b);
    -    }
    -    
    -    public String getName()
    -    {
    -        return jdoGetname(this);
    -    }
    -    
    -    public B getB()
    -    {
    -        return jdoGetb(this);
    -    }
    -    
    -    public long getId()
    -    {
    -        return jdoGetid(this);
    -    }
    -    
    -    public String toString()
    -    {
    -        return new StringBuilder().append("A : id=").append(jdoGetid(this))
    -           .append(" [").append(jdoGetname(this))
    -           .append("] b=\"").append(jdoGetb(this))
    -           .append("\"").toString();
    -    }
    -
    -    public void jdoCopyKeyFieldsFromObjectId(PersistenceCapable.ObjectIdFieldConsumer fc, Object oid)
    -    {
    -        if (fc == null)
    -            throw new IllegalArgumentException
    -              ("ObjectIdFieldConsumer is null");
    -        if (!(oid instanceof LongIdentity))
    -            throw new ClassCastException
    -              ("oid is not instanceof javax.jdo.identity.LongIdentity");
    -        LongIdentity o = (LongIdentity) oid;
    -        fc.storeLongField(1, o.getKey());
    -    }
    -    
    -    protected void jdoCopyKeyFieldsFromObjectId(Object oid)
    -    {
    -        if (!(oid instanceof LongIdentity))
    -            throw new ClassCastException
    -              ("key class is not javax.jdo.identity.LongIdentity or null");
    -        LongIdentity o = (LongIdentity) oid;
    -        id = o.getKey();
    -    }
    -    
    -    public final void jdoCopyKeyFieldsToObjectId(Object oid)
    -    {
    -        throw new JDOFatalInternalException
    -          ("It's illegal to call jdoCopyKeyFieldsToObjectId for a class with Single Field Identity.");
    -    }
    -    
    -    public final void jdoCopyKeyFieldsToObjectId
    -    (PersistenceCapable.ObjectIdFieldSupplier fs, Object oid) {
    -    throw new JDOFatalInternalException
    -          ("It's illegal to call jdoCopyKeyFieldsToObjectId for a class with Single Field Identity.");
    -    }
    -    
    -    public final Object jdoGetObjectId()
    -    {
    -        if (jdoStateManager != null)
    -            return jdoStateManager.getObjectId(this);
    -        if (this.jdoIsDetached() != true)
    -            return null;
    -        return jdoDetachedState[0];
    -    }
    -    
    -    public final Object jdoGetVersion()
    -    {
    -        if (jdoStateManager != null)
    -            return jdoStateManager.getVersion(this);
    -        if (this.jdoIsDetached() != true)
    -            return null;
    -        return jdoDetachedState[1];
    -    }
    -    
    -    protected final void jdoPreSerialize()
    -    {
    -        if (jdoStateManager != null)
    -            jdoStateManager.preSerialize(this);
    -    }
    -    
    -    public final PersistenceManager jdoGetPersistenceManager()
    -    {
    -        return (jdoStateManager != null
    -            ? jdoStateManager.getPersistenceManager(this) : null);
    -    }
    -    
    -    public final Object jdoGetTransactionalObjectId() 
    -    {
    -        return (jdoStateManager != null
    -           ? jdoStateManager.getTransactionalObjectId(this) : null);
    -    }
    -    
    -    public final boolean jdoIsDeleted()
    -    {
    -        return (jdoStateManager != null ? jdoStateManager.isDeleted(this): false);
    -    }
    -    
    -    public final boolean jdoIsDirty()
    -    {
    -        if (jdoStateManager != null)
    -            return jdoStateManager.isDirty(this);
    -        if (this.jdoIsDetached() != true)
    -            return false;
    -        if (((BitSet) jdoDetachedState[3]).length() <= 0)
    -            return false;
    -        return true;
    -    }
    -    
    -    public final boolean jdoIsNew()
    -    {
    -        return jdoStateManager != null ? jdoStateManager.isNew(this) : false;
    -    }
    -    
    -    public final boolean jdoIsPersistent()
    -    {
    -        return (jdoStateManager != null ? jdoStateManager.isPersistent(this): false);
    -    }
    -    
    -    public final boolean jdoIsTransactional()
    -    {
    -        return (jdoStateManager != null ? jdoStateManager.isTransactional(this): false);
    -    }
    -    
    -    public final boolean jdoIsDetached()
    -    {
    -        if (jdoStateManager == null) {
    -            if (jdoDetachedState == null)
    -                return false;
    -            return true;
    -        }
    -        return false;
    -    }
    -    
    -    public final void jdoMakeDirty(String fieldName)
    -    {
    -        if (jdoStateManager != null)
    -            jdoStateManager.makeDirty(this, fieldName);
    -    }
    -    
    -    public final Object jdoNewObjectIdInstance() 
    -    {
    -        return new LongIdentity(getClass(), id);
    -    }
    -    
    -    public final Object jdoNewObjectIdInstance(Object key) 
    -    {
    -        if (key == null)
    -            throw new IllegalArgumentException("key is null");
    -        if (key instanceof String != true)
    -            return new LongIdentity(this.getClass(), (Long) key);
    -        return new LongIdentity(this.getClass(), (String) key);
    -    }
    -    
    -    public final void jdoProvideFields(int[] fieldId)
    -    {
    -        if (fieldId == null)
    -            throw new IllegalArgumentException("argment is null");
    -        int i = fieldId.length - 1;
    -        if (i >= 0)
    -        {
    -            do
    -                jdoProvideField(fieldId[i]);
    -            while (--i >= 0);
    -        }
    -    }
    -    
    -    public final void jdoReplaceFields(int[] fieldId) 
    -    {
    -        if (fieldId == null)
    -            throw new IllegalArgumentException("argument is null");
    -        int i = fieldId.length;
    -        if (i > 0)
    -        {
    -            int i_0_ = 0;
    -            do
    -                jdoReplaceField(fieldId[i_0_]);
    -            while (++i_0_ < i);
    -        }
    -    }
    -    
    -    public final void jdoReplaceFlags()
    -    {
    -        if (jdoStateManager != null) 
    -        {
    -            A a = this;
    -            a.jdoFlags = a.jdoStateManager.replacingFlags(this);
    -        }
    -    }
    -    
    -    public final synchronized void jdoReplaceStateManager(StateManager stateManager)
    -    {
    -        if (jdoStateManager != null)
    -        {
    -            A a = this;
    -            a.jdoStateManager = a.jdoStateManager.replacingStateManager(this, stateManager);
    -        }
    -        else
    -        {
    -            JDOImplHelper.checkAuthorizedStateManager(sm);
    -            jdoStateManager = stateManager;
    -            jdoFlags = (byte) 1;
    -        }
    -    }
    -    
    -    public final synchronized void jdoReplaceDetachedState()
    -    {
    -        if (jdoStateManager == null)
    -            throw new IllegalStateException("state manager is null");
    -        A a = this;
    -        a.jdoDetachedState = a.jdoStateManager.replacingDetachedState(this, jdoDetachedState);
    -    }
    -    
    -    public PersistenceCapable jdoNewInstance(StateManager sm)
    -    {
    -        A result = new A();
    -        A a = result;
    -        a.jdoFlags = (byte) 1;
    -        a.jdoStateManager = sm;
    -        return a;
    -    }
    -    
    -    public PersistenceCapable jdoNewInstance(StateManager sm, Object o)
    -    {
    -        A result = new A();
    -        A a = result;
    -        a.jdoFlags = (byte) 1;
    -        a.jdoStateManager = sm;
    -        result.jdoCopyKeyFieldsFromObjectId(o);
    -        return a;
    -    }
    -    
    -    public void jdoReplaceField(int fieldIndex)
    -    {
    -        if (jdoStateManager == null)
    -            throw new IllegalStateException("state manager is null");
    -        switch (fieldIndex)
    -        {
    -            case 0:
    -            {
    -                A a = this;
    -                a.b = (B) a.jdoStateManager.replacingObjectField(this, fieldIndex);
    -                break;
    -            }
    -            case 1:
    -            {
    -                A a = this;
    -                a.id = a.jdoStateManager.replacingLongField(this, fieldIndex);
    -                break;
    -            }
    -            case 2:
    -            {
    -                A a = this;
    -                a.name = a.jdoStateManager.replacingStringField(this, fieldIndex);
    -                break;
    -            }
    -            default:
    -                throw new IllegalArgumentException("out of field index :" + fieldIndex);
    -        }
    -    }
    -    
    -    public void jdoProvideField(int fieldIndex)
    -    {
    -        if (jdoStateManager == null)
    -            throw new IllegalStateException("state manager is null");
    -        switch (fieldIndex)
    -        {
    -            case 0:
    -                jdoStateManager.providedObjectField(this, fieldIndex, b);
    -                break;
    -            case 1:
    -                jdoStateManager.providedLongField(this, fieldIndex, id);
    -                break;
    -            case 2:
    -                jdoStateManager.providedStringField(this, fieldIndex, name);
    -                break;
    -            default:
    -                throw new IllegalArgumentException("out of field index :" + fieldIndex);
    -         }
    -    }
    -    
    -    protected final void jdoCopyField(A obj, int index)
    -    {
    -        switch (index)
    -        {
    -            case 0:
    -                b = obj.b;
    -                break;
    -            case 1:
    -                id = obj.id;
    -                break;
    -            case 2:
    -                name = obj.name;
    -                break;
    -            default:
    -                throw new IllegalArgumentException("out of field index :" + index);
    -        }
    -    }
    -    
    -    public void jdoCopyFields(Object obj, int[] fieldNumbers)
    -    {
    -        if (jdoStateManager == null)
    -            throw new IllegalStateException("state manager is null");
    -        if (fieldNumbers == null)
    -            throw new IllegalStateException("fieldNumbers is null");
    -        if (obj instanceof A != true)
    -            throw new IllegalArgumentException("object is not org.apache.jdo.test.A");
    -        A me = (A) obj;
    -        if (jdoStateManager != me.jdoStateManager)
    -            throw new IllegalArgumentException("state manager unmatch");
    -        int i = fieldNumbers.length - 1;
    -        if (i >= 0)
    -        {
    -            do
    -                jdoCopyField(me, fieldNumbers[i]);
    -            while (--i >= 0);
    -        }
    -    }
    -    
    -    private static final String[] __jdoFieldNamesInit()
    -    {
    -        return new String[] { "b", "id", "name" };
    -    }
    -    
    -    private static final Class[] __jdoFieldTypesInit()
    -    {
    -        return new Class[] { ___jdo$loadClass("org.apache.jdo.test.B"), Long.TYPE,
    -                 ___jdo$loadClass("java.lang.String") };
    -    }
    -    
    -    private static final byte[] __jdoFieldFlagsInit()
    -    {
    -        return new byte[] { 10, 24, 21 };
    -    }
    -    
    -    protected static int __jdoGetInheritedFieldCount()
    -    {
    -        return 0;
    -    }
    -    
    -    protected static int jdoGetManagedFieldCount()
    -    {
    -        return 3;
    -    }
    -    
    -    private static Class __jdoPersistenceCapableSuperclassInit()
    -    {
    -        return null;
    -    }
    -    
    -    public static Class ___jdo$loadClass(String className)
    -    {
    -        try
    -        {
    -            return Class.forName(className);
    -        }
    -        catch (ClassNotFoundException e)
    -        {
    -            throw new NoClassDefFoundError(e.getMessage());
    -        }
    -    }
    -    
    -    private Object jdoSuperClone()
    -    throws CloneNotSupportedException
    -    {
    -        A o = (A) super.clone();
    -        o.jdoFlags = (byte) 0;
    -        o.jdoStateManager = null;
    -        return o;
    -    }
    -    
    -    public A() 
    -    {
    -        /* empty */
    -    }
    -    
    -    static void jdoSetb(A objPC, B b_m)
    -    {
    -        if (objPC.jdoStateManager == null)
    -            objPC.b = b_m;
    -        else
    -            objPC.jdoStateManager.setObjectField(objPC, 0, objPC.b, b_m);
    -        if (objPC.jdoIsDetached() == true)
    -            ((BitSet) objPC.jdoDetachedState[3]).set(0);
    -    }
    -    
    -    static B jdoGetb(A objPC)
    -    {
    -        if (objPC.jdoStateManager != null
    -        && !objPC.jdoStateManager.isLoaded(objPC, 0))
    -            return (B) objPC.jdoStateManager.getObjectField(objPC, 0, objPC.b);
    -        if (objPC.jdoIsDetached() != false
    -        && ((BitSet) objPC.jdoDetachedState[2]).get(0) != true
    -        && ((BitSet) objPC.jdoDetachedState[3]).get(0) != true)
    -            throw new JDODetachedFieldAccessException
    -              ("You have just attempted to access field \"b\" yet this field was not detached when you detached the object. " +
    -               "Either dont access this field, or detach the field when detaching the object.");
    -        return objPC.b;
    -    }
    -    
    -    static void jdoSetid(A objPC, long id_n)
    -    {
    -        objPC.id = id_n;
    -    }
    -    
    -    static long jdoGetid(A objPC)
    -    {
    -        return objPC.id;
    -    }
    -    
    -    static void jdoSetname(A objPC, String name_c)
    -    {
    -        if (objPC.jdoFlags != 0 && objPC.jdoStateManager != null)
    -            objPC.jdoStateManager.setStringField(objPC, 2, objPC.name, name_c);
    -        else
    -        {
    -            objPC.name = name_c;
    -            if (objPC.jdoIsDetached() == true)
    -                ((BitSet) objPC.jdoDetachedState[3]).set(2);
    -        }
    -    }
    -    
    -    static String jdoGetname(A objPC)
    -    {
    -        if (objPC.jdoFlags > 0 && objPC.jdoStateManager != null && !objPC.jdoStateManager.isLoaded(objPC, 2))
    -            return objPC.jdoStateManager.getStringField(objPC, 2, objPC.name);
    -        if (objPC.jdoIsDetached() != false && ((BitSet) objPC.jdoDetachedState[2]).get(2) != true)
    -            throw new JDODetachedFieldAccessException
    -              ("You have just attempted to access field \"name\" yet this field was not detached when you detached the object." +
    -               "Either dont access this field, or detach the field when detaching the object.");
    -        return objPC.name;
    -    }
    -
    -    public A(String name)
    -    {
    -        jdoSetname(this, name);
    -    }
    -}
    -
    - - + + +

    JDO Enhancement

    +

    + JDO defines a byte-code enhancement process that provides for dirty detection of fields. + Before a class is used at runtime it is compiled and then "enhanced" to implement the interface + PersistenceCapable, and optionally also Detachable. +

    +

    + We can demonstrate this by taking a sample class, and seeing it before and after enhancement. + We start with the following class +

    +
    +package org.apache.jdo.test;
    +
    +public class A
    +{
    +    long id;
    +    String name;
    +    B b;
    +
    +    public A(String name)
    +    {
    +        this.name = name;
    +    }
    +
    +    public void setId(long id)
    +    {
    +        this.id = id;
    +    }
    +
    +    public void setB(B b)
    +    {
    +        this.b = b;
    +    }
    +
    +    public String getName()
    +    {
    +        return name;
    +    }
    +
    +    public B getB()
    +    {
    +        return b;
    +    }
    +
    +    public long getId()
    +    {
    +        return id;
    +    }
    +
    +    public String toString()
    +    {
    +        return "A : id=" + id + " [" + name + "] b=\"" + b + "\"";
    +    }
    +}
    +

    + and require it to be PersistenceCapable and Detachable. + The enhancement process needs to intercept all updates of the fields of the class (id, name, b) as well + as add on the necessary PersistenceCapable, Detachable methods. + After "enhancement" it becomes +

    +
    +package org.apache.jdo.test;
    +import java.util.BitSet;
    +
    +import javax.jdo.JDODetachedFieldAccessException;
    +import javax.jdo.JDOFatalInternalException;
    +import javax.jdo.PersistenceManager;
    +import javax.jdo.identity.LongIdentity;
    +import javax.jdo.spi.Detachable;
    +import javax.jdo.spi.JDOImplHelper;
    +import javax.jdo.spi.JDOPermission;
    +import javax.jdo.spi.PersistenceCapable;
    +import javax.jdo.spi.StateManager;
    +
    +public class A implements PersistenceCapable, Detachable
    +{
    +    long id;
    +    String name;
    +    B b;
    +    protected transient StateManager jdoStateManager;
    +    protected transient byte jdoFlags;
    +    protected Object[] jdoDetachedState;
    +    private static final byte[] jdoFieldFlags;
    +    private static final Class jdoPersistenceCapableSuperclass;
    +    private static final Class[] jdoFieldTypes;
    +    private static final String[] jdoFieldNames = __jdoFieldNamesInit();
    +    private static final int jdoInheritedFieldCount;
    +
    +    static
    +    {
    +        jdoFieldTypes = __jdoFieldTypesInit();
    +        jdoFieldFlags = __jdoFieldFlagsInit();
    +        jdoInheritedFieldCount = __jdoGetInheritedFieldCount();
    +        jdoPersistenceCapableSuperclass = __jdoPersistenceCapableSuperclassInit();
    +        JDOImplHelper.registerClass(___jdo$loadClass("org.apache.jdo.test.A"),
    +                    jdoFieldNames, jdoFieldTypes,
    +                    jdoFieldFlags,
    +                    jdoPersistenceCapableSuperclass, new A());
    +    }
    +    
    +    public void setId(long id)
    +    {
    +        jdoSetid(this, id);
    +    }
    +    
    +    public void setB(B b)
    +    {
    +        jdoSetb(this, b);
    +    }
    +    
    +    public String getName()
    +    {
    +        return jdoGetname(this);
    +    }
    +    
    +    public B getB()
    +    {
    +        return jdoGetb(this);
    +    }
    +    
    +    public long getId()
    +    {
    +        return jdoGetid(this);
    +    }
    +    
    +    public String toString()
    +    {
    +        return new StringBuilder().append("A : id=").append(jdoGetid(this))
    +           .append(" [").append(jdoGetname(this))
    +           .append("] b=\"").append(jdoGetb(this))
    +           .append("\"").toString();
    +    }
    +
    +    public void jdoCopyKeyFieldsFromObjectId(PersistenceCapable.ObjectIdFieldConsumer fc, Object oid)
    +    {
    +        if (fc == null)
    +            throw new IllegalArgumentException
    +              ("ObjectIdFieldConsumer is null");
    +        if (!(oid instanceof LongIdentity))
    +            throw new ClassCastException
    +              ("oid is not instanceof javax.jdo.identity.LongIdentity");
    +        LongIdentity o = (LongIdentity) oid;
    +        fc.storeLongField(1, o.getKey());
    +    }
    +    
    +    protected void jdoCopyKeyFieldsFromObjectId(Object oid)
    +    {
    +        if (!(oid instanceof LongIdentity))
    +            throw new ClassCastException
    +              ("key class is not javax.jdo.identity.LongIdentity or null");
    +        LongIdentity o = (LongIdentity) oid;
    +        id = o.getKey();
    +    }
    +    
    +    public final void jdoCopyKeyFieldsToObjectId(Object oid)
    +    {
    +        throw new JDOFatalInternalException
    +          ("It's illegal to call jdoCopyKeyFieldsToObjectId for a class with Single Field Identity.");
    +    }
    +    
    +    public final void jdoCopyKeyFieldsToObjectId
    +    (PersistenceCapable.ObjectIdFieldSupplier fs, Object oid) {
    +    throw new JDOFatalInternalException
    +          ("It's illegal to call jdoCopyKeyFieldsToObjectId for a class with Single Field Identity.");
    +    }
    +    
    +    public final Object jdoGetObjectId()
    +    {
    +        if (jdoStateManager != null)
    +            return jdoStateManager.getObjectId(this);
    +        if (this.jdoIsDetached() != true)
    +            return null;
    +        return jdoDetachedState[0];
    +    }
    +    
    +    public final Object jdoGetVersion()
    +    {
    +        if (jdoStateManager != null)
    +            return jdoStateManager.getVersion(this);
    +        if (this.jdoIsDetached() != true)
    +            return null;
    +        return jdoDetachedState[1];
    +    }
    +    
    +    protected final void jdoPreSerialize()
    +    {
    +        if (jdoStateManager != null)
    +            jdoStateManager.preSerialize(this);
    +    }
    +    
    +    public final PersistenceManager jdoGetPersistenceManager()
    +    {
    +        return (jdoStateManager != null
    +            ? jdoStateManager.getPersistenceManager(this) : null);
    +    }
    +    
    +    public final Object jdoGetTransactionalObjectId() 
    +    {
    +        return (jdoStateManager != null
    +           ? jdoStateManager.getTransactionalObjectId(this) : null);
    +    }
    +    
    +    public final boolean jdoIsDeleted()
    +    {
    +        return (jdoStateManager != null ? jdoStateManager.isDeleted(this): false);
    +    }
    +    
    +    public final boolean jdoIsDirty()
    +    {
    +        if (jdoStateManager != null)
    +            return jdoStateManager.isDirty(this);
    +        if (this.jdoIsDetached() != true)
    +            return false;
    +        if (((BitSet) jdoDetachedState[3]).length() <= 0)
    +            return false;
    +        return true;
    +    }
    +    
    +    public final boolean jdoIsNew()
    +    {
    +        return jdoStateManager != null ? jdoStateManager.isNew(this) : false;
    +    }
    +    
    +    public final boolean jdoIsPersistent()
    +    {
    +        return (jdoStateManager != null ? jdoStateManager.isPersistent(this): false);
    +    }
    +    
    +    public final boolean jdoIsTransactional()
    +    {
    +        return (jdoStateManager != null ? jdoStateManager.isTransactional(this): false);
    +    }
    +    
    +    public final boolean jdoIsDetached()
    +    {
    +        if (jdoStateManager == null) {
    +            if (jdoDetachedState == null)
    +                return false;
    +            return true;
    +        }
    +        return false;
    +    }
    +    
    +    public final void jdoMakeDirty(String fieldName)
    +    {
    +        if (jdoStateManager != null)
    +            jdoStateManager.makeDirty(this, fieldName);
    +    }
    +    
    +    public final Object jdoNewObjectIdInstance() 
    +    {
    +        return new LongIdentity(getClass(), id);
    +    }
    +    
    +    public final Object jdoNewObjectIdInstance(Object key) 
    +    {
    +        if (key == null)
    +            throw new IllegalArgumentException("key is null");
    +        if (key instanceof String != true)
    +            return new LongIdentity(this.getClass(), (Long) key);
    +        return new LongIdentity(this.getClass(), (String) key);
    +    }
    +    
    +    public final void jdoProvideFields(int[] fieldId)
    +    {
    +        if (fieldId == null)
    +            throw new IllegalArgumentException("argment is null");
    +        int i = fieldId.length - 1;
    +        if (i >= 0)
    +        {
    +            do
    +                jdoProvideField(fieldId[i]);
    +            while (--i >= 0);
    +        }
    +    }
    +    
    +    public final void jdoReplaceFields(int[] fieldId) 
    +    {
    +        if (fieldId == null)
    +            throw new IllegalArgumentException("argument is null");
    +        int i = fieldId.length;
    +        if (i > 0)
    +        {
    +            int i_0_ = 0;
    +            do
    +                jdoReplaceField(fieldId[i_0_]);
    +            while (++i_0_ < i);
    +        }
    +    }
    +    
    +    public final void jdoReplaceFlags()
    +    {
    +        if (jdoStateManager != null) 
    +        {
    +            A a = this;
    +            a.jdoFlags = a.jdoStateManager.replacingFlags(this);
    +        }
    +    }
    +    
    +    public final synchronized void jdoReplaceStateManager(StateManager stateManager)
    +    {
    +        if (jdoStateManager != null)
    +        {
    +            A a = this;
    +            a.jdoStateManager = a.jdoStateManager.replacingStateManager(this, stateManager);
    +        }
    +        else
    +        {
    +            JDOImplHelper.checkAuthorizedStateManager(sm);
    +            jdoStateManager = stateManager;
    +            jdoFlags = (byte) 1;
    +        }
    +    }
    +    
    +    public final synchronized void jdoReplaceDetachedState()
    +    {
    +        if (jdoStateManager == null)
    +            throw new IllegalStateException("state manager is null");
    +        A a = this;
    +        a.jdoDetachedState = a.jdoStateManager.replacingDetachedState(this, jdoDetachedState);
    +    }
    +    
    +    public PersistenceCapable jdoNewInstance(StateManager sm)
    +    {
    +        A result = new A();
    +        A a = result;
    +        a.jdoFlags = (byte) 1;
    +        a.jdoStateManager = sm;
    +        return a;
    +    }
    +    
    +    public PersistenceCapable jdoNewInstance(StateManager sm, Object o)
    +    {
    +        A result = new A();
    +        A a = result;
    +        a.jdoFlags = (byte) 1;
    +        a.jdoStateManager = sm;
    +        result.jdoCopyKeyFieldsFromObjectId(o);
    +        return a;
    +    }
    +    
    +    public void jdoReplaceField(int fieldIndex)
    +    {
    +        if (jdoStateManager == null)
    +            throw new IllegalStateException("state manager is null");
    +        switch (fieldIndex)
    +        {
    +            case 0:
    +            {
    +                A a = this;
    +                a.b = (B) a.jdoStateManager.replacingObjectField(this, fieldIndex);
    +                break;
    +            }
    +            case 1:
    +            {
    +                A a = this;
    +                a.id = a.jdoStateManager.replacingLongField(this, fieldIndex);
    +                break;
    +            }
    +            case 2:
    +            {
    +                A a = this;
    +                a.name = a.jdoStateManager.replacingStringField(this, fieldIndex);
    +                break;
    +            }
    +            default:
    +                throw new IllegalArgumentException("out of field index :" + fieldIndex);
    +        }
    +    }
    +    
    +    public void jdoProvideField(int fieldIndex)
    +    {
    +        if (jdoStateManager == null)
    +            throw new IllegalStateException("state manager is null");
    +        switch (fieldIndex)
    +        {
    +            case 0:
    +                jdoStateManager.providedObjectField(this, fieldIndex, b);
    +                break;
    +            case 1:
    +                jdoStateManager.providedLongField(this, fieldIndex, id);
    +                break;
    +            case 2:
    +                jdoStateManager.providedStringField(this, fieldIndex, name);
    +                break;
    +            default:
    +                throw new IllegalArgumentException("out of field index :" + fieldIndex);
    +         }
    +    }
    +    
    +    protected final void jdoCopyField(A obj, int index)
    +    {
    +        switch (index)
    +        {
    +            case 0:
    +                b = obj.b;
    +                break;
    +            case 1:
    +                id = obj.id;
    +                break;
    +            case 2:
    +                name = obj.name;
    +                break;
    +            default:
    +                throw new IllegalArgumentException("out of field index :" + index);
    +        }
    +    }
    +    
    +    public void jdoCopyFields(Object obj, int[] fieldNumbers)
    +    {
    +        if (jdoStateManager == null)
    +            throw new IllegalStateException("state manager is null");
    +        if (fieldNumbers == null)
    +            throw new IllegalStateException("fieldNumbers is null");
    +        if (obj instanceof A != true)
    +            throw new IllegalArgumentException("object is not org.apache.jdo.test.A");
    +        A me = (A) obj;
    +        if (jdoStateManager != me.jdoStateManager)
    +            throw new IllegalArgumentException("state manager unmatch");
    +        int i = fieldNumbers.length - 1;
    +        if (i >= 0)
    +        {
    +            do
    +                jdoCopyField(me, fieldNumbers[i]);
    +            while (--i >= 0);
    +        }
    +    }
    +    
    +    private static final String[] __jdoFieldNamesInit()
    +    {
    +        return new String[] { "b", "id", "name" };
    +    }
    +    
    +    private static final Class[] __jdoFieldTypesInit()
    +    {
    +        return new Class[] { ___jdo$loadClass("org.apache.jdo.test.B"), Long.TYPE,
    +                 ___jdo$loadClass("java.lang.String") };
    +    }
    +    
    +    private static final byte[] __jdoFieldFlagsInit()
    +    {
    +        return new byte[] { 10, 24, 21 };
    +    }
    +    
    +    protected static int __jdoGetInheritedFieldCount()
    +    {
    +        return 0;
    +    }
    +    
    +    protected static int jdoGetManagedFieldCount()
    +    {
    +        return 3;
    +    }
    +    
    +    private static Class __jdoPersistenceCapableSuperclassInit()
    +    {
    +        return null;
    +    }
    +    
    +    public static Class ___jdo$loadClass(String className)
    +    {
    +        try
    +        {
    +            return Class.forName(className);
    +        }
    +        catch (ClassNotFoundException e)
    +        {
    +            throw new NoClassDefFoundError(e.getMessage());
    +        }
    +    }
    +    
    +    private Object jdoSuperClone()
    +    throws CloneNotSupportedException
    +    {
    +        A o = (A) super.clone();
    +        o.jdoFlags = (byte) 0;
    +        o.jdoStateManager = null;
    +        return o;
    +    }
    +    
    +    public A() 
    +    {
    +        /* empty */
    +    }
    +    
    +    static void jdoSetb(A objPC, B b_m)
    +    {
    +        if (objPC.jdoStateManager == null)
    +            objPC.b = b_m;
    +        else
    +            objPC.jdoStateManager.setObjectField(objPC, 0, objPC.b, b_m);
    +        if (objPC.jdoIsDetached() == true)
    +            ((BitSet) objPC.jdoDetachedState[3]).set(0);
    +    }
    +    
    +    static B jdoGetb(A objPC)
    +    {
    +        if (objPC.jdoStateManager != null
    +        && !objPC.jdoStateManager.isLoaded(objPC, 0))
    +            return (B) objPC.jdoStateManager.getObjectField(objPC, 0, objPC.b);
    +        if (objPC.jdoIsDetached() != false
    +        && ((BitSet) objPC.jdoDetachedState[2]).get(0) != true
    +        && ((BitSet) objPC.jdoDetachedState[3]).get(0) != true)
    +            throw new JDODetachedFieldAccessException
    +              ("You have just attempted to access field \"b\" yet this field was not detached when you detached the object. " +
    +               "Either dont access this field, or detach the field when detaching the object.");
    +        return objPC.b;
    +    }
    +    
    +    static void jdoSetid(A objPC, long id_n)
    +    {
    +        objPC.id = id_n;
    +    }
    +    
    +    static long jdoGetid(A objPC)
    +    {
    +        return objPC.id;
    +    }
    +    
    +    static void jdoSetname(A objPC, String name_c)
    +    {
    +        if (objPC.jdoFlags != 0 && objPC.jdoStateManager != null)
    +            objPC.jdoStateManager.setStringField(objPC, 2, objPC.name, name_c);
    +        else
    +        {
    +            objPC.name = name_c;
    +            if (objPC.jdoIsDetached() == true)
    +                ((BitSet) objPC.jdoDetachedState[3]).set(2);
    +        }
    +    }
    +    
    +    static String jdoGetname(A objPC)
    +    {
    +        if (objPC.jdoFlags > 0 && objPC.jdoStateManager != null && !objPC.jdoStateManager.isLoaded(objPC, 2))
    +            return objPC.jdoStateManager.getStringField(objPC, 2, objPC.name);
    +        if (objPC.jdoIsDetached() != false && ((BitSet) objPC.jdoDetachedState[2]).get(2) != true)
    +            throw new JDODetachedFieldAccessException
    +              ("You have just attempted to access field \"name\" yet this field was not detached when you detached the object." +
    +               "Either dont access this field, or detach the field when detaching the object.");
    +        return objPC.name;
    +    }
    +
    +    public A(String name)
    +    {
    +        jdoSetname(this, name);
    +    }
    +}
    +
    + +
    @@ -769,7 +769,7 @@ public class A implements PersistenceCap