Kodo supports many persistence strategies beyond those of the JPA specification. Section 6.3, “Additional JPA Metadata” covered the logical metadata for Kodo's additional persistence strategies. We now demonstrate how to map entities using these strategies to the database.
			Section 5.3, “Object Identity” describes how to use datastore
			identity in JPA.  Kodo requires a single numeric 
			primary key column to hold datastore identity values.  The
			
			org.apache.openjpa.persistence.jdbc.DataStoreIdColumn
			 annotation customizes the datastore identity column.  This 
			annotation has the following properties:
			
					String name:  Defaults to 
					ID.
					
int precision
String columnDefinition
boolean insertable
boolean updatable
			All properties correspond exactly to the same-named properties on 
			the standard Column annotation, described in
			Section 12.3, “Column”.
			
			Kodo supports version fields as defined by the JPA
			specification, but allows you to use a surrogate version column
			in place of a version field if you like.  You map the surrogate 
			version column with the 
			
			kodo.persistence.jdbc.LockGroupVersionColumn 
            annotation.  If you take advantage of Kodo's ability to define
			multiple lock groups,
			you may have multiple version columns.  In that case, use the 
			
			kodo.persistence.jdbc.LockGroupVersionColumns 
			annotation to declare an array of 
			LockGroupVersionColumn values.
			Each LockGroupVersionColumn has the following 
			properties:
			
					String name:  Defaults to 
					VERSN.
					
String lockGroup
int length
int precision
int scale
String columnDefinition
boolean nullable
boolean insertable
boolean updatable
			The lockGroup property allows you to specify that
			a version column is for some lock group other than the default
			group.  See Section 5.8, “Lock Groups” for an example.
			All other properties correspond exactly to the same-named 
			properties on the standard Column annotation,
			described in Section 12.3, “Column”.
			
			By default, Kodo assumes that surrogate versioning uses a version
			number strategy.  You can choose a different strategy with the
			VersionStrategy annotation described in
			Section 7.9.1.4, “Version Strategy”.
			
			Kodo makes it easy to create multi-column 
			custom 
			mappings.  The JPA specification includes a
			Column annotation, but is missing a way to
			declare multiple columns for a single field.  Kodo remedies this
			with the 
			
			org.apache.openjpa.persistence.jdbc.Columns
			annotation, which contains an array of Column
			values.  Example 7.34, “Custom Mappings via Extensions”
			uses Kodo's Columns annotation to map a
			java.awt.Point to separate X and Y columns.
			
			Remember to annotate custom field types with 
			Persistent, as described in
			Section 6.3.3, “Persistent Field Values”.
			
			Section 12.8.4, “Direct Relations” in the JPA
			Overview introduced you to the JoinColumn
			annotation.  A JoinColumn's 
			referencedColumnName property declares which column in
			the table of the related type this join column links to.  Suppose, 
			however, that the related type is unmapped, or that it is part of
			a table-per-class inheritance hierarchy.  Each subclass that might
			be assigned to the field could reside in a different table, and
			could use entirely different names for its primary key columns.  
			It becomes impossible to supply a single 
			referencedColumnName that works for all subclasses.
			
			Kodo rectifies this by allowing you to declare which 
			attribute in the related type each join column
			links to, rather than which column.  If the attribute is mapped 
			differently in various subclass tables, Kodo automatically forms the
			proper join for the subclass record at hand.  The
			
			org.apache.openjpa.persistence.jdbc.XJoinColumn
			annotation has all the same properties as the standard 
			JoinColumn annotation, but adds an
			additional referencedAttributeName property for
			this purpose.  Simply use a XJoinColumn
			in place of a JoinColumn whenever you need
			to access this added functionality.
			
			For compound keys, use the
			
			org.apache.openjpa.persistence.jdbc.XJoinColumns
			 annotation.  The value of this annotation is an array of
			individual XJoinColumns.
			
			JPA uses the AttributeOverride
			annotation to override the default mappings of an embeddable
			class.  The JPA Overview details this process in
			Section 12.8.3, “Embedded Mapping”.  
			AttributeOverrides suffice for simple mappings, but
			do not allow you to override complex mappings.  Also, JPA 
			has no way to differentitate between a null embedded
			object and one with default values for all of its fields.
			
			Kodo overcomes these shortcomings with the 
			
			kodo.persistence.jdbc.XEmbeddedMapping
			annotation.  This annotation has the following properties:
			
					String nullIndicatorColumnName: If the
					named column's value is NULL, then the 
					embedded object is assumed to be null.  If the named column
					has a non-NULL value, then the embedded 
					object will get loaded and 
					populated with data from the other embedded fields.  
					This property is entirely optional.  By default, Kodo 
					always assumes the embedded object is non-null, just as
					in standard JPA mapping.
					
					If the column you name does not belong to any fields of the 
					embedded object, Kodo will create a synthetic null-indicator
					column with this name.  In fact, you can specify a value of
					true to simply indicate that you want
					a synthetic null-indicator column, without having to 
					come up with a name for it.  A value of false
					 signals that you explicitly do not want a
					null-indicator column created for this mapping (in case you
					have configured your 
					mapping defaults
					 to create one by default).
					
					String nullIndicatorFieldName: Rather 
					than name a null indicator column, you can name a field of
					the embedded type.  Kodo will use the column of this field
					as the null-indicator column.
					
					XMappingOverride[] overrides: This array
					allows you to override any mapping of the embedded object.
					
			The XEmbeddedMapping's 
			overrides array serves the same purpose as
			standard JPA's AttributeOverrides and
			AssociationOverrides.  In fact,
			you can also use the XMappingOverride 
			annotation on an entity class to override a complex mapping of its
			mapped superclass, just as you can with 
			AttributeOverride and 
			AssociationOverrides.  The XMappingOverrides
			 annotation, whose value is an array of
			XMappingOverrides, allows you to overide
			multiple mapped superclass mappings.
			
			Each
			
			kodo.persistence.jdbc.XMappingOverride
			annotation has the following properties:
			
					String name: The name of the field
					that is being overridden.
					
					Column[] columns: Columns for the new
					field mapping.
					
					XJoinColumn[] joinColumns: Join 
					columns for the new field mapping, if it is a relation 
					field.
					
					ContainerTable containerTable: Table
					for the new collection or map field mapping.  We 
					cover collection mappings in
					Section 7.7.6, “Collections”, and map 
					mappings in
					Section 7.7.8, “Maps”.
					
					ElementColumn[] elementColumns: Element 
					columns for the new collection or map field mapping.
					You will see how to use element columns in
					Section 7.7.6.2, “Element Columns”.
					
					ElementJoinColumn[] elementJoinColumns: 
					Element join columns for the new collection or map 
					field mapping.  You will see how to use element join 
					columns in
					Section 7.7.6.3, “Element Join Columns”.
					
					KeyColumn[] keyColumns: Map key 
					columns for the new map field mapping.
					You will see how to use key columns in
					Section 7.7.8.1, “Key Columns”.
					
					KeyJoinColumn[] keyJoinColumns: 
					Key join columns for the new map field mapping.
					You will see how to use key join columns in
					Section 7.7.8.2, “Key Join Columns”.
					
			The following example defines an embeddable 
			PathCoordinate class with a custom
			mapping of a java.awt.Point field to two
			columns.  It then defines an entity which embeds a 
			PointCoordinate and overrides the default 
			mapping for the point field.  The entity also declares that if the
			PathCoordinate's siteName
			field column is null, it means that no PathCoordinate
			 is stored in the embedded record; the owning field
			will load as null.
			
Example 7.28. Overriding Complex Mappings
import kodo.persistence.jdbc.*;
import org.apache.openjpa.jdbc.persistence.jdbc.*;
@Embeddable
public class PathCoordinate
{
    private String siteName;
    @Persistent
    @Strategy("com.xyz.kodo.PointValueHandler")
    private Point point;
    ...
}
@Entity
public class Path
{
    @Embedded
    @XEmbeddedMapping(nullIndicatorFieldName="siteName", overrides={
        @XMappingOverride(name="siteName", columns=@Column(name="START_SITE")),
        @XMappingOverride(name="point", columns={
            @Column(name="START_X"),
            @Column(name="START_Y")
        })
    })
    private PathCoordinate start;
    ...
}
			In Section 6.3.4, “Persistent Collection Fields”, we 
			explored the PersistentCollection annotation
			for persistent collection fields that aren't a standard
			OneToMany or ManyToMany
			relation.  To map these non-standard collections, combine Kodo's
			ContainerTable annotation with 
			ElementColumns, 
			ElementJoinColumns, or an 
			ElementEmbeddedMapping.  We explore the annotations
			below.
			
				The 
				
				org.apache.openjpa.persistence.jdbc.ContainerTable
				 annotation describes a database table that holds 
				collection (or map) elements.  This annotation has the 
				following properties:
				
String name
String catalog
String schema
						XJoinColumn[] joinColumns
						
						ForeignKey joinForeignKey
						
Index joinIndex
				The name, catalog, 
				schema, and joinColumns
				properties describe the container table and how it joins to 
				the owning entity's table.  These properties correspond 
				to the same-named properties on the standard 
				JoinTable annotation, described in
				Section 12.8.5, “Join Table”.  If left
				unspecified, the name of the table defaults to 
				the first five characters of the entity table name, plus an
				underscore, plus the field name.  The
				joinForeignKey and 
				joinIndex properties override default foreign key
				and index generation for the join columns.  We explore foreign
				keys and indexes later in this chapter.
				
You may notice that the container table does not define how to store the collection elements. That is left to separate annotations, which are the subject of the next sections.
				Just as the JPA Column	
				annotation maps a simple value (primitive wrapper, 
				String, etc), Kodo's
				
				kodo.persistence.jdbc.ElementColumn
				 annotation maps a simple element value.  To map custom
				multi-column elements, use the
				
				kodo.persistence.jdbc.ElementColumns
				 annotation, whose value is an array of 
				ElementColumns.
				
				An ElementColumn always resides in 
				a container table, so it does not have the 
				table property of a standard 
				Column.  Otherwise, the ElementColumn
				 and standard Column 
				annotations are equivalent.  See
				Section 12.3, “Column” in the JPA 
				Overview for a review of the Column
				 annotation.
				
				Element join columns are equivalent to standard JPA
				join columns, except that they represent a join to a collection
				or map element entity rather than a direct relation.  You 
				represent an element join column with Kodo's
				
				org.apache.openjpa.persistence.jdbc.ElementJoinColumn
				 annotation.  To declare a compound join, enclose an
				array of ElementJoinColumns in the
				
				org.apache.openjpa.persistence.jdbc.ElementJoinColumns
				 annotation.
				
				An ElementJoinColumn always resides in 
				a container table, so it does not have the 
				table property of a standard 
				JoinColumn.  Like 
				XJoinColumns above, 
				ElementJoinColumns can reference a linked attribute 
				rather than a static linked column.  Otherwise, the 
				ElementJoinColumn and standard JoinColumn
				 annotations are equivalent.  See
				Section 12.8.4, “Direct Relations” in the JPA 
				Overview for a review of the JoinColumn
				 annotation.
				
				The 
				
				kodo.persistence.jdbc.ElementEmbeddedMapping
				 annotation allows you to map your
				collection or map's embedded element type to your container 
				table.  This annotation has exactly the same properties as the 
				EmbeddedMapping annotation described
				above.
				
				Relational databases do not guarantee that records are returned
				in insertion order.  If you want to make sure that your 
				collection elements are loaded in the same order they were in
				when last stored, you must declare an order column.  Kodo's
				
				org.apache.openjpa.persistence.jdbc.OrderColumn
				annotation has the following properties:
				
						String name:  Defaults to 
						ORDR.
						
boolean enabled
int precision
String columnDefinition
boolean insertable
boolean updatable
				Order columns are always in the container table.
				You can explicitly turn off ordering (if you have enabled it
				by default via your 
				mapping defaults) by setting the enabled
				 property to false.  All other 
				properties correspond exactly to the same-named properties on 
				the standard Column annotation, 
				described in Section 12.3, “Column”.
				

				Our first example maps the Article.subtitles
				field to the ART_SUBS container table, as
				shown in the diagram above.  Notice the use of 
				ContainerTable in combination with 
				ElementColumn and OrderColumn
				 to map this ordered list of strings.
				
Example 7.29. String List Mapping
package org.mag;
import kodo.persistence.jdbc.*;
import org.apache.openjpa.persistence.*;
import org.apache.openjpa.persistence.jdbc.*;
@Entity
@Table(name="ART")
public class Article
{
    @Id private long id;
    @PersistentCollection
    @ContainerTable(name="ART_SUBS", joinColumns=@XJoinColumn(name="ART_ID"))
    @ElementColumn(name="SUBTITLE")
    @OrderColumn(name="ORD")
    private List<String> subtitles;
    ...
}
				Now we map a collection of embedded Address
				 objects for a Company,
				according to the following diagram:
				

Example 7.30. Embedded Element Mapping
package org.mag.pub;
import kodo.persistence.jdbc.*;
import org.apache.openjpa.persistence.*;
import org.apache.openjpa.persistence.jdbc.*;
@Embeddable
public class Address
{
    ...
}
@Entity
@Table(name="COMP")
public class Company
{
    @Id private long id;
  
    @PersistentCollection(elementEmbedded=true)
    @ContainerTable(name="COMP_ADDRS", joinColumns=@XJoinColumn(name="COMP_ID"))
    @ElementEmbeddedMapping(overrides=@XMappingOverride(name="state", 
        columns=@Column(columnDefinition="CHAR(2)")))
    private Collection<Address> addresses;
    ...
}
			The previous section covered the use of ElementJoinColumn
			 annotations in conjunction with a 
			ContainerTable for mapping collections to dedicate 
			tables. ElementJoinColumns, however, have 
			one additional use: to create a one-sided one-many mapping.  
			Standard JPA supports OneToMany 
			fields without a mappedBy inverse, but only by 
			mapping these fields to a JoinTable (see
			Section 12.8.5, “Join Table” in the JPA
			Overview for details).  Often, you'd like to create
			a one-many association based on an inverse foreign key (logical
			or actual) in the table of the related type.
			

			Consider the model above.  Subscription has
			a collection of LineItems, but 
			LineItem has no inverse relation to 
			Subscription.  To retrieve all of the 
			LineItem records for a 
			Subscription, we join the SUB_ID
			inverse foreign key column in the LINE_ITEM
			table to the primary key column of the SUB 
			table.  The example below shows how to represent this model in
			mapping annotations.  Note that Kodo automatically assumes an 
			inverse foreign key mapping when element join columns are given, but
			no container or join table is given.
			
Example 7.31. One-Sided One-Many Mapping
package org.mag.subscribe;
import org.apache.openjpa.persistence.jdbc.*;
@Entity
@Table(name="LINE_ITEM", schema="CNTRCT")
public class LineItem
{
    ...
}
@Entity
@Table(name="SUB", schema="CNTRCT")
public class Subscription
{
    @Id private long id;
    @OneToMany
    @ElementJoinColumn(name="SUB_ID", target="ID")
    private Collection<LineItem> items;
    ...
}
			Section 6.3.5, “Persistent Map Fields” discussed
			the PersistentMap annotation for persistent 
			map fields. To map these non-standard fields to the database, 
			combine Kodo's ContainerTable annotation 
			with KeyColumns, 
			KeyJoinColumns, or an 
			KeyEmbeddedMapping and
			ElementColumns, 
			ElementJoinColumns, or an 
			ElementEmbeddedMapping.
			
			We detailed the ContainerTable annotation in
			Section 7.7.6.1, “Container Table”.
			We also discussed element columns, join columns, and embedded 
			mappings in Section 7.7.6.2, “Element Columns”,
			Section 7.7.6.3, “Element Join Columns”, and
			Section 7.7.6.4, “Element Embedded Mapping”.
			Key columns, join columns, and embedded mappings are new, however;
			we tackle them below.
			
				Key columns serve the same role for map keys as the element 
				columns described in 
				Section 7.7.6.2, “Element Columns” serve for 
				collection elements.  Kodo's
				
				kodo.persistence.jdbc.KeyColumn
				 annotation represents a map key.  To map custom
				multi-column keys, use the
				
				kodo.persistence.jdbc.KeyColumns
				 annotation, whose value is an array of 
				KeyColumns.
				
				A KeyColumn always resides in 
				a container table, so it does not have the 
				table property of a standard 
				Column.  Otherwise, the KeyColumn
				 and standard Column 
				annotations are equivalent.  See
				Section 12.3, “Column” in the JPA 
				Overview for a review of the Column
				 annotation.
				
				Key join columns are equivalent to standard JPA
				join columns, except that they represent a join to a map
				key entity rather than a direct relation.  You represent
				a key join column with Kodo's
				
				kodo.persistence.jdbc.KeyJoinColumn
				 annotation.  To declare a compound join, enclose an
				array of KeyJoinColumns in the
				
				kodo.persistence.jdbc.KeyJoinColumns
				 annotation.
				
				A KeyJoinColumn always resides in 
				a container table, so it does not have the 
				table property of a standard 
				JoinColumn.  Like 
				XJoinColumns above, 
				KeyJoinColumns can reference a linked field 
				rather than a static linked column.  Otherwise, the 
				KeyJoinColumn and standard JoinColumn
				 annotations are equivalent.  See
				Section 12.8.4, “Direct Relations” in the JPA 
				Overview for a review of the JoinColumn
				 annotation.
				
				The 
				
				kodo.persistence.jdbc.KeyEmbeddedMapping
				 annotation allows you to map your map field's embedded
				key type to your container table.  This annotation has exactly 
				the same properties as the 
				EmbeddedMapping annotation described
				above.
				

				Map mapping in Kodo uses the same principles you saw in 
				collection mapping.  The example below maps the 
				Article.authors map according to the diagram above.
				
Example 7.32. String Key, Entity Value Map Mapping
package org.mag.pub;
import kodo.persistence.jdbc.*;
import org.apache.openjpa.persistence.*;
import org.apache.openjpa.persistence.jdbc.*;
@Entity
@Table(name="AUTH")
@DataStoreIdColumn(name="AID" columnDefinition="INTEGER64")
public class Author
{
    ...
}
package org.mag;
@Entity
@Table(name="ART")
public class Article
{
    @Id private long id;
 
    @PersistentMap
    @ContainerTable(name="ART_AUTHS", joinColumns=@XJoinColumn(name="ART_ID"))
    @KeyColumn(name="LNAME")
    @ElementJoinColumn(name="AUTH_ID")
    private Map<String,Author> authors;
    ...
}
Kodo uses index information during schema generation to index the proper columns. Kodo uses foreign key and unique constraint information during schema creation to generate the proper database constraints, and also at runtime to order SQL statements to avoid constraint violations while maximizing SQL batch size.
Kodo assumes certain columns have indexes or constraints based on your mapping defaults, as detailed in Section 7.4, “Mapping Defaults”. You can override the configured defaults on individual joins, field values, collection elements, map keys, or map values using the annotations presented in the following sections.
				The 
				
				org.apache.openjpa.persistence.jdbc.Index
				annotation represents an index on the columns of a field.  It
				is also used within the 
				
				ConterainTable annotation to index join 
				columns.
				
				To index the columns of a collection or map element or map key, 
				use the
				
				
				org.apache.openjpa.persistence.jdbc.ElementIndex and
				
				kodo.persistence.jdbc.KeyIndex
				annotations, respectively.  These annotations have the
				following properties:
				
						boolean enabled: Set this property
						to false to explicitly tell Kodo not
						to index these columns, when Kodo would otherwise do so.
						
						String name: The name of the index.
						Kodo will choose a name if you do not provide one.
						
						boolean unique: Whether to create
						a unique index.  Defaults to false.
						
				The 
				
				org.apache.openjpa.persistence.jdbc.ForeignKey
				annotation represents a foreign key on the columns of a field.
				It is also used within the 
				
				ContainerTable
				annotation to set a database foreign key on join columns.
				
				To set a constraint to the columns of a collection or map
				element or map value, use the
				
				
				org.apache.openjpa.persistence.jdbc.ElementForeignKey and
				
				
				kodo.persistence.jdbc.KeyForeignKey
				annotations, respectively.  These annotations 
				have the following properties:
				
						boolean enabled: Set this property
						to false to explicitly tell Kodo not
						to set a foreign key on these columns, when Kodo would 
						otherwise do so.
						
						String name: The name of the foreign
						key.  Kodo will choose a name if you do not provide one,
						or will create an anonymous key.
						
						boolean deferred: Whether to create
						a deferred key if supported by the database.
						
						ForeignKeyAction deleteAction: 
						Value from the 
						
						org.apache.openjpa.persistence.jdbc.ForeignKeyAction
						 enum identifying the desired 
						delete action.  Defaults to RESTRICT.
						
						ForeignKeyAction updateAction: 
						Value from the 
						
						org.apache.openjpa.persistence.jdbc.ForeignKeyAction
						 enum identifying the desired 
						update action.  Defaults to RESTRICT.
						
Keep in mind that Kodo uses foreign key information at runtime to avoid constraint violations; it is important, therefore, that your mapping defaults and foreign key annotations combine to accurately reflect your existing database constraints, or that you configure Kodo to reflect on your database schema to discover existing foreign keys (see Section 4.13.2, “Schema Factory”).
				The 
				
				org.apache.openjpa.persistence.jdbc.Unique
				annotation represents a unqiue constraint on the columns of a 
				field.  It is more convenient than using the 
				uniqueConstraints property of standard JPA
				Table and SecondaryTable
				 annotations, because you can apply it directly to
				the constrained field.  The Unique 
				annotation has the following properties:
				
						boolean enabled: Set this property
						to false to explicitly tell Kodo not
						to constrain these columns, when Kodo would otherwise 
						do so.
						
						String name: The name of the 
						constraint.  Kodo will choose a name if you do not 
						provide one, or will create an anonymous constraint.
						
						boolean deferred: Whether to create
						a deferred constraint if supported by the database.
						
Here again is our map example from Section 7.7.8, “Maps”, now with explicit indexes and constraints added.

Example 7.33. Constraint Mapping
package org.mag.pub;
import kodo.persistence.jdbc.*;
import org.apache.openjpa.persistence.*;
import org.apache.openjpa.persistence.jdbc.*;
@Entity
@Table(name="AUTH")
@DataStoreIdColumn(name="AID" columnDefinition="INTEGER64")
public class Author
{
    ...
}
package org.mag;
@Entity
@Table(name="ART")
public class Article
{
    @Id private long id;
 
    @PersistentMap
    @ContainerTable(name="ART_AUTHS", joinColumns=@XJoinColumn(name="ART_ID")
        joinForeignKey=@ForeignKey(deleteAction=ForeignKeyAction.CASCADE))
    @KeyColumn(name="LNAME")
    @KeyIndex(name="I_AUTH_LNAME")
    @ElementJoinColumn(name="AUTH_ID")
    @ElementForeignKey(deleteAction=ForeignKeyAction.RESTRICT)
    private Map<String,Author> authors;
    ...
}