Working with Artifacts and Owners
This final section of the chapter provides a sample set of operations. The entire class is shown in Listing 3.13, broken up to allow for commentary.
The code shown in Listing 3.13 shows the primary flow for the test application. A SessionFactory is shared throughout the execution of the application. An array of strings is used to describe a set of basic objects. The main() method tests the creation, update, and deletion of a set of objects.
Listing 3.13. Setting Up the Code
package com.cascadetg.ch03;
/** Note that we leverage a JDBC connection for
* our mass delete code.
*/
import java.sql.Connection;
import java.sql.Statement;
/** Various Hibernate-related imports */
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate;
import net.sf.hibernate.expression.Order;
public class TestSuite
{
/** We use this session factory to create our sessions */
public static SessionFactory sessionFactory;
/** Our artifact data */
public static String[] artifactNames =
{
"Bast Figurine, Faience",
"Obsidian Spearpoint, Maglenian Period",
"Lion Bowl, Unidentified",
"Golden Torq, Six Inch Diameter",
"Silver Ring, Roman" };
static long update_id;
public static void main(String[] args)
{
initialization();
if (currentCount() == 0)
System.out.println("initialization OK");
createObjects();
if (currentCount() == 5)
System.out.println("createObjects OK");
loadAllArtifacts();
if (currentCount() == 5)
System.out.println("loadAllArtifacts OK");
updateOneObject();
if (currentCount() == 5)
System.out.println("updateOneObject OK");
deleteObjects();
if (currentCount() == 4)
System.out.println("deleteObjects OK");
massDelete();
if (currentCount() == 0)
System.out.println("massDelete OK");
}
Listing 3.14 shows the use of HQL to determine the number of artifacts currently in the system. For more information on HQL, see Chapter 8.
Listing 3.14. Obtaining the Current Count
public static int currentCount()
{
System.out.println();
Session hibernateSession = null;
Transaction myTransaction = null;
Integer result = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction =
hibernateSession.beginTransaction();
String hql =
"select count(artifact) from Artifact as artifact";
Query myQuery = hibernateSession.createQuery(hql);
result = (Integer)myQuery.uniqueResult();
System.out.println(
"Current count: " + result.toString());
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
if (hibernateSession != null)
hibernateSession.close();
} catch (Exception e)
{
// Silent failure of session close
}
}
return result.intValue();
}
Listing 3.15 shows the standard initialization of a Hibernate application. Note the use of the SchemaUpdate class to ensure that the database schema is brought in line with the current mapping files (see Chapter 11 for more information on schema management).
Listing 3.15. Setting Up the Code
/** Loads the Hibernate configuration information,
* sets up the database and the Hibernate session factory.
*/
public static void initialization()
{
//System.setErr(System.out);
System.out.println("initialization");
try
{
Configuration myConfiguration = new
Configuration();
myConfiguration.addClass(Owner.class);
myConfiguration.addClass(Artifact.class);
// This is the code that updates the database to
// the current schema.
new SchemaUpdate(myConfiguration).execute(true,
true);
// Sets up the session factory (used in the rest
// of the application).
sessionFactory =
myConfiguration.buildSessionFactory();
} catch (Exception e)
{
e.printStackTrace();
}
}
Listing 3.16 shows the creation of a set of objects, along with the establishment of the relationships between various objects. Note that nowhere is the ownership table referenced by name; the relationships are instead managed by Hibernate. For more information on the management of relationships by Hibernate, see Chapter 7.
Listing 3.16. Creating Objects
public static void createObjects()
{
System.out.println();
System.out.println("createObjects");
Session hibernateSession = null;
Transaction myTransaction = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction =
hibernateSession.beginTransaction();
Owner myExhibition = new Exhibition();
myExhibition.setName("New Acquisitions 2005");
Person myPerson = new Person();
myPerson.setName("Smith, Bob");
Foundation myFoundation = new Foundation();
myFoundation.setName("Smith Foundation");
myFoundation.setOwner(myPerson);
Museum myMuseum = new Museum();
myMuseum.setName("Waldendorf");
myMuseum.setDateOpened(new java.util.Date());
hibernateSession.save(myPerson);
hibernateSession.save(myFoundation);
hibernateSession.save(myMuseum);
hibernateSession.flush();
myTransaction.commit();
myTransaction = hibernateSession.beginTransaction
();
for (int i = 0; i < artifactNames.length; i++)
{
Artifact myArtifact = new Artifact();
myArtifact.setTitle(artifactNames[i]);
hibernateSession.save(myArtifact);
// Important to issue the save first,
// so the ID of the artifact is set.
myArtifact.addOwner(myExhibition);
myArtifact.addOwner(myFoundation);
myArtifact.addOwner(myMuseum);
hibernateSession.save(myExhibition);
hibernateSession.save(myFoundation);
hibernateSession.save(myMuseum);
hibernateSession.flush();
}
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
hibernateSession.close();
} catch (Exception e2)
{
// Silent failure of session close
}
}
}
Listing 3.17 shows the use of the Criteria API to fetch both the Artifact and all of the associated Owners with a single SQL statement. For more information on the Criteria API, see Chapter 8.
Listing 3.17. Loading the Artifacts and Owners
public static void loadAllArtifacts()
{
System.out.println();
System.out.println("loadAllArtifacts");
Session hibernateSession = null;
Transaction myTransaction = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction =
hibernateSession.beginTransaction();
// In this example, we use the Criteria API.
// We could also have used the HQL, but the
// Criteria API allows us to express this
// query more easily. First indicate that
// we want to grab all of the artifacts.
Criteria query =
hibernateSession.createCriteria(Artifact.class);
// Now, specify sorting by the artifact title
query.addOrder(Order.asc("title"));
// Indicate that we want to grab all of the
// associated owners of artifacts as well.
// This lets us pull of the data in a single
// SQL statement!
query.setFetchMode("owners", FetchMode.EAGER);
// This actually performs the database request,
// based on the query we've built.
java.util.Iterator results =
query.list().iterator();
Artifact myArtifact;
// Because we are grabbing all of the artifacts and
// artifact owners, we need to store the returned
// artifacts
java.util.LinkedList retrievedArtifacts =
new java.util.LinkedList();
while (results.hasNext())
{
// Note that the result set is cast to the
// Animal object directlyno manual
// binding required.
myArtifact = (Artifact)results.next();
if (!retrievedArtifacts.contains(myArtifact))
retrievedArtifacts.add(myArtifact);
update_id = myArtifact.getId();
}
java.util.Iterator results2 =
retrievedArtifacts.iterator();
while (results2.hasNext())
{
myArtifact = (Artifact)results2.next();
if (false)
{
System.out.println(myArtifact.getId() + "");
System.out.println(myArtifact.getTitle() +
"");
}
java.util.Set myOwners =
myArtifact.getOwners();
java.util.Iterator myOwnersIterator =
myOwners.iterator();
if (false)
while (myOwnersIterator.hasNext())
System.out.println(
((Owner)myOwnersIterator.next())
.getName());
}
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
if (hibernateSession != null)
hibernateSession.close();
} catch (Exception e)
{
// Silent failure of session close
}
}
}
Listing 3.18 shows a single object, loaded and then updated after a minor change.
Listing 3.18. Updating a Single Object
public static void updateOneObject()
{
System.out.println();
System.out.println("updateOneObject");
Session hibernateSession = null;
Transaction myTransaction = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction = hibernateSession.beginTransaction();
Artifact myArtifact =
(Artifact)hibernateSession.get(
Artifact.class,
new Long(update_id));
myArtifact.setTitle("Test");
hibernateSession.update(myArtifact);
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
if (hibernateSession != null)
hibernateSession.close();
} catch (Exception e)
{
// Silent failure of session close
}
}
}
Listing 3.19 shows the deletion of a set of objects that meet a particular HQL query (in this case, items that happen to have a title starting with "Golden").
Note the commented-out call to Session.find() prior to the Session.delete(). Whenever you are deleting objects, it's a good idea to test this out in advance, making sure that the objects being deleted are the objects you actually want to delete.
Listing 3.19. Deleting Particular Objects
public static void deleteObjects()
{
System.out.println();
System.out.println("deleteObjects");
Session hibernateSession = null;
Transaction myTransaction = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction =
hibernateSession.beginTransaction();
String hql =
"from Artifact as artifact where "
+ "artifact.title like 'Golden%'";
java.util.List myArtifacts =
hibernateSession.find(hql);
hibernateSession.delete(hql);
hibernateSession.flush();
String sql =
"DELETE ownership FROM ownership LEFT JOIN artifact "
+ "ON ownership.artifact_id=artifact.id "
+ "WHERE artifact.id IS NULL";
Connection myConnection =
hibernateSession.connection();
Statement myStatement =
myConnection.createStatement();
System.out.println(myStatement.execute(sql));
System.out.println(myStatement.getUpdateCount());
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
if (hibernateSession != null)
hibernateSession.close();
} catch (Exception e)
{
// Silent failure of session close
}
}
}
You may sometimes wish to perform SQL operations on the database directly, instead of relying on HQL or the Criteria API. This is especially true when performing a mass insert, but Listing 3.20 shows the use of SQL to perform a bulk deletion.
Listing 3.20. Deleting Many Objects at Once Using SQL
public static void massDelete()
{
System.out.println();
System.out.println("massDelete");
Session hibernateSession = null;
Transaction myTransaction = null;
try
{
hibernateSession = sessionFactory.openSession();
myTransaction =
hibernateSession.beginTransaction();
Connection myConnection =
hibernateSession.connection();
Statement myStatement =
myConnection.createStatement();
String sql = "delete from artifact";
System.out.println(sql);
myStatement.execute(sql);
sql = "delete from owner";
System.out.println(sql);
myStatement.execute(sql);
sql = "delete from ownership";
System.out.println(sql);
myStatement.execute(sql);
myTransaction.commit();
} catch (Exception e)
{
e.printStackTrace();
try
{
myTransaction.rollback();
} catch (Exception e2)
{
// Silent failure of transaction rollback
}
} finally
{
try
{
if (hibernateSession != null)
hibernateSession.close();
} catch (Exception e)
{
// Silent failure of session close
}
}
}
}
Assuming that everything is working properly, the output of this test application should be as shown in Listing 3.21.
NOTE
The final step of this program is the deletion of all the data in the tablesyou may wish to comment out the references to the deleteObjects() and/or mass Delete() methods in the main() method to explore the data generated in the database.
Listing 3.21. Successful Output
Current count: 0
initialization OK
createObjects
Current count: 5
createObjects OK
loadAllArtifacts
Current count: 5
loadAllArtifacts OK
updateOneObject
Current count: 5
updateOneObject OK
deleteObjects
false
3
Current count: 4
deleteObjects OK
massDelete
delete from artifact
delete from owner
delete from ownership
Current count: 0
massDelete OK
 |