<document>
  <header>
    <product>resin</product>
    <title>Amber</title>
    <type>contents</type>

    <description>
      <p>
      Amber is Resin's implementation of the
      JPA 1.0 persistence specification, focusing on simplicity and
      quality.
      </p>
    </description>
  </header>

<body>

<localtoc/>

<s1 title="See Also">

<ul>
<li>See <a href="../examples/amber-basic/index.xtp">Basic tutorial</a> for
a complete single-table example.</li>
<li>See <a href="../examples/amber-many2one/index.xtp">Many-to-one tutorial</a> for basic relations.</li>
</ul>

</s1>

<s1 title="Quick Start">

<ol>
<li>Expected SQL for the database</li>
<li>Entity bean implementation</li>
<li>Servlet loading, querying, and persisting</li>
<li>persistence.xml configuration</li>
<li>resin-web.xml configuration</li>
</ol>

<example title="Example: House SQL">
create table HOUSE (
  id integer auto_increment,
  name varchar(255)
)
</example>

<example title="Example: House entity">
package demo;

import javax.persistence.*;

@Entity
public class House {
  @Id
  @Column(name="id")
  @GeneratedValue
  private int _id;

  @Basic
  @Column(name="name")
  private String _name;
}
</example>

<example title="Example: HouseServlet">
package demo;

import javax.ejb.*;
import javax.servlet.*;
import javax.persistence.*;

public class HouseServlet extends GenericServlet {
  @PersistenceUnit("test") EntityManagerFactory _factory;

  public void load(PrintWriter out)
  {
    EntityManager amber = _factory.createEntityManager();

    try {
      House house = amber.find(House.class, 1);

      out.println("House: " + house);
    } finally {
      amber.close();
    }
  }

  public void query(PrintWriter out)
  {
    EntityManager amber = _factory.createEntityManager();

    try {
      Query query = amber.createQuery("select o from House o WHERE o.id=1");

      out.println("House: " + query.getSingleResult());
    } finally {
      amber.close();
    }
  }

  @TransactionAttribute
  protected void insert(PrintWriter out)
  {
    EntityManager amber = _factory.createEntityManager();

    try {
      House house = new House("Gryffindor");

      amber.persist(house);
    } finally {
      amber.close();
    }
  }
}
</example>

<example title="META-INF/persistence.xml">
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

  &lt;persistence-unit name="test">
  &lt;/persistence-unit>

&lt;/persistence>
</example>

<example title="WEB-INF/resin-web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;ejb-server database="jdbc/test"/>

  &lt;servlet-mapping url-pattern="/test"
                    servlet-class="demo.HouseServlet"/>

&lt;/web-app>
</example>

</s1>

<s1 title="API">

<s2 title="EntityManager">

<def title="javax.persistence.EntityManager">
public interface EntityManager {
  public &lt;T> T find(Class&lt;T> entityCLass, Object primaryKey);
  public &lt;T> T getReference(Class&lt;T> entityClass, Object primaryKey);

  public void flush();
  public &lt;T> T merge(T entity);
  public void persist(Object entity);
  public void refresh(Object entity);
  public void remove(Object entity);

  public FlushModeType getFlushMode();
  public void setFlushMode(FlushModeType flushMode);

  public Query createQuery(String ql);
  public Query createNamedQuery(String name);
  public Query createNativeQuery(String sql);
  public Query createNativeQuery(String sql, Class resultClass);
  public Query createNativeQuery(String sql, String resultSEtMapping);

  public void clear();
  public void close();
  public boolean contains(Object entity);
  public Object getDelegate();
  public boolean isOpen();

  public EntityTransaction getTransaction();
  public void joinTransaction();
  public void lock(Object entity, LockModeType lockMode);
}
</def>

</s2>

<s2 title="EntityManagerFactory">

<def title="javax.persistence.EntityManagerFactory">
public interface EntityManagerFactory {
  public EntityManager createEntityManager();
  public EntityManager createEntityManager(Map map);

  public void close();
  public boolean isOpen();
}
</def>

</s2>

<s2 title="EntityTransaction">

<def title="javax.persistence.EntityTransaction">
public interface EntityTransaction {
  public void begin();
  public void commit();
  public void rollback();

  public boolean getRollbackOnly();
  public void setRollbackOnly();
  public boolean isActive();
}
</def>

</s2>

<s2 title="Query">

<def title="javax.persistence.Query">
public interface Query {
  public List getResultList();
  public Object getSingleResult();
  public int executeUpdate();

  public Query setFirstResult(int startPosition);
  public Query setFlushMode(FlushModeType flushMode);
  public Query setHint(String hintName, Object value);
  public Query setMaxResults(int maxResult);

  public Query setParameter(String name, Object value);
  public Query setParameter(String name, Date date, TemporalType type); 
  public Query setParameter(String name, Calendar date, TemporalType type); 
  public Query setParameter(int pos, Object value);
  public Query setParameter(int pos, Date date, TemporalType type); 
  public Query setParameter(int pos, Calendar date, TemporalType type);
}
</def>

</s2>

</s1>

<s1 title="Annotations">

<s2 title="Class Annotations">

<s3 title="@DiscriminatorColumn">

<p>Configures the discriminator column, which select the entity class
in an inheritance relationship.  Each entity class will have a
column value which uniquely selects the class to be loaded.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The name of the column</td>
  <td></td>
</tr>
<tr>
  <td>discriminatorType</td>
  <td>The column type: STRING, CHAR or INTEGER</td>
  <td>STRING</td>
</tr>
<tr>
  <td>columnDefinition</td>
  <td>SQL definition used when creating the column</td>
  <td></td>
</tr>
<tr>
  <td>length</td>
  <td>default VARCHAR length when creating a STRING column</td>
  <td>31</td>
</tr>
</deftable>

<def title="javax.persistence.DiscriminatorColumn">
@Target(TYPE)
@Retention(RUNTIME)
public @interface DiscriminatorColumn {
  String name() default "";
  DiscriminatorType discriminatorType() default STRING;
  String columnDefinition() default "";
  int length() default 31;
}
</def>

</s3>

<s3 title="@Embeddable">

<p>Annotates the class as an embeddable value.  The class fields will
represent a collection of table columns embedded as part of a
containing class for the table.
</p>

<def title="javax.persistence.Embeddable">
@Target(TYPE)
@Retention(RUNTIME)
public @interface Embeddable {
}
</def>

</s3>

<s3 title="@Entity">

<p>Annotates the class as an entity bean.</p>

<p>See the <a href="../examples/amber-basic/index.xtp">basic property tutorial</a>
and the <a href="../examples/amber-basic-field/index.xtp">basic field tutorial</a>
for an introduction.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The name of the bean</td>
  <td>The class name (unqualified)</td>
</tr>
</deftable>

<def title="javax.persistence.Entity">
@Target(TYPE)
@Retention(RUNTIME)
public @interface Entity {
  String name() default "";
}
</def>

<p>The fields or properties will be annotated by @Id, @Basic, etc.
Amber will detect either field or property annotation by the
type for the @Id.  In other words, if Amber sees an @Id on a field,
it will use field access.  If Amber sees @Id on a method, it will use
property access.</p>

</s3>

<s3 title="@IdClass">

<p>The <code>@IdClass</code> annotation specifies the class to be used
to contain a compount primary key.
</p>

<def title="javax.persistence.IdClass">
@Target({TYPE})
@Retention(RUNTIME)
public @interface IdClass {
  Class value();
}
</def>

</s3>

<s3 title="@Inheritance">

<p>@Inheritance marks the entity bean as supporting inheritance,
i.e. the database maps to different Java classes depending on
a discriminator value.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>strategy</td>
  <td>The mapping strategy for inheritance: SINGLE_TABLE,
      JOINED or TABLE_PER_CLASS </td>
  <td>SINGLE_TABLE</td>
</tr>
</deftable>

<def title="javax.persistence.Inheritance">
@Target(TYPE)
@Retention(RUNTIME)
public @interface Inheritance {
  InteritanceType strategy() default SINGLE_TABLE;
}
</def>

</s3>

<s3 title="@MappedSuperclass">

<p>The <code>@MappedSuperclass</code> annotation marks the class
as a parent class to an <code>@Entity</code>.
</p>

<def title="javax.persistence.MappedSuperclass">
@Target({TYPE})
@Retention(RUNTIME)
public @interface MappedSuperclass {
}
</def>

</s3>

<s3 title="@SecondaryTable">

<p>Specifies a secondary database table for an entity bean.
The secondary table will contain the fields with a secondaryTable
in the @Column.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The name of the table</td><td>The unqualified class name.</td>
</tr>
<tr>
  <td>catalog</td>
  <td>the table's catalog</td>
  <td>none</td>
</tr>
<tr>
  <td>schema</td>
  <td>the table's schema</td><td>none</td>
</tr>
<tr>
  <td>pkJoinColumns</td>
  <td>join column to the primary table</td>
  <td>joins the primary key</td>
</tr>
<tr>
  <td>uniqueConstraint</td>
  <td>unique constraints during generation</td>
  <td>none</td>
</tr>
</deftable>

<def title="javax.persistence.SecondaryTable">
@Target(TYPE)
@Retention(RUNTIME)
public @interface SecondaryTable {
  String name() default "";
  String catalog() default "";
  String schema() default "";
  PrimaryKeyJoinColumn []pkJoinColumns() default {};
  UniqueConstraint []uniqueConstraints() default {};
}
</def>

</s3>

<s3 title="@SequenceGenerator">

<p>Specifies a sequence table to be used for generating keys.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The amber name of the sequence table</td>
  <td>required</td>
</tr>
<tr>
  <td>sequenceName</td>
  <td>The SQL name of the sequence table</td>
  <td><var>name</var></td>
</tr>
<tr>
  <td>initialValue</td>
  <td>The initial value to seed the generator</td>
  <td>0</td>
</tr>
<tr>
  <td>allocationSize</td>
  <td>The number of values to increment by for each allocation</td>
  <td>50</td>
</tr>
</deftable>

<def title="javax.persistence.SequenceGenerator">
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator {
  String name();
  String sequenceName() default "";
  int initialValue() default 0;
  int allocationSize() default 50;
}
</def>

</s3>

<s3 title="@Table">

<p>Specifies the database table for an entity bean.  The
default table name is the class name.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The name of the table</td>
  <td>The unqualified class name.</td>
</tr>
<tr>
  <td>catalog</td>
  <td>the table's catalog</td>
  <td>none</td>
</tr>
<tr>
  <td>schema</td>
  <td>the table's schema</td>
  <td>none</td>
</tr>
<tr>
  <td>uniqueConstraint</td>
  <td>unique constraints during generation</td>
  <td>none</td>
</tr>
</deftable>

<def>
package javax.persistence;

@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
  String name() default "";
  String catalog() default "";
  String schema() default "";
  UniqueConstraint []uniqueConstraints() default {};
}
</def>

</s3>

<s3 title="@TableGenerator">

<p>Specifies a secondary table to be used for generating keys.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The amber name of the generator table</td>
  <td>required</td>
</tr>
<tr>
  <td>table</td>
  <td>The SQL name of the generator table</td>
  <td><var>name</var></td>
</tr>
<tr>
  <td>catalog</td>
  <td>The SQL catalog of the generator table</td>
  <td></td>
</tr>
<tr>
  <td>schema</td>
  <td>The SQL schema of the generator table</td>
  <td></td>
</tr>
<tr>
  <td>pkColumnName</td>
  <td>The SQL column name for the primary key name</td>
  <td></td>
</tr>
<tr>
  <td>valueColumnName</td>
  <td>The SQL column name for the value</td>
  <td></td>
</tr>
<tr>
  <td>pkColumnName</td>
  <td>The SQL column name for the primary key's value</td>
  <td></td>
</tr>
<tr>
  <td>initialValue</td>
  <td>The initial value to seed the generator</td>
  <td>0</td>
</tr>
<tr>
  <td>allocationSize</td>
  <td>The number of values to increment by for each allocation</td>
  <td>50</td>
</tr>
<tr>
  <td>uniqueConstraints</td>
  <td>Extra uniqueness constraints when creating the table</td>
  <td></td>
</tr>
</deftable>

<def title="javax.persistence.TableGenerator">
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface TableGenerator {
  String name();
  String table() default "";
  String catalog() default "";
  String schema() default "";
  String pkColumnName() default "";
  String valueColumnName() default "";
  String pkColumnValue() default "";
  int initialValue() default 0;
  int allocationSize() default 50;
  UniqueConstraint []uniqueConstraints() default {};
}
</def>

</s3>

</s2>

<s2 title="Property Annotations">

<s3 title="@Basic">

<p>Marks a field as a persistent field.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>fetch</td>
  <td>EAGER or LAZY fetching</td><td>FetchType.EAGER</td>
</tr>
<tr>
  <td>optional</td>
  <td>if true, the column may be null</td>
  <td>true</td>
</tr>
</deftable>

<def title="javax.persistence.Basic">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Basic {
  FetchType fetch() default EAGER;
  boolean optional() default true;
}
</def>

<p>The fetch types are:
</p>

<ul>
<li>EAGER - fetch the field when the bean is loaded</li>
<li>LAZY - fetch the field only when the field is used</li>
</ul>

<example title="Example: string property ">
@Entity
public class Course {
  @Basic
  public String getName()

  ...
}
</example>

<example title="Example: lazy-loaded property ">
@Entity
public class Course {
  @Basic(fetch=FetchType.LAZY)
  public String getMassiveText()

  ...
}
</example>

</s3>

<s3 title="@Column">

<p>Specifies the field's SQL column name as well as any CREATE TABLE
properties for auto generation.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The SQL name of the column</td>
  <td>the field name</td>
</tr>
<tr>
  <td>unique</td>
  <td>True for UNIQUE columns</td>
  <td>false</td>
</tr>
<tr>
  <td>nullable</td>
  <td>False for IS NOT NULL columns</td>
  <td>true</td>
</tr>
<tr>
  <td>insertable</td>
  <td>True if column is inserted on as SQL <code>INSERT</code> call</td>
  <td>true</td>
</tr>
<tr>
  <td>updatable</td>
  <td>True if column is updated when the field is modified</td>
  <td>false</td>
</tr>
<tr>
  <td>columnDefinition</td>
  <td>SQL to create the column in a CREATE TABLE</td>
  <td>none</td>
</tr>
<tr>
  <td>table</td>
  <td>specified if column is stored in a secondary table</td>
  <td>none</td>
</tr>
<tr>
  <td>length</td>
  <td>the default length for a VARCHAR for a CREATE TABLE</td>
  <td>255</td>
</tr>
<tr>
  <td>precision</td>
  <td>the default length for a number definition for a CREATE TABLE</td>
  <td>0</td>
  </tr>
<tr>
  <td>scale</td>
  <td>the default length for a number definition for a CREATE TABLE</td>
  <td>0</td>
</tr>
</deftable>

<def title="javax.persistence.Column">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Column {
  String name() default "";
  boolean unique() default false;
  boolean nullable() default true;
  boolean insertable() default true;
  boolean updateable() default true;
  String columnDefinition() default "";
  String table() default "";
  int length() default 255;
  int precision() default 0;
  int scale() default 0;
}
</def>

<example title="Example: @Column for a string property ">
@Entity
public class Course {
  @Basic
  @Column(name="MY_NAME",
          unique=true,
          nullable=false,
          length=32)
  public String getName()

  ...
}
</example>

</s3>

<s3 title="@Embedded">

<p>Marks a field as containing an embeddable value.  The field's value
will be a class marked as @Embeddable.  Applications can use @Embedded
fields to gather columns into meaningful groups.</p>

<def title="javax.persistence.Embedded">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Embedded {
}
</def>

</s3>

<s3 title="@EmbeddedId">

<p>Marks a field as a primary key with a embedded class. The field's
value class must be marked with <code>@Embeddable</code>.   Applications can
use <code>@EmbeddedId</code> to implement compound keys.</p>

<def title="javax.persistence.EmbeddedId">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface EmbeddedId {
}
</def>

</s3>

<s3 title="@Enumerated">

<p>Marks a field as containing an enumerated value.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>value</td>
  <td>Specifies whether the enum's ORDINAL or STRING representation should be saved in the database.</td>
  <td>ORDINAL</td>
</tr>
</deftable>

<def title="javax.persistence.Enumerated">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Enumerated {
  EnumType value() default ORDINAL;
}
</def>

</s3>

<s3 title="@GeneratedValue">

<p>Used with @Id to specify a generator for automatic key generation when new
objects are created.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>generator</td>
  <td>The sequence or table generator name</td>
  <td>${table}_cseq</td>
</tr>
<tr>
  <td>strategy</td>
  <td>The auto-generation type: TABLE, SEQUENCE, IDENTITY or AUTO</td>
  <td>AUTO</td>
</tr>
</deftable>

<p>The generator types are:
</p>

<ul>
<li>IDENTITY - the database supplies the new key, e.g. auto_increment, SERIAL, or IDENTITY</li>
<li>SEQUENCE - use a SEQUENCE type to generate the key</li>
<li>TABLE - use a @TableGenerator for the key</li>
<li>AUTO - choose the generator based on the database
<ul>
  <li>MySQL - IDENTITY using auto_increment</li>
  <li>Resin - IDENTITY using auto_increment</li>
  <li>Postgres - SEQUENCE</li>
  <li>Oracle - SEQUENCE</li>
</ul>
</li>
</ul>

<def title="javax.persistence.GeneratedValue">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
  GenerationType strategy() default AUTO;
  String generator() default "";
}
</def>

<p>For SEQUENCE and TABLE, Resin will create the sequence
name as "${table}_cseq".</p>

<example title="Example: autoincrement generation">
import javax.persistence.*;

@Entity
public class Course {
  @Id
  @GeneratedValue
  public long getId()

  ...
}
</example>

<example title="Example: sequence generation">
import javax.persistence.*;

@Entity
public class Course {
  @Id
  @GeneratedValue(strategy=GeneratorType.AUTO
                  generator="COURSE_SEQ")
  public long getId()

  ...
}
</example>
</s3>

<s3 title="@Id">

<p>Marks a field as a primary key.  The <code>@Id</code>
may be used in combination with <code>@GeneratedValue</code> to specify a generator for automatic key generation when new
objects are created.</p>

<def title="javax.persistence.Id">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Id {
}
</def>

<p>The default column name is "ID".</p>

<example title="Example: automatic generation">
import javax.persistence.*;

@Entity
public class Course {
  @Id
  @Column(name="t_id")
  @GeneratedValue
  public long getId()

  ...
}
</example>

</s3>

<s3 title="@Lob">

<p>Marks a field as containing a large blob value.</p>

<def title="javax.persistence.Lob">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Lob {
}
</def>

</s3>

<s3 title="@Temporal">

<p>Marks a field as a time-based value.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>value</td>
  <td>The SQL type used for the field value: DATE, TIME or TIMESTAMP</td>
  <td>TIMESTAMP</td>
</tr>
</deftable>

<def title="javax.persistence.Temporal">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Temporal {
  TemporalType value() default TIMESTAMP;
}
</def>

</s3>

<s3 title="@Transient">

<p><code>@Transient</code> makes a field non-persistent.
<code>@Transient</code> fields work like the <code>transient</code>
annotation to prevent properties being saved.</p>

<def title="javax.persistence.Transient">
@Target({METHOD,FIELD})
@Retention(RUNTIME)
public @interface Transient {
}
</def>

</s3>

<s3 title="@Version">

<p><code>@Version</code> marks a version field, used for
optimistic locking.</p>

<def title="javax.persistence.Version">
@Target({METHOD,FIELD})
@Retention(RUNTIME)
public @interface Version {
}
</def>

</s3>

</s2>

<s2 title="Relation annotations">

<s3 title="@JoinColumn">

<p>Defines a join (foreign) columns.  Used for <a href="#@ManyToOne">@ManyToOne</a>.</p>

<p>See also <a href="#@Column">@Column</a> for
corresponding definition for <a href="#@Basic">@Basic</a> columns.</p>

<p>See the <a href="../examples/amber-many2one/index.xtp">Many-to-One
tutorial</a> for a full example.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The column name of the source table</td><td>the column name of the target key</td>
</tr>
<tr>
  <td>referencedColumnName</td>
  <td>The target column for composite keys</td><td>the single primary key</td>
</tr>
<tr>
  <td>unique</td>
  <td>True if unique</td>
  <td>false</td>
</tr>
<tr>
  <td>nullable</td>
  <td>False if IS NOT NULL</td>
  <td>true</td>
</tr>
<tr>
  <td>insertable</td>
  <td>True if the column is inserted on a <code>create</code></td>
  <td>true</td>
</tr>
<tr>
  <td>updateable</td>
  <td>True if the column is updated on field changes</td>
  <td>true</td>
</tr>
<tr>
  <td>columnDefinition</td>
  <td>SQL column definition</td>
  <td>false</td>
</tr>
<tr>
  <td>table</td>
  <td>specifies a secondary table if not in the primary</td>
  <td>none</td>
</tr>
</deftable>

<def title="javax.persistence.JoinColumn">
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinColumn {
  String name() default "";
  String referencedColumnName() default "";
  boolean unique() default false;
  boolean nullable() default false;
  boolean insertable() default true;
  boolean updateable() default true;
  String columnDefinition() default "";
  String table() default "";
}
</def>

<example title="Example: Student to House link">
public class Student {
  @Id
  @Column(name="student_id")
  long getId()

  @ManyToOne
  @JoinColumn(name="house_id")
  public House getHouse()
}
</example>

<example title="Example: Student SQL">
CREATE TABLE Student {
  student_id BIGINT PRIMARY KEY auto_increment

  house_id BIGINT REFERENCES House(id)
)
</example>

</s3>

<s3 title="@JoinColumns">

<p>Defines a set of join (foreign) columns for composite keys.</p>

<def title="javax.persistence.JoinColumns">
@Target({TYPE,METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinColumns {
  JoinColumn [] value() default{}
}
</def>

</s3>

<s3 title="@JoinTable">

<p>Defines an association table for a many-to-many relation.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>Table definition for the association table</td>
  <td>concatening the source and target table names</td>
</tr>
<tr>
  <td>catalog</td>
  <td>Database catalog</td>
  <td>""</td>
</tr>
<tr><td>schema</td><td>Database schema</td><td>""
</td></tr><tr><td>joinColumns</td><td>Columns from from the association table to the source table</td><td>Uses the source table primary key
</td></tr><tr><td>inverseJoinColumns</td><td>Columns from from the association table to the target table</td><td>Uses the target table primary key
</td></tr></deftable>

<def title="javax.persistence.JoinTable">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface JoinTable {
  String table() default "";
  String catalog() default "";
  String schema() default "";
  JoinColumn []joinColumns() default {};
  JoinColumn []inverseJoinColumns() default {};
  UniqueContraint []uniqueConstraint() default {};
}
</def>

</s3>

<s3 title="@ManyToMany">

<p>Marks a field as a many-to-many (association) relation.</p>

<p>The column names are the key columns of the source and target tables.</p>

<p>See the <a href="../examples/amber-many2many/index.xtp">many-to-many tutorial</a> for an example.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>cascade</td>
  <td>Operations which cascade to the target</td>
  <td>none</td>
</tr>
<tr>
  <td>fetch</td>
  <td>EAGER or LAZY fetching</td>
  <td>FetchType.EAGER</td>
</tr>
<tr>
  <td>mappedBy</td>
  <td>Specifies the source relation if a target</td>
  <td></td>
</tr>
<tr>
  <td>targetEntity</td>
  <td>The class of the target entity</td>
  <td>the property's type</td>
</tr>
</deftable>

<def title="javax.persistence.ManyToMany">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ManyToMany {
  String targetEntity default "";
  CascadeType []cascade() default {};
  FetchType fetch() default LAZY;
  String mappedBy isInverse() default "";
}
</def>

<example title="Example: @ManyToMany link ">
@Entity
public class Student {
  @ManyToMany
  @JoinTable(
    name="student_course_map",
    joinColumns={@JoinColumn(name="student_id")},
    inverseJoinColumns={@JoinColumn(name="course_id")}
  )
  public Collection getCourses()

  ...
}
</example>

</s3>

<s3 title="@ManyToOne">

<p>Marks a field as a many-to-one (link) relation.</p>

<p>The default column name is the column name of the target key.</p>

<p>See the <a href="../examples/amber-many2one/index.xtp">many-to-one tutorial</a> for an example.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>targetEntity</td>
  <td>The class of the target entity</td>
  <td>the property's type</td>
</tr>
<tr>
  <td>cascade</td>
  <td>Operations which cascade to the target: ALL, PERSIST,
      MERGE, REMOVE or REFRESH</td>
  <td>none</td>
</tr>
<tr>
  <td>fetch</td>
  <td>EAGER or LAZY fetching</td>
  <td>FetchType.EAGER</td>
</tr>
<tr>
  <td>optional</td>
  <td>If false, the relation must always have a value</td>
  <td>true</td>
</tr>
</deftable>

<def title="javax.persistence.ManyToOne">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface ManyToOne {
  String targetEntity default "";
  CascadeType []cascade() default {};
  FetchType fetch() default EAGER;
  boolean optional() default true;
}
</def>

<example title="Example: @ManyToOne link ">
@Entity
public class Student {
  @ManyToOne
  @JoinColumn(name="house")
  public House getHouse()

  ...
}
</example>

</s3>

<s3 title="@MapKey">

<p>Marks a field as key in a Map relationship.</p>

<def title="javax.persistence.MapKey">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface MapKey {
  String name() default "";
}
</def>

</s3>

<s3 title="@OneToMany">

<p>Marks a field as a one-to-many (collection) relation.
Because a one-to-many field is dependent, it
needs a @ManyToOne relation on the source table which defines the column.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>targetEntity</td>
  <td>The class of the target entity</td>
  <td>the property's type</td>
</tr>
<tr>
  <td>cascade</td>
  <td>Operations which cascade to the target: ALL, PERSIST, MERGE,
REMOVE, and REFRESH</td>
  <td>none</td>
</tr>
<tr>
  <td>fetch</td>
  <td>EAGER or LAZY fetching</td>
  <td>FetchType.EAGER</td>
</tr>
<tr>
  <td>mappedBy</td>
  <td>Specifies the owning @ManyToOne property on the target entity.</td>
  <td></td>
</tr>
</deftable>

<def title="javax.persistence.OneToMany">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OneToMany {
  String targetEntity default "";
  CascadeType []cascade() default {};
  FetchType fetch() default EAGER;
  String mappedBy() default "";
}
</def>

<example title="Example: collection">
@Entity
public class House {
  ...
  @OneToMany(targetEntity=Student.class,
             mappedBy="house")
  public Collection getStudents()
}

@Entity
public class Student {
  ...
  @ManyToOne
  @JoinColumn(name="house")
  public House getHouse()
}
</example>

<example title="Example: Collection SQL">
CREATE TABLE House {
  id BIGINT PRIMARY KEY
)

CREATE TABLE Student {
  id BIGINT PRIMARY KEY,

  house BIGINT REFERENCES House(id)
)
</example>

</s3>

<s3 title="@OneToOne">

<p>Marks a field as a one-to-one (dependent link) relation.
Because a one-to-one field is dependent, it
needs a @ManyToOne relation on the source table which defines the column.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>targetEntity</td>
  <td>The class of the target entity</td><td>the property's type</td>
</tr>
<tr>
  <td>cascade</td>
  <td>Operations which cascade to the target: ALL, PERSIST, MERGE,
REMOVE, and REFRESH</td>
  <td>none</td>
</tr>
<tr>
  <td>fetch</td>
  <td>EAGER or LAZY fetching</td>
  <td>FetchType.EAGER</td>
</tr>
<tr>
  <td>mappedBy</td>
  <td>Specifies the owning relation</td>
  <td></td>
</tr>
</deftable>

<def title="javax.persistence.OneToOne">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OneToOne {
  String targetEntity default "";
  CascadeType []cascade() default {};
  FetchType fetch() default EAGER;
  boolean optional() default true;
  String mappedBy() default "";
}
</def>

</s3>

<s3 title="@OrderBy">

<p><code>@OrderBy</code> specifies the SQL column to use for ordering
collection relations.</p>

<deftable>
<tr>
  <th>Property</th>
  <th>Description</th>
  <th>Default</th>
</tr>
<tr>
  <td>name</td>
  <td>The property name to sort the collection by.</td>
  <td>the property's type</td>
</tr>
</deftable>

<def title="javax.persistence.OrderBy">
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface OrderBy {
  String value() default "";
}
</def>

</s3>

</s2>

</s1>

<s1 title="Amber Lifecycle">

<s2 title="Non-Transactional Lifecycle">

<p>Amber's non-transactional lifecycle has three important states:</p>

<ul>
<li><b>clean:</b> the bean is loaded from the database</li>
<li><b>dirty:</b> the bean has unwritten changes</li>
<li><b>hollow:</b> the bean is unloaded (lazily-loaded)</li>
</ul>

<p>In the diagram below, the red methods (<code>load()</code>,
<code>getXXX()</code>, and <code>flush()</code>) query and
update the database.</p>

<figure src="amber-non-xa.gif" width="356" height="140"/>

<p>The <code>aConn.load("1")</code> method loads the bean from the
database and transitions to the <var>clean</var> state.</p>

<p>Calling <code>test.setData("foo")</code> will change to
the <var>dirty</var> state.</p>

<p>Calling <code>aConn.flush()</code> writes the changes to
the database and changes to the <var>clean</var> state.  Amber may
also flush the changes and change to the clean state
at any time.  <code>flush()</code> merely guarantees that the changes
will be flushed to the database.</p>

<p>The <var>hollow</var> state represents lazily-loaded entities.  many-to-one
relations and some queries will return the unloaded bean instead of
a loaded bean.  When the application calls a <code>getXXX()</code> method,
the bean will load from the database and change to the <var>clean</var> state.
When the application calls a <code>setXXX()</code> method, the bean
will change to the <var>dirty</var> state.</p>

<example title="Example: Amber outside transaction">
public class MyServlet extends GenericServlet {
  @In EntityManagerFactory _factory;
  @In UserTransaction _trans;

  ...

  public void doTest(PrintWriter out)
    throws IOException
  {
     EntityManager aConn = _factory.createManager();

     // load() loads test and then detaches it
     qa.Test test = aConn.load(qa.Test.class, "1");

     // test has the loaded values
     out.println(test.getData());

     // but parent is not lazily-loaded when detached, i.e. it's null.
     qa.Test parent = test.getParent();

     aConn.close();
  }
}
</example>

</s2>

<s2 title="Transactional Lifecycle">

<p>In a transaction, Amber loads the bean from the
database, even if it was loaded outside of the transaction.
(Exceptions exist for cases like read-only beans.) By loading the
bean in the transaction, Amber lets the database handle the
transactional locking and state consistency.</p>

<p>Just like the non-transactional <var>clean</var> and <var>dirty</var>
states, Amber has transactional <var>clean</var> and <var>dirty</var> states
called <var>Persistent-clean</var> and <var>Persistent-dirty</var>.  As in
the non-transactional case, the <var>hollow</var> state represents
lazily-loaded beans.</p>
<ul>
<li><b>persistent-clean:</b> the bean is loaded from the database
within the transaction</li>
<li><b>persistent-dirty:</b> the bean has been changed</li>
<li><b>hollow:</b> the bean is unloaded (lazily-loaded or rolled-back)</li>
<li><b>persistent-nonXA:</b> the bean was loaded outside of the
transaction (and would need reloading if used in the transaction)</li>
</ul>

<figure src="amber-lifecycle.gif" width="511" height="285"/>

<p>The main differences from the non-transactional lifecycle
are:</p>
<ul>
<li>Transactions need a load from inside the transaction.  Loads
before the transaction cannot be reused.</li>
<li>Updates occur during the commit() call and change to the
nonXA-clean state</li>
<li>Rollbacks change to the hollow state.</li>
</ul>

</s2>
</s1>


<s1 title="Configuration Files">
<s2 title="Example configuration">

<p>The lifecycle description uses a single running example, Test, which
has two properties: <code>getData()</code> which returns a string, and
<code>getParent()</code> which is a pointer to another Test object.</p>

<example title="Example: META-INF/orm.xml">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
   version="1.0"&gt;
  &lt;package&gt;qa&lt;/package&gt;
  &lt;entity name="Test" class="qa.Test" access="PROPERTY"&gt;
    &lt;table name="TEST"/&gt;
      &lt;attributes&gt;
        &lt;id name="id"&gt;
          &lt;column name="ID"/&gt;
        &lt;/id&gt;
        &lt;basic name="data"&gt;
          &lt;column name="DATA"/&gt;
        &lt;/basic&gt;
        &lt;many-to-one name="parent"&gt;
          &lt;join-column name="FK_PARENT"/&gt;
        &lt;/many-to-one&gt;
     &lt;/attributes&gt;
   &lt;/table&gt;
  &lt;/entity&gt;
&lt;/entity-mappings&gt;
</example>

</s2>
</s1>

  </body>
</document>