| Google App Engine and Java Persistence API and Java Data Objects  You can also use the low-level API that is GAE specific  
        com.google.appengin.api.datastore.* packagesometimes this is a necessity to use (as JPA,JDO do not have same functionality)however if you can use JPA or JDO, do so as then your webapp will be more portable (moving to a not GAE web app environment) 
        see more   JPA configuration file in GAE  , 
        
          location = WAR's WEB-INF/classes/META-INF/ 
         Eclipse Development location =  can 
            create this file in the src/META-INF/ directory, and Eclipse will copy it to the final 
            location automatically. 
        
          
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
         http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <persistence-unit name="transactions-optional">
    <provider>
         org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider
    </provider>
    <properties>
       <property name="datanucleus.NontransactionalRead" value="true"/>
      <property name="datanucleus.NontransactionalWrite" value="true"/>
       <property name="datanucleus.ConnectionURL" value="appengine"/>
    </properties>
  </persistence-unit>
</persistence>
             
 
 Above Explained
               use the "appengine" adapter.                allow reads and writes outside of transactions (NontransactionalRead andNontransactionalWrite are true)
 named this configuration set "transactions-optional" to match.  - javax.persistence.EntityManagerFactory to load persistence.xml configuration named specification (see above persistence.xml that has a "transactions-optional" persistence unit defined) - using @Entity in plain java class to repesent Data Object to store
 
  
    
      Using Plain Java Objects makes it easy to test application with out datastore ---make instances of the class@Entity = means this entity will be associated with the Kind of classname = Book
      
        
          import java.util.Dateimport java.util.Date;import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 @Entity
 public class Book {
 //.....
 }     
    
      @Entity(name = "Book")
        = this entity stored in kind Book
      @Table(name = "BookItem")        = alternative kind name
      Properties = title,author, copyrightYear, authorBirthdate
      @Id        =  key name for Entity (IF PROPERTY IS STRING)  OR key id for Entity (when property is long) --in case of key name the application 
        must set this field before saving the object for the first time.
       @GeneratedValue(strategy = GenerationType.IDENTITY)       = tell JPA to let GAE assign a unique numeric ID instead of using an app provided
        key name string.
        
          
            
              import java.util.Dateimport java.util.Date;import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 @Entity(name = "Book")
 @Table(name = "BookItem")
 public class Book {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;
 private String title;
 private String author;
 private int copyrightYear;
 private Date authorBirthdate;
 public Long getId() {
 return id;
 }
 public String getTitle() {
 return title;
 }
 public void setTitle(String title) {
 this.title = title;
 }
    public String getAuthor() {
 return author;
 }
 public void setAuthor(String author) {
 this.author = author;
 }
 public int getCopyrightYear() {
 return copyrightYear;
 }
 public void setCopyrightYear(int copyrightYear) {
 this.copyrightYear = copyrightYear;
 }
 public Date getAuthorBirthdate() {
 return authorBirthdate;
 }
 public void setAuthorBirthdate(Date authorBirthdate) {
 this.authorBirthdate = authorBirthdate;
 }
 }
     
    
      
        
          
            
     import javax.persistence.Entity;
     import javax.persistence.Id;
     import com.google.appengine.api.datastore.Key;
     @Entity(name = "Book")
     public class Book {
        @Id
private Key id;
     // ...
     } 
      
        
         
    
      
        
          
            import javax.persistence.Entity;import javax.persistence.Id;
 import org.datanucleus.jpa.annotations.Extension;
 import com.google.appengine.api.datastore.Key;
 @Entity(name = "Book")
 public class Book {
 @Id
 @Extension(vendorName = "datanucleus",
 key = "gae.encoded-pk", 
              value = "true")
 private String id;
 // ...
 }
 Class variables/fields = 
   properties of Entity and (in general) will be stored to GAE datastore ---  SOME GAE datatypes must specify should be saved by using @Basic TO SAY NOT TO SAVE class variables use the @Transient 
    
      
        
          import java.util.List;
   import javax.persistence.Basic;
   import javax.persistence.Id;
   import javax.persistence.Transient;
   import com.google.appengine.api.datastore.ShortBlob;
   @Entity(name = "Book")
   public class Book {
       // ...
      private String title; // saved
      @Basic // saved
      private ShortBlob coverIcon;
      @Basic // saved
      private List<String> tags;
 @Transient // not saved
      private int debugAccessCount;
   }
   OTHER annotations and important ideas 
  @Column - change the name of the Entity property NOT EQUAL to class variable name 
    
      
        
     import javax.persistence.Column;
     import javax.persistence.Entity;
     @Entity(name = "Book")
     public class Book {
           // ...
            @Column(name = "long_description")    //now called long_description NOT longDescription
            private String longDescription;
     } @Extension = do NOT include this property in Index 
    
      
        import org.datanucleus.jpa.annotations.Extension;
 @Entity(name = "Book")
 public class Book {
 // ...
 @Extension(vendorName = "datanucleus",
 key = "gae.unindexed",
 value = "true")
 private String firstSentence;
 }
 @Embeddable - declare a class that will be used as the type of an Entity Class's property (class varible) 
    
      Fields of embedded classes are stored as separate propertiesCan Query them ----e.g. 
         publisher.name
        
import javax.persistence.Embeddable;
import javax.persistence.Entity;
@Embeddable
public class Publisher {
     private String name;
     private String address;
     private String city;
     private String stateOrProvince;
     private String postalCode;
     // ...
}
@Entity(name = "Book")
public class Book {
     // ...private Publisher publisher;       //the Entity property (class variable) publisher is instance of Publisher, the Embeddable class}
 Collection data variables = Collection types are stored as multivalued properties in iteration order.  Multivalued Properties =When loaded 
    into the data class, multivalued properties are converted back into the specified collection
    type.
  - creating/saving Objects 
  : Create Entity Manager for each Request Handler, ---use the EntityManagerFactory to create an
    EntityManager.  : Use Entity Manager to save, fetch, delete objects 
    
      
        CREATION = 1) create instance of an @Entity java class, 2)  call EntityManager's persist()  
          If you create an object with a complete key, and an entity with that key already existsin the datastore, saving the new object will overwrite the old one.
 : Close Entity Manager 
    
      
     import javax.persistence.EntityManager;
     import javax.persistence.EntityManagerFactory;
     import myapp.EMF; // where "myapp" is your app's package
     // ...
     EntityManagerFactory emf = EMF.get();
     EntityManager em = null;
     try {
         em = emf.createEntityManager();     //STEP 1
         
         // ... do datastore stuff ...
     } finally {
        book = new Book();    //CREATE ENTITYbook.title = "The Grapes of Wrath";   //SET POPERTIES
 // ask book Entity to be added to datastore via EntityManager
 em.persist(book);
        em.close();     //STEP 3
     }
    -  fetching  Objects 
  : Create Entity Manager for each Request Handler, ---use the EntityManagerFactory to create an
    EntityManager.  : Use Entity Manager to save, fetch, delete objects 
    
      
        FETCHING = use EntityManager.find(NameofJavaDataClass.class, "key");
          2nd parameter = a string key name, a numeric ID, a datastore.Key object,
            or a string-encoded complete key : Close Entity Manager 
    
      
// em is EntityManager Instance
Book book = em.find(Book.class, "9780596156732");   //find Entity associated with Book.java class with key 9780****if (book == null) {
 // not found
 }
    - updating Objects 
  : Create Entity Manager for each Request Handler, ---use the EntityManagerFactory to create an
    EntityManager.  : Use Entity Manager to find the data object you want to update or get passed one from some other part of the code  AND then alter its properties : Either call EntityManager.persist(entity_object) or when you Close Entity Manager em.close() it will commite the changes to the datastore. 
    
      
// em is EntityManager Instance
Book book = em.find(Book.class, "9780596156732");   //find Entity associated with Book.java class with key 9780****if (book == null) {
 // not found
 }
//change values
book.author = "Lynne Grewe";
em.persist(book);
    - deleting Objects 
  : Create Entity Manager for each Request Handler, ---use the EntityManagerFactory to create an
    EntityManager.  : Use Entity Manager to find the data object you want to update  : Either call EntityManager.remove(entity_object)  
    
      
// em is EntityManager Instance
Book book = em.find(Book.class, "9780596156732");   //find Entity associated with Book.java class with key 9780****if (book == null) {
 // not found
 }
//delete object book
em.remove(book);
 
    - OPTIONALY creating Transaction 
  Similar to Low-level API for Tansaction   You call a method on the entity manager to create a Transaction object, then call methodson the object to begin and commit or roll back the transaction.
 
 NOTE: The JPA  knows nothing of GAE's local transactions and entity groups. Application must group appropriateoperations together
     import javax.persistence.EntityTransaction;
     // ...
     EntityTransaction txn = em.getTransaction();
     txn.begin();
     try {
         Book book = em.find(Book.class, "9780596156732");
         BookReview bookReview = new BookReview();
         bookReview.setRating(5);
         book.getBookReviews().add(bookReview);
         // Persist all updates and commit.
         txn.commit();
     } finally {
         if (txn.isActive()) {
            txn.rollback();
        }
     } |