Added: db/jdo/site/docs/fetchgroups.html URL: http://svn.apache.org/viewvc/db/jdo/site/docs/fetchgroups.html?rev=1090559&view=auto ============================================================================== --- db/jdo/site/docs/fetchgroups.html (added) +++ db/jdo/site/docs/fetchgroups.html Sat Apr 9 10:16:58 2011 @@ -0,0 +1,229 @@ +
+ When an object is retrieved from the datastore by JDO typically not all fields are retrieved immediately. + This is because for efficiency purposes only particular field types are retrieved in the initial access + of the object, and then any other objects are retrieved when accessed (lazy loading). + The group of fields that are loaded is called a fetch group. + There are 3 types of "fetch groups" to consider +
+ The fetch group in use for a class is controled via the FetchPlan
+
+ interface. To get a handle on the current FetchPlan we do
+
FetchPlan fp = pm.getFetchPlan();
+ JDO provides an initial fetch group, comprising the fields that will be retrieved when an object + is retrieved if the user does nothing to define the required behaviour. By default the default + fetch group comprises all fields of the following types :- +
+ If you wish to change the Default Fetch Group for a class you can update the Meta-Data + for the class as follows (for XML) +
++<class name="MyClass"> + ... + <field name="fieldX" default-fetch-group="true"/> +</class>
or using annotations
++@Persistent(defaultFetchGroup="true") +SomeType fieldX;
+ When a PersistenceManager is created it starts with a FetchPlan of the "default" fetch group. + That is, if we call +
+Collection fetchGroups = fp.getGroups();
+ this will have one group, called "default". At runtime, if you have been using other + fetch groups and want to revert back to the default fetch group at any time you simply do +
+fp.setGroup(FetchPlan.DEFAULT);
+ As mentioned above, JDO allows specification of users own fetch groups. These are specified in the + MetaData of the class. For example, if we have the following class +
++class MyClass +{ + String name; + HashSet coll; + MyOtherClass other; +}
+ and we want to have the other field loaded whenever we load objects of this class, we define + our MetaData as +
++<package name="mydomain"> + <class name="MyClass"> + <field name="name"> + <column length="100" jdbc-type="VARCHAR"/> + </field> + <field name="coll" persistence-modifier="persistent"> + <collection element-type="mydomain.Address"/> + <join/> + </field> + <field name="other" persistence-modifier="persistent"/> + <fetch-group name="otherfield"> + <field name="other"/> + </fetch-group> + </class> +</package>
or using annotations
++@PersistenceCapable +@FetchGroup(name="otherfield", members={@Persistent(name="other")}) +public class MyClass +{ + ... +}
+ So we have defined a fetch group called "otherfield" that just includes the field with name + other. We can then use this at runtime in our persistence code. +
++PersistenceManager pm = pmf.getPersistenceManager(); +pm.getFetchPlan().addGroup("otherfield"); + +... (load MyClass object)
+ By default the FetchPlan will include the default fetch group. We have changed this above by + adding the fetch group "otherfield", so when we retrieve an object using this + PersistenceManager we will be retrieving the fields name AND other since they + are both in the current FetchPlan. We can take the above much further than what is shown by + defining nested fetch groups in the MetaData. In addition we can change the FetchPlan just + before any PersistenceManager operation to control what is fetched during that operation. + The user has full flexibility to add many groups to the current Fetch Plan. + This gives much power and control over what will be loaded and when. +
+ The FetchPlan applies not just to calls to PersistenceManager.getObjectById(), but also + to PersistenceManager.newQuery(), PersistenceManager.getExtent(), + PersistenceManager.detachCopy and much more besides. +
+ You can read more about named fetch-groups and how to use it with + attach/detach +
+ The mechanism above provides static fetch groups defined in XML or annotations. + That is great when you know in advance what fields you want to fetch. In some situations + you may want to define your fields to fetch at run time. This became standard in JDO2.2 + It operates as follows +
++import org.datanucleus.FetchGroup; + +// Create a FetchGroup on the PMF called "TestGroup" for MyClass +FetchGroup grp = myPMF.getFetchGroup("TestGroup", MyClass.class); +grp.addMember("field1").addMember("field2"); + +// Add this group to the fetch plan (using its name) +fp.addGroup("TestGroup");
+ So we use the DataNucleus PMF as a way of creating a FetchGroup, and then register that + FetchGroup with the PMF for use by all PMs. We then enable our FetchGroup for use in the + FetchPlan by using its group name (as we do for a static group). The FetchGroup allows you + to add/remove the fields necessary so you have full API control over the fields to be + fetched. +
+ The basic fetch group defines which fields are to be fetched. It doesn't explicitly define how far + down an object graph is to be fetched. JDO provides two ways of controlling this. +
+ The first is to set the maxFetchDepth for the FetchPlan. This value specifies how + far out from the root object the related objects will be fetched. A positive value means that + this number of relationships will be traversed from the root object. A value of -1 means that + no limit will be placed on the fetching traversal. The default is 1. Let's take an example +
++public class MyClass1 +{ + MyClass2 field1; + ... +} + +public class MyClass2 +{ + MyClass3 field2; + ... +} + +public class MyClass3 +{ + MyClass4 field3; + ... +}
+ and we want to detach field1 of instances of MyClass1, down 2 levels - so detaching + the initial "field1" MyClass2 object, and its "field2" MyClass3 instance. So we + define our fetch-groups like this +
++<class name="MyClass1"> + ... + <fetch-group name="includingField1"> + <field name="field1"/> + </fetch-group> +</class> +<class name="MyClass2"> + ... + <fetch-group name="includingField2"> + <field name="field2"/> + </fetch-group> +</class>
+ and we then define the maxFetchDepth as 2, like this +
+pm.getFetchPlan().setMaxFetchDepth(2);
+ A further refinement to this global fetch depth setting is to control the fetching of recursive + fields. This is performed via a MetaData setting "recursion-depth". A value of 1 means that only + 1 level of objects will be fetched. A value of -1 means there is no limit on the amount of recursion. + The default is 1. Let's take an example +
++public class Directory +{ + Collection children; + ... +}
+<class name="Directory"> + <field name="children"> + <collection element-type="Directory"/> + </field> + + <fetch-group name="grandchildren"> + <field name="children" recursion-depth="2"/> + </fetch-group> + ... +</class>
+ So when we fetch a Directory, it will fetch 2 levels of the children field, hence fetching + the children and the grandchildren. +
+ A FetchPlan can also be used for defining the fetching policy when using queries. This can be + set using +
+pm.getFetchPlan().setFetchSize(value);
+ The default is FetchPlan.FETCH_SIZE_OPTIMAL which leaves it to DataNucleus to optimise the fetching + of instances. A positive value defines the number of instances to be fetched. Using + FetchPlan.FETCH_SIZE_GREEDY means that all instances will be fetched immediately. +
![]() |
+ @import url("./style/maven-theme.css");
When persisting a class, a persistence solution needs to know how to persist the types of each field in the class. Clearly a persistence solution can only support a finite number of Java types. It cannot know how to persist every possible type creatable. The JDO @@ -28,4 +28,4 @@ and whether the java type can be used as part of the primary key.
Java Type | DFG? | Persistent? | PK? |
---|---|---|---|
boolean | ![]() | ![]() | ![]() |
byte | ![]() | ![]() | ![]() |
char | ![]() | ![]() | ![]() |
double | ![]() | ![]() | ![]() |
float | ![]() | ![]() | ![]() |
int | ![]() | ![]() | ![]() |
long | ![]() | ![]() | ![]() |
short | ![]() | ![]() | ![]() |
boolean[] | ![]() | ![]() | ![]() |
byte[] | ![]() | ![]() | ![]() |
char[] | ![]() | ![]() | ![]() |
double[] | ![]() | ![]() | ![]() |
float[] | ![]() | ![]() | ![]() |
int[] | ![]() | ![]() | ![]() |
long[] | ![]() | ![]() | ![]() |
short[] | ![]() | ![]() | ![]() |
java.lang.Boolean | ![]() | ![]() | ![]() |
java.lang.Byte | ![]() | ![]() | ![]() |
java.lang.Character | ![]() | ![]() | ![]() |
java.lang.Double |
![]() | ![]() | ![]() |
java.lang.Float | ![]() | ![]() | ![]() |
java.lang.Integer | ![]() | ![]() | ![]() |
java.lang.Long | ![]() | ![]() | ![]() |
java.lang.Short | ![]() | ![]() | ![]() |
java.lang.Boolean[] | ![]() | ![]() | ![]() |
java.lang.Byte[] | ![]() | ![]() | ![]() |
java.lang.Character[] | ![]() | ![]() | ![]() |
java.lang.Double[] | ![]() | ![]() | ![]() |
java.lang.Float[] | ![]() | ![]() | ![]() |
java.lang.Integer[] | ![]() | ![]() | ![]() |
java.lang.Long[] | ![]() | ![]() | ![]() |
java.lang.Short[] | ![]() | ![]() | ![]() |
java.lang.Number | ![]() | ![]() | ![]() |
java.lang.Object | ![]() | ![]() | ![]() |
java.lang.String | ![]() | ![]() | ![]() |
java.lang.String[] | ![]() | ![]() | ![]() |
java.math.BigDecimal | ![]() | ![]() | ![]() |
java.math.BigInteger | ![]() | ![]() | ![]() |
java.math.BigDecimal[] | ![]() | ![]() | ![]() |
java.math.BigInteger[] | ![]() | ![]() | ![]() |
java.sql.Date | ![]() | ![]() | ![]() |
java.sql.Time | ![]() | ![]() | ![]() |
java.sql.Timestam p | ![]() | ![]() | ![]() |
java.util.ArrayList | ![]() | ![]() | ![]() |
java.util.Collection | ![]() | ![]() | ![]() |
java.util.Currency | ![]() | ![]() | ![]() |
java.util.Date | ![]() | ![]() | ![]() |
java.util.Date[] | ![]() | ![]() | ![]() |
java.util.HashMap | ![]() | ![]() | ![]() |
java.util.HashSet | ![]() | ![]() | ![]() |
java.util.Hashtable | ![]() | ![]() | ![]() |
java.util.LinkedHashMap | ![]() | ![]() | ![]() |
java.util.LinkedHashSet | ![]() | ![]() | ![]() |
java.util.LinkedList | ![]() | ![]() | |
java.util.List | ![]() | ![]() | ![]() |
java.util.Locale | ![]() | ![]() | ![]() |
java.util.Locale[] | ![]() | ![]() | ![]() |
java.util.Map | ![]() | < img src="images/icon_success_sml.gif" border="0" alt=""> | ![]() |
java.util.Set | ![]() | ![]() | ![]() |
java.util.TreeMap | ![]() | ![]() | ![]() |
java.util.TreeSet | ![]() | ![]() | ![]() |
java.util.Vector | ![]() | ![]() | ![]() |
java.io.Serializable | ![]() | ![]() | ![]() |
javax.jdo.spi.PersistenceCapable | ![]() | ![]() | ![]() |
javax.jdo.spi.PersistenceCapable[] | ![]() | ![]() | ![]() |
java.lang.Enum | ![]() | ![]() | ![]() |
java.lang.Enum[] | ![]() | ![]() | ![]() |
![]() |