jpersist
A One-Man Company Where
Donations Are Desperately Needed

Please donate today at SourceForge.net
jWebApp - Java Web Application Framework
Convention Over Configuration

Introducing jPersist

 

Overview

 

jPersist is an extremely powerful object-relational persistence API that is based on the active-record and data-mapper patterns. 

 

jPersist is as easy as:

 

public static void main(String[] args)

  {

    DatabaseManager dbm;

 

    dbm = new DatabaseManager("example", 5, "com.mysql.jdbc.Driver",

                                                       "jdbc:mysql://localhost/example",

                                                       null, null, "username", "password");

 

    Customer customer = new Customer(“Smith”);

 

    if ((customer = dbm.loadObject(customer)) != null)

      {

        customer.setLastName(“Smithman”);

        dbm.saveObject(customer);

      }

 

    dbm.saveObject(new Customer("dbuser1", "passwd", "Dave"));

  }

 

public class Customer [extends PersistentObject or Entity] // optional

  {

    String lastName;

    ...

    public Customer(String lastName) { this.lastName = lastName; }

    ...

    public getLastName() { return lastName; }

    public setLastName(String lastName) { this.lastName = lastName; }

    …

  }

 

Just doesn’t get easier.  If you’re familiar with ORMs (Hibernate, JPA, etc.), then the first thing you might wonder about is the configuration and/or annotations.  With jPersist there is no need for configuration and/or annotations.  jPersist is mapless, in that it has no need for XML or annotation-based mapping.  In reality jPersist has automatic mapping.  jPersist looks at both your class definition and database table definition and automatically figures out what needs to happen when inserting, updating, querying, and deleting.

 

jPersist wraps and uses JDBC functionality and can work with any relational database, and any type of connection resource, including: java.sql.DriverManager, JNDI, javax.sql.DataSource, and third-party connection pooling libraries (DBCP, C3PO, etc.).  jPersist has full support for database transactions and automatically handles transactions with all relationships (inheritance and associations).  Transactions can also be handled with the jpersist.TransactionManager class or manually with beginTransaction(), endTransaction(), commit() and rollback() functionality.  jPersist automatically handles inheritance via multi-table joins, but also supports single-table and concrete-table inheritance.  jPersist easily handles associations with support for arrays, collections, and single-instance objects.  With jPersist, all JDBC functionality is supported and available.

 

jPersist has a database manager class (jpersist.DatabaseManager) that handles pooling of its own resources as well as managing JDBC data sources and connections, as needed (including connection pooling and third party connection pooling libraries).  The database manager also provides several object-oriented access methods (by wrapping jpersist.Database and jpersist.Result calls) that allow queries, inserts, updates, deletes, etc., in a single line of code. 

 

While jpersist.DatabaseManager provides several convenience methods for accessing your data, the real power resides in the jpersist.Database and jpersist.Result classes.

 

An instance of jpersist.Database is retrieved with DatabaseManager’s getDatabase() method. The jpersist.Database and jpersist.Result classes can serve any of the database access needs you may have, from working with stored procedures that return multiple result sets, to automatically loading simple and complex object hierarchies.

 

An example of using jpersist.Database and jpersist.Result:

 

Database db = dbm.getDatabase();

 

Result<Customer> result = db.queryObject(Customer.class);

 

for (Customer customer : result)

  {

    System.out.println(customer);

  }

 

db.close();

 

jpersist.Database has several methods (all JDBC provides) to easily handle transactions, for example:

 

Database db = dbm.getDatabase();

 

db.beginTransaction();

 

try

  {

    db.saveObject(new YourObject(...));

  }

catch (YourException e)

  {

    db.rollback();

  }

finally

  {

    db.endTransaction(); // also commits transaction

  }

 

You can also use the methods commit(),getSavepoint(), and rollback().  And they can be called at anytime.

 

jPersist also has a transaction manager class that allows the following:

 

new TransactionManager(dbm)

  {

    public void run() throws JPersistException

      {

        new Contact("alincoln", "Abraham", "Lincoln", ...).save(this);

        // or

        getDatabase().saveObject(new Contact("alincoln", "Abraham", ...));

        // or just

        saveObject(new Contact("alincoln", "Abraham", ...));

        ...

      }

  }.executeTransaction();

 

 

All in all, jPersist’s sole reason for being is to provide simple trouble-free POJO oriented access to your database data.  With jPersist and your POJOs, you should rarely have to do anything more than:

 

  • Define a POJO (optionally extending jpersist.PersistentObject), which can be extended by other POJOs (relational hierarchy via joins).
  • Call one of jpersist.DatabaseManager’s: loadObject(), saveObject(), and deleteObject(), or one of jpersist.Database’s: saveObject(), deleteObject(), and queryObject() with jpersist.Result’s loadObject().
  • Group saves and deletes in a transaction using jpersist.TransactionManager or jpersist.Database’s transaction oriented methods.
  • Most likely process a query result with:

 

while (result.hasNext())

  {

    MyObject myObj = result.next();

    ...

  }

 

That’s not to say you won’t have other JDBC needs, like calling stored procedures or executing SQL statements, but with jPersist it’s all easy to handle.

 

Requirements

 

jPersist requires Java 1.2 or above and a database with JDBC support.

 

Java Support

 

jPersist has two JAR versions available; one for pre 1.5 environments, and one for 1.5+ environments.  Both have the same functionality.  However, the Java 1.5+ version allows for generics, annotations, variable arguments, dynamic casting, etc. where appropriate. 

 

Supported Databases

 

Right now our focus is on adding support for as many databases as we can, and jPersist currently has complete, and fully tested, support for:

 

MySQL

DB2

Oracle

Derby

HSQL

PostgreSQL

H2

 

You should be able to use jPersist’s complete functionality, without issue, with these databases.  Of course, there is varying support from vendor to vendor for JDBC features.  If your vendor doesn’t support a certain feature (stored procedures, bi-directional cursors, etc.), you’ll find the same is true with jPersist, as it wraps JDBC.

 

Logging

 

jPersist uses Java logging and can be set with:

 

DatabaseManager.setLogLevel(Level);

 

With logging set to Level.FINE, you can see the SQL that is generated for your objects.  You can also access the root logger with “jpersist”.

 

  • Object-relational persistence API
  • A Java implementation of the active-record and data-mapper patterns
  • Mapping is automatic, there is no configuration, or annotation required
  • Objects are isolated from database changes, and vice versa
  • Optionally provides simple annotation/functional support for mapping
  • Full Support for MySQL, DB2, Oracle, Derby, HSQL, PostgreSQL, H2, and more
  • Object-oriented queries, inserts, updates, deletes and more
  • All JDBC functionality is supported at some level
  • Intermix objects with SQL, and use object properties in SQL fragments
  • Full support for database transactions (automatic and manual)
  • Automatically handles inheritance via table joins
  • Also supports single table inheritance and concrete table inheritance
  • Easily handles associations with single instance, arrays, and collections
  • Supports any JDBC source including DriverManager, JNDI, and DataSource
  • Support for third-party connection pooling (DBCP, C3PO, etc.)
  • No SQL required for queries, inserts, updates, deletes
  • Uses JDBC with access to underlying connection, statement and result set
  • Access stored procedures and prepared statements with the same object-oriented functionality
  • Full support for batch updates
  • Implements ListIterator and Iterable for object-oriented iteration through data
  • Tracks object persistence for inserting and updating
  • Can be cast to an interface for database proxying
  • Multiple utilities for loading data into collections and maps
  • and lots more!

Support & Community

All our projects are open source and located on SourceForge.net. All support requests, bug reports, code access, etc. can be found at SourceForge.net

If you would like to contribute code and/or fixes, please send a support request (via SourceForge.net) requesting commit access to our repository.

jPersist & jWebApp will be complete with the release of jPersist2 (except for minor releases). The idea behind these projects is to have as simple an object/relational persistence API, and web development framework as is possible. So we don't want to develop these projects further with the exception of integrations and plug-ins/add-ons.

jPersist & jWebApp can be found at https://sourceforge.net/projects/jpersistjwebapp


Other Requests

Email: cinfo@jpersist.com

Simple Example of jPersist

With the exception of the imports and ellipsis (...), the following is a complete, compilable, and runable program example. For the purposes of this example, the ellipsis are being used to reduce non-essential information. The class definitions and database table creation scripts follow. There are no mapping requirements, no XML and no Annotations.

public class DatabaseExample
  {
    public DatabaseExample(DatabaseManager dbm) throws JPersistException
      {
        // Inserting contact with associations
        Contact contact = new Contact("deisenhower", ...);

        contact.getSupport().add(new Support("Request", ...));
        contact.getSupport().add(new Support("Response", ...));
        contact.getSupport().add(new Support("Request", ...));

        contact.getOrders().add(new Order("Dwight D. Eisenhower Dollar", ...));
        contact.getOrders().add(new Order("Susan B. Anthony Dollar", ...));

        // Saving within an automatic transaction (covers all relationships)
        contact.save(dbm);

        // Load based on information contained in classes
        contact = dbm.loadObject(Contact.class, "where :contactId like 'tjef%'");
        System.out.println("\ncontactId = " + contact.getContactId());

        // Load a collection of objects from the database
        Collection<Contact> c = dbm.loadObjects(new Vector<Contact>(), Contact.class);

        for (Contact contact2 : c)
          System.out.println("contactId = " + contact2.getContactId());
      }

    public static void main(String[] args) throws JPersistException
      {
        DatabaseManager dbm = null;

        try
          {
            DatabaseManager.setLogLevel(Level.OFF);

            dbm = new DatabaseManager("example", 5, "com.mysql.jdbc.Driver", 
                                      "jdbc:mysql://localhost/example", 
                                      null, null, "username", "password");

            new DatabaseExample(dbm);
          }
        finally
          {
            // Also closes any open Databases
            dbm.close();  // optional
          }
      }

    /*
     * The following are normal class definitions that
     * automatically map to database
     */
     
    public static class Contact
      {
        private String contactId, password, firstName, lastName, companyName, email;
        private Vector<Support> support = new Vector<Support>();
        private Vector<Order> orders = new Vector<Order>();

        public Contact() {}

        public Contact(String contactId)
          {
            this.contactId = contactId;
          }

        public Contact(String contactId, String password, String firstName, 
                       String lastName, String companyName, String email)
          {
            this.contactId = contactId;
            this.password = password;
            this.firstName = firstName;
            this.lastName = lastName;
            this.companyName = companyName;
            this.email = email;
          }

        public String getContactId() { return contactId; }
        public void setContactId(String id) { contactId = id; }
        public String getPassword() { return password; }
        public void setPassword(String passwd) { password = passwd; }
        public String getFirstName() { return firstName; }
        public void setFirstName(String fName) { firstName = fName; }
        public String getLast() { return lastName; }
        public void setLast(String lName) { lastName = lName; }
        public String getCompanyName() { return companyName; }
        public void setCompanyName(String name) { companyName = name; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }

        // Associations
        public Vector<Support> getDbAssociation(Support c) { return support; }
        public void setDbAssociation(Support c, Vector<Support> s) { support = s; }
        public Vector<Order> getDbAssociation(Order c) { return orders; }
        public void setDbAssociation(Order c, Vector<Order> o) { orders = o; }
        
        // Association convenience (is optional)
        public Vector<Support> getSupport() { return support; }
        public void setSupport(Vector<Support> support) { this.support = support; }
        public Vector<Order> getOrders() { return orders; }
        public void setOrders(Vector<Order> orders) { this.orders = orders; }
      }
    
    public static class Order
      {
        private Long orderId;
        private Integer quantity;
        private Double price;
        private String contactId, product, status;

        public Order() {}

        public Order(String product, Integer quantity, Double price, String status)
          {
            this.product = product;
            this.quantity = quantity;
            this.price = price;
            this.status = status;
          }

        public Order(String contactId, String product, Integer quantity, 
                     Double price, String status)
          {
            this.contactId = contactId;
            this.product = product;
            this.quantity = quantity;
            this.price = price;
            this.status = status;
          }

        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }
        public String getContactId() { return contactId;}
        public void setContactId(String contactId) { this.contactId = contactId; }
        public String getProduct() { return product; }
        public void setProduct(String product) { this.product = product; }
        public Integer getQuantity() { return quantity; }
        public void setQuantity(Integer quantity) { this.quantity = quantity; }
        public Double getPrice() { return price; }
        public void setPrice(Double price) { this.price = price; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
      }
      
    public static class Support
      {
        private Long supportId;
        private String contactId, code, status, phone, email, request;

        public Support() {}

        public Support(String code, String status, String phone, 
                       String email, String request)
          {
            this.code = code;
            this.status = status;
            this.phone = phone;
            this.email = email;
            this.request = request;
          }

        public Support(String contactId, String code, String status, 
                       String phone, String email, String request)
          {
            this.contactId = contactId;
            this.code = code;
            this.status = status;
            this.phone = phone;
            this.email = email;
            this.request = request;
          }

        public Long getSupportId() { return supportId; }
        public void setSupportId(Long id) { supportId = id; }
        public String getContactId() { return contactId; }
        public void setContactId(String id) { contactId = id; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getRequest() { return request; }
        public void setRequest(String request) { this.request = request; }
      }
  }

# MySQL database creation

CREATE TABLE contacts
  (
    CONTACT_ID varchar(40) NOT NULL PRIMARY KEY,
    PASSWORD varchar(40) NOT NULL,
    FIRST_NAME varchar(40) NOT NULL,
    LAST_NAME varchar(60) NOT NULL,
    COMPANY_NAME varchar(60),
    EMAIL varchar(255),
    CREATED timestamp NOT NULL default CURRENT_TIMESTAMP
  );

CREATE TABLE orders
  (
    ORDER_ID int(11) NOT NULL auto_increment PRIMARY KEY,
    CONTACT_ID varchar(40) NOT NULL,
    PRODUCT varchar(40) NOT NULL,
    QUANTITY int(11) NOT NULL,
    PRICE double NOT NULL,
    STATUS varchar(20) NOT NULL default 'unverified',
    created timestamp NOT NULL default CURRENT_TIMESTAMP,
    FOREIGN KEY (CONTACT_ID) REFERENCES contacts (CONTACT_ID) ON DELETE CASCADE
  );

CREATE TABLE support
  (
    SUPPORT_ID int(11) NOT NULL auto_increment PRIMARY KEY,
    CONTACT_ID varchar(40) NOT NULL,
    CODE varchar(10) NOT NULL,
    STATUS varchar(20) NOT NULL,
    PHONE varchar(20),
    EMAIL varchar(255),
    REQUEST varchar(255) NOT NULL,
    CREATED timestamp NOT NULL default CURRENT_TIMESTAMP,
    FOREIGN KEY (CONTACT_ID) REFERENCES contacts (CONTACT_ID) ON DELETE CASCADE
  );

In-Depth Example of jPersist

With the exception of the imports and ellipsis (...), the following is a complete, compilable, and runable program example. For the purposes of this example, the ellipsis are being used to reduce non-essential information. The class definitions and database table creation scripts follow. There are no mapping requirements, no XML and no Annotations.

public class DatabaseExample
  {
    public DatabaseExample(DatabaseManager dbm) throws JPersistException
      {
        // Inserting contact with associations
        Contact contact = new Contact("deisenhower", ...);

        contact.getSupport().add(new Support("Request", ...));
        contact.getSupport().add(new Support("Response", ...));
        contact.getSupport().add(new Support("Request", ...));

        contact.getOrders().add(new Order("Dwight D. Eisenhower Dollar", ...));
        contact.getOrders().add(new Order("Susan B. Anthony Dollar", ...));

        // Saving within an automatic transaction (covers all relationships)
        contact.save(dbm);

        // Add an associated record and update
        contact.getSupport().add(new Support("Response", ...));
        contact.save(dbm);

        // Saving within a transaction manager
        new TransactionManager(dbm)
          {
            public void run() throws Exception
              {
                // Inserting individually
                new Contact("alincoln", ...).save(this);
                new Support("alincoln", ...).save(this);
                new Order("alincoln", ...).save(this);

                // Can also use the TransactionManager's equivalent
                // saveObject() and deleteObject()
                saveObject(new Contact("tjefferson", ...));
                saveObject(new Support("tjefferson", ...));
                saveObject(new Order("tjefferson", ...));

                // Insert new contact only
                Contact contact1 = new Contact("fdroosevelt", ...);
                contact1.save(this);
                
                // Add associated records and update
                contact1.getSupport().add(new Support("fdroosevelt", ...));
                contact1.getOrders().add(new Order("fdroosevelt", ...));
                contact1.save(this);

                // Can still freely use commit, savepoint and rollback
                commit();

                Savepoint savepoint = null;
                
                if (supportsSavepoints())
                  savepoint = setSavepoint();

                new Contact("gwashington", ...).save(this);
                new Support("gwashington", ...).save(this);
                new Order("gwashington", ...).save(this);

                if (supportsSavepoints())
                  rollback(savepoint);

                // Same as save() and saveObject()
                getDatabase().saveObject(new Contact("jkennedy", ...));
                getDatabase().saveObject(new Support("jkennedy", ...));
                getDatabase().saveObject(new Support("jkennedy", ...));
                getDatabase().saveObject(new Order("jkennedy", ...));
              }
          }.executeTransaction();
        
        /*
         * The jpersist.DatabaseManager way to load objects
         */
        
        // Load based on information contained in classes
        contact = dbm.loadObject(Contact.class, "where :contactId like 'tjef%'");
        System.out.println("\ncontactId = " + contact.getContactId());

        // or Load based on information contained in objects
        contact = dbm.loadObject(new Contact("tjef%"));
        System.out.println("contactId = " + contact.getContactId());
        
        // or with variable argument parameters
        contact = dbm.loadObject(Contact.class, "where :contactId like ?", "tjef%");
        System.out.println("contactId = " + contact.getContactId() + "\n");
        
        // Load a collection of objects from the database
        Collection<Contact> c = dbm.loadObjects(new Vector<Contact>(), Contact.class);

        for (Contact contact2 : c)
          System.out.println("contactId = " + contact2.getContactId());

        System.out.println();
        
        /*
         * The jpersist.Database way to load objects
         */
        
        Database db = dbm.getDatabase();

        try
          {
            // Query all
            Result<Contact> result = db.queryObject(Contact.class, "order by :lastName");

            // Result is Iterable
            for (Contact contact3 : result)
              {
                System.out.println(contact3);
              }

            // jpersist.Result is a cursor
            // and can be closed to free the resource
            result.close();

            // or
            result = db.queryObject(Contact.class);
            
            // Print and delete
            while (result.hasNext() && (contact = result.next()) != null)
              {
                System.out.println(contact);
                db.deleteObject(contact);
              }
            
            result.close();
          }
        finally
          {
            // Also closes any open results
            db.close();
          }
      }

    public static void main(String[] args) throws JPersistException
      {
        DatabaseManager dbm = null;

        try
          {
            DatabaseManager.setLogLevel(Level.OFF);

            dbm = new DatabaseManager("example", 5, "com.mysql.jdbc.Driver", 
                                      "jdbc:mysql://localhost/example", 
                                      null, null, "username", "password");

            new DatabaseExample(dbm);
          }
        finally
          {
            // Also closes any open Databases
            dbm.close();  // optional
          }
      }

    /*
     * The following are normal class definitions that
     * automatically map to database
     */
     
    public static class Contact extends PersistentObject
      {
        private String contactId, password, firstName, lastName, companyName, email;
        private Vector<Support> support = new Vector<Support>();
        private Vector<Order> orders = new Vector<Order>();

        public Contact() {}

        public Contact(String contactId)
          {
            this.contactId = contactId;
          }

        public Contact(String contactId, String password, String firstName, 
                       String lastName, String companyName, String email)
          {
            this.contactId = contactId;
            this.password = password;
            this.firstName = firstName;
            this.lastName = lastName;
            this.companyName = companyName;
            this.email = email;
          }

        public String getContactId() { return contactId; }
        public void setContactId(String id) { contactId = id; }
        public String getPassword() { return password; }
        public void setPassword(String passwd) { password = passwd; }
        public String getFirstName() { return firstName; }
        public void setFirstName(String fName) { firstName = fName; }
        public String getLast() { return lastName; }
        public void setLast(String lName) { lastName = lName; }
        public String getCompanyName() { return companyName; }
        public void setCompanyName(String name) { companyName = name; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }

        // Associations
        public Vector<Support> getDbAssociation(Support c) { return support; }
        public void setDbAssociation(Support c, Vector<Support> s) { support = s; }
        public Vector<Order> getDbAssociation(Order c) { return orders; }
        public void setDbAssociation(Order c, Vector<Order> o) { orders = o; }
        
        // Association convenience (is optional)
        public Vector<Support> getSupport() { return support; }
        public void setSupport(Vector<Support> support) { this.support = support; }
        public Vector<Order> getOrders() { return orders; }
        public void setOrders(Vector<Order> orders) { this.orders = orders; }
      }
    
    public static class Order extends Entity
      {
        private Long orderId;
        private Integer quantity;
        private Double price;
        private String contactId, product, status;

        public Order() {}

        public Order(String product, Integer quantity, Double price, String status)
          {
            this.product = product;
            this.quantity = quantity;
            this.price = price;
            this.status = status;
          }

        public Order(String contactId, String product, Integer quantity, 
                     Double price, String status)
          {
            this.contactId = contactId;
            this.product = product;
            this.quantity = quantity;
            this.price = price;
            this.status = status;
          }

        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }
        public String getContactId() { return contactId;}
        public void setContactId(String contactId) { this.contactId = contactId; }
        public String getProduct() { return product; }
        public void setProduct(String product) { this.product = product; }
        public Integer getQuantity() { return quantity; }
        public void setQuantity(Integer quantity) { this.quantity = quantity; }
        public Double getPrice() { return price; }
        public void setPrice(Double price) { this.price = price; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
      }
      
    public static class Support extends Entity
      {
        private Long supportId;
        private String contactId, code, status, phone, email, request;

        public Support() {}

        public Support(String code, String status, String phone, 
                       String email, String request)
          {
            this.code = code;
            this.status = status;
            this.phone = phone;
            this.email = email;
            this.request = request;
          }

        public Support(String contactId, String code, String status, 
                       String phone, String email, String request)
          {
            this.contactId = contactId;
            this.code = code;
            this.status = status;
            this.phone = phone;
            this.email = email;
            this.request = request;
          }

        public Long getSupportId() { return supportId; }
        public void setSupportId(Long id) { supportId = id; }
        public String getContactId() { return contactId; }
        public void setContactId(String id) { contactId = id; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getRequest() { return request; }
        public void setRequest(String request) { this.request = request; }
      }
  }

# MySQL database creation

CREATE TABLE contacts
  (
    CONTACT_ID varchar(40) NOT NULL PRIMARY KEY,
    PASSWORD varchar(40) NOT NULL,
    FIRST_NAME varchar(40) NOT NULL,
    LAST_NAME varchar(60) NOT NULL,
    COMPANY_NAME varchar(60),
    EMAIL varchar(255),
    CREATED timestamp NOT NULL default CURRENT_TIMESTAMP
  );

CREATE TABLE orders
  (
    ORDER_ID int(11) NOT NULL auto_increment PRIMARY KEY,
    CONTACT_ID varchar(40) NOT NULL,
    PRODUCT varchar(40) NOT NULL,
    QUANTITY int(11) NOT NULL,
    PRICE double NOT NULL,
    STATUS varchar(20) NOT NULL default 'unverified',
    created timestamp NOT NULL default CURRENT_TIMESTAMP,
    FOREIGN KEY (CONTACT_ID) REFERENCES contacts (CONTACT_ID) ON DELETE CASCADE
  );

CREATE TABLE support
  (
    SUPPORT_ID int(11) NOT NULL auto_increment PRIMARY KEY,
    CONTACT_ID varchar(40) NOT NULL,
    CODE varchar(10) NOT NULL,
    STATUS varchar(20) NOT NULL,
    PHONE varchar(20),
    EMAIL varchar(255),
    REQUEST varchar(255) NOT NULL,
    CREATED timestamp NOT NULL default CURRENT_TIMESTAMP,
    FOREIGN KEY (CONTACT_ID) REFERENCES contacts (CONTACT_ID) ON DELETE CASCADE
  );

Example of Efficient Updates and Batch Updates

With the exception of the imports and ellipsis (...), the following is a complete, compilable, and runable program example. For the purposes of this example, the ellipsis are being used to reduce non-essential information. The class definitions and database table creation scripts follow. There are no mapping requirements, no XML and no Annotations.

public class UpdateAndBatchExample 
  {
    public UpdateAndBatchExample(DatabaseManager dbm) throws JPersistException
      {
        Database db = dbm.getDatabase();
        
        // Clean out contacts
        db.executeUpdate("delete from contacts");
        
        // Inserting contacts - efficiently uses a single prepared statement
        db.saveObject(new Contact("contact0", ...));
        db.saveObject(new Contact("contact1", ...));
        db.saveObject(new Contact("contact2", ...));
        db.saveObject(new Contact("contact3", ...));
        db.saveObject(new Contact("contact4", ...));

        /**
         * Inserting contacts - uses batch updating
         * and efficiently uses a single prepared statement
         */
        db.beginBatch();
        
        db.saveObject(new Contact("contact5", ...));
        db.saveObject(new Contact("contact6", ...));
        db.saveObject(new Contact("contact7", ...));
        db.saveObject(new Contact("contact8", ...));
        db.saveObject(new Contact("contact9", ...));

        db.executeBatch();
        db.endBatch();
        
        // List the contacts          
        for (Contact c : db.queryObject(Contact.class))
          System.out.println(c);
        
        db.close();

        /**
         * The following are equivalent to the above.
         */
        
        // Inserting contacts - efficiently uses a single prepared statement
        new UpdateManager(dbm) 
          {
            public void run() throws JPersistException 
              {
                for (int i = 10; i < 500; i++)
                  saveObject(new Contact("contact" + i, ...));
              }
          }.executeUpdates();

        /**
         * Inserting contacts - uses batch updating
         * and efficiently uses a single prepared statement
         */
        new UpdateManager(dbm) 
          {
            public void run() throws JPersistException 
              {
                for (int i = 501; i < 1000; i++)
                  saveObject(new Contact("contact" + i, ...));
              }
          }.executeBatchUpdates();

        // List the contacts          
        for (Contact c : dbm.loadObjects(new ArrayList<Contact>(), Contact.class))
          System.out.println(c);
      }

    public static void main(String[] args) throws JPersistException
      {
        DatabaseManager dbm = null;

        try
          {
            DatabaseManager.setLogLevel(Level.OFF);

            dbm = new DatabaseManager("example", 5, "com.mysql.jdbc.Driver", 
                                      "jdbc:mysql://localhost/example", 
                                      null, null, "username", "password");

            new UpdateAndBatchExample(dbm);
          }
        finally
          {
            // also closes any open jpersist.Database
            dbm.close();
          }
      }
    
    public static class Contact
      {
        private String contactId, password, firstName, lastName, companyName, email;

        public Contact() {}

        public Contact(String contactId)
          {
            this.contactId = contactId;
          }

        public Contact(String contactId, String password, String firstName, 
                       String lastName, String companyName, String email)
          {
            this.contactId = contactId;
            this.password = password;
            this.firstName = firstName;
            this.lastName = lastName;
            this.companyName = companyName;
            this.email = email;
          }

        public String getContactId() { return contactId; }
        public void setContactId(String id) { contactId = id; }
        public String getPassword() { return password; }
        public void setPassword(String passwd) { password = passwd; }
        public String getFirstName() { return firstName; }
        public void setFirstName(String fName) { firstName = fName; }
        public String getLastName() { return lastName; }
        public void setLastName(String lName) { lastName = lName; }
        public String getCompanyName() { return companyName; }
        public void setCompanyName(String name) { companyName = name; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String toString()
          {
            return contactId + ", " + firstName + ", " + lastName 
                             + ", " + companyName + ", " + email;
          }
      }
  }
Notice

Copyright (C) 2002 - present, dabu/Software Sensation Inc. ALL RIGHTS RESERVED.

Software Sensation, jWebApp, jPersist, ContentRoller, Enterprise Server Objects (ESO), Enterprise Server Scripting (ESS), and Memory Structures Library (MemSL) are trademarks or registered trademarks of Software Sensation, Inc. in the U.S. and other countries.

Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.