![]() |
![]() |
Back to the Speedo tutorial home page
![]() |
A Book is identified by its title. A Book has an author and
an editor. An author is identified by his name. An Editor is identified by his name and has an address. The PK of an Address is composed of its street and its zip code (we use an AddressId class). The source code of the java classes is located in the org.objectweb.speedo.tutorial.pobjects.additional.detach package. |
Let's have a look at the detach.jdo file :
<!DOCTYPE jdo PUBLIC "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 1.0//EN"1 To perform a detach on instances of a class, the class has to be marked as detachable.
"jdo.dtd">
<jdo>
<package name="org.objectweb.speedo.pobjects.tutorial.additional.detach">
<class name="Author" identity-type="application" detachable="true"> 1
<extension vendor-name="speedo" key="sql-name" value="T_ADDITIONAL_AUTHOR"/>
<field name="name" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="NAME"/>
</field>
</class>
<class name="Address" identity-type="application" objectid-class="org.objectweb.speedo.pobjects.tutorial.additional.detach.AddressId" detachable="true">
<extension vendor-name="speedo" key="sql-name" value="T_ADDITIONAL_ADDRESS"/>
<field name="street" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="STREET"/>
</field>
<field name="zipCode" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="ZIP"/>
</field>
<field name="city">
<extension vendor-name="speedo" key="sql-name" value="CITY"/>
</field>
</class>
<class name="Editor" identity-type="application" detachable="true">
<extension vendor-name="speedo" key="sql-name" value="T_ADDITIONAL_EDITOR"/>
<field name="name" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="NAME"/>
</field>
<field name="address">
<extension vendor-name="speedo" key="target-foreign-keys" value="STREET:A_STREET,ZIP:A_ZIP"/>
</field>
</class>
<class name="Book" identity-type="application" detachable="true">
<extension vendor-name="speedo" key="sql-name" value="T_ADDITIONAL_BOOK"/>
<field name="title" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="TITLE"/>
</field>
<field name="author" default-fetch-group="false">
<extension vendor-name="speedo" key="target-foreign-keys" value="NAME:AUTHOR_NAME"/>
</field>
<field name="editor" default-fetch-group="false">
<extension vendor-name="speedo" key="target-foreign-keys" value="NAME:EDITOR_NAME"/>
</field>
<field name="year">
<extension vendor-name="speedo" key="sql-name" value="YEAR"/>
</field>
<fetch-group name="onlyAuthor"> |
<field name="author"/> |
</fetch-group> |
<fetch-group name="editorName"> | 2
<fetch-group name="default"/> |
<field name="editor.name"/> |
</fetch-group> |
</class>
</package>
</jdo>
Within Speedo, four fetch groups are predefined:
/**
* detach persistent objects
*/
public static void detachObject(PersistenceManager pm){
Author author = new Author("Henry Miller");
Address address = new Address("Coronation Street", "811XBA", "Manchester");
Editor editor = new Editor("Grasset", address);
Book book = new Book("Tropic of Capricorn", author, editor, 1939);
//make the book persistent
pm.currentTransaction().begin();
System.out.println( "make persistent the book " + book.toString());
pm.makePersistent(book);
pm.currentTransaction().commit();
//detach the book
Book copyOfBook = (Book) pm.detachCopy(book);
System.out.println("The detached version of the book is as follows:\n " + copyOfBook.toString());
}
/**To launch the step 6:
* detach persistent object
* modify it
* then re-attach it
*/
public static void attachObject(PersistenceManager pm){
Author author = new Author("Hubert Selby Jr");
Address address = new Address("Sharrow Street", "911ZB2", "Sheffield");
Editor editor = new Editor("Folio", address);
Book book = new Book("The willow tree", author, editor, 1999);
//make the book persistent
pm.currentTransaction().begin();
System.out.println( "make persistent the book " + book.toString());
pm.makePersistent(book);
pm.currentTransaction().commit();
//detach the book
Book copyOfBook = (Book) pm.detachCopy(book);
System.out.println("The detached version of the book is as follows:\n " + copyOfBook.toString());
//modify the book
copyOfBook.setYear(2012);
copyOfBook.getEditor().getAddress().setCity("New York");
System.out.println( "Copy of the book " + copyOfBook.toString());
//attach the book
pm.currentTransaction().begin();
Book attachedBook = (Book) pm.makePersistent(copyOfBook);
pm.currentTransaction().commit();
System.out.println("The attached version of the book is as follows:\n " + attachedBook.toString());
}
/**The execution of this method gives these results:
* Detach objects with the predefined fetchgroups:
* default
* all
*/
public static void usePredefinedFetchGroups(PersistenceManager pm){
//get the pm fetch plan
FetchPlan fp = pm.getFetchPlan();
//create a book
Author author = new Author("William S. Burroughs");
Address address = new Address("Fenton Street", "931ZR2", "Leeds");
Editor editor = new Editor("Mille et Une Nuits", address);
Book book = new Book("The Yage Letters", author, editor, 1955);
//make the book persistent
pm.currentTransaction().begin();
System.out.println( "make persistent the book " + book.toString());
pm.makePersistent(book);
pm.currentTransaction().commit();
//detach the book --> "default" fetch group
//fields title and year are loaded
// fields editor and author are not loaded
Book defaultBook = (Book) pm.detachCopy(book);
System.out.println( "With the default fetchgroup:");
try{
System.out.println( "Title can be accessed: " + defaultBook.getTitle());
System.out.println( "Year can be accessed: " + defaultBook.getYear());
System.out.println( "Author should not be accessed: " + defaultBook.getAuthor().toString());
System.out.println( "Editor should not be accessed: " + defaultBook.getEditor().toString());
}
catch(Exception e){
if(e instanceof JDODetachedFieldAccessException && e.getMessage().indexOf("author") != -1)
System.out.println( "Correct exception caught: " + e.getMessage());
else
System.out.println( "Error: " + e);
}
//detach the book --> "all" fetch group
//all fields are loaded
fp.addGroup("all").removeGroup("default");
Book allBook = (Book) pm.detachCopy(book);
System.out.println( "With the all fetchgroup:");
try{
System.out.println( "Title can be accessed: " + allBook.getTitle());
System.out.println( "Year can be accessed: " + allBook.getYear());
System.out.println( "Author can be accessed: " + allBook.getAuthor().toString());
System.out.println( "Editor can be accessed: " + allBook.getEditor().toString());
}
catch(Exception e){
System.out.println( "Error: " + e);
}
}
[java] make persistent the book The Yage Letters, author=[William S.Burroughs], editor=[Mille et Une Nuits, address=[Fenton Street, 931ZR2,Leeds]], 1955
[java] With the default fetchgroup:
[java] Title can be accessed: The Yage Letters
[java] Year can be accessed: 1955
[java] Correct exception caught: Field author cannot be accessed: not loaded when the object has been detached
[java] With the all fetchgroup:
[java] Title can be accessed: The Yage Letters
[java] Year can be accessed: 1955
[java] Author can be accessed: William S. Burroughs
[java] Editor can be accessed: Mille et Une Nuits, address=[Fenton Street, 931ZR2, Leeds]
/**The execution of the method gives these results:
* Detach objects with user-defined fetchgroups (see the detach.jdo file)
*/
public static void useDefinedFetchGroups(PersistenceManager pm){
//get the pm fetch plan
FetchPlan fp = pm.getFetchPlan();
//create a book
Author author = new Author("John Fante");
Address address = new Address("South Street", "211ZL2", "York");
Editor editor = new Editor("Plon", address);
Book book = new Book("Bandini", author, editor, 1938);
//make the book persistent
pm.currentTransaction().begin();
System.out.println( "make persistent the book " + book.toString());
pm.makePersistent(book);
pm.currentTransaction().commit();
//detach the book --> "onlyAuthor" fetch group
//fields title year and author are loaded
// fields editor is not loaded
fp.addGroup("onlyAuthor").removeGroup("default");
Book onlyAuthorBook = (Book) pm.detachCopy(book);
System.out.println( "With the onlyAuthor fetchgroup:");
try{
System.out.println( "Title can be accessed: " + onlyAuthorBook.getTitle());
System.out.println( "Year can be accessed: " + onlyAuthorBook.getYear());
System.out.println( "Author can be accessed: " + onlyAuthorBook.getAuthor().toString());
System.out.println( "Editor should not be accessed: " + onlyAuthorBook.getEditor().toString());
}
catch(Exception e){
if(e instanceof JDODetachedFieldAccessException && e.getMessage().indexOf("editor") != -1)
System.out.println( "Correct exception caught: " + e.getMessage());
else
System.out.println( "Error: " + e);
}
//detach the book --> "editorName" fetch group
//fields title, year, editor.name are loaded
//fields author, editor.address are not loaded
fp.addGroup("editorName").removeGroup("onlyAuthor");
Book editorNameBook = (Book) pm.detachCopy(book);
System.out.println( "With the editorName fetchgroup:");
try{
System.out.println( "Title can be accessed: " + editorNameBook.getTitle());
System.out.println( "Year can be accessed: " + editorNameBook.getYear());
System.out.println( "Editor name can be accessed: " + editorNameBook.getEditor().getName());
System.out.println( "Editor address should not be accessed: " + editorNameBook.getEditor().getAddress().toString());
System.out.println( "Author should not be accessed: " + editorNameBook.getAuthor().toString());
}
catch(Exception e){
if(e instanceof JDODetachedFieldAccessException && e.getMessage().indexOf("address") != -1)
System.out.println( "Correct exception caught: " + e.getMessage());
else
System.out.println( "Error: " + e);
}
}
[java] make persistent the book Bandini, author=[John Fante], editor=[Plon, address=[South Street, 211ZL2, York]], 1938To launch the step 7:
[java] With the onlyAuthor fetchgroup:
[java] Title can be accessed: Bandini
[java] Year can be accessed: 1938
[java] Author can be accessed: John Fante
[java] Correct exception caught: Field editor cannot be accessed: not loaded when the object has been detached
[java] With the editorName fetchgroup:
[java] Title can be accessed: Bandini
[java] Year can be accessed: 1938
[java] Editor name can be accessed: Plon
[java] Correct exception caught: Field address cannot be accessed: not loaded when the object has been detached