001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: PersonExample.java,v 1.9.2.2 2008/01/07 15:14:04 cwl Exp $
007: */
008:
009: package persist;
010:
011: import java.io.File;
012: import java.util.HashSet;
013: import java.util.Set;
014:
015: import com.sleepycat.je.DatabaseException;
016: import com.sleepycat.je.Environment;
017: import com.sleepycat.je.EnvironmentConfig;
018: import com.sleepycat.persist.EntityCursor;
019: import com.sleepycat.persist.EntityIndex;
020: import com.sleepycat.persist.EntityStore;
021: import com.sleepycat.persist.PrimaryIndex;
022: import com.sleepycat.persist.SecondaryIndex;
023: import com.sleepycat.persist.StoreConfig;
024: import com.sleepycat.persist.model.Entity;
025: import com.sleepycat.persist.model.Persistent;
026: import com.sleepycat.persist.model.PrimaryKey;
027: import com.sleepycat.persist.model.SecondaryKey;
028: import static com.sleepycat.persist.model.DeleteAction.NULLIFY;
029: import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
030: import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
031: import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
032: import static com.sleepycat.persist.model.Relationship.MANY_TO_MANY;
033:
034: public class PersonExample {
035:
036: /* An entity class. */
037: @Entity
038: static class Person {
039:
040: @PrimaryKey
041: String ssn;
042:
043: String name;
044: Address address;
045:
046: @SecondaryKey(relate=MANY_TO_ONE,relatedEntity=Person.class)
047: String parentSsn;
048:
049: @SecondaryKey(relate=ONE_TO_MANY)
050: Set<String> emailAddresses = new HashSet<String>();
051:
052: @SecondaryKey(relate=MANY_TO_MANY,relatedEntity=Employer.class,onRelatedEntityDelete=NULLIFY)
053: Set<Long> employerIds = new HashSet<Long>();
054:
055: Person(String name, String ssn, String parentSsn) {
056: this .name = name;
057: this .ssn = ssn;
058: this .parentSsn = parentSsn;
059: }
060:
061: private Person() {
062: } // For deserialization
063: }
064:
065: /* Another entity class. */
066: @Entity
067: static class Employer {
068:
069: @PrimaryKey(sequence="ID")
070: long id;
071:
072: @SecondaryKey(relate=ONE_TO_ONE)
073: String name;
074:
075: Address address;
076:
077: Employer(String name) {
078: this .name = name;
079: }
080:
081: private Employer() {
082: } // For deserialization
083: }
084:
085: /* A persistent class used in other classes. */
086: @Persistent
087: static class Address {
088: String street;
089: String city;
090: String state;
091: int zipCode;
092:
093: private Address() {
094: } // For deserialization
095: }
096:
097: /* The data accessor class for the entity model. */
098: static class PersonAccessor {
099:
100: /* Person accessors */
101: PrimaryIndex<String, Person> personBySsn;
102: SecondaryIndex<String, String, Person> personByParentSsn;
103: SecondaryIndex<String, String, Person> personByEmailAddresses;
104: SecondaryIndex<Long, String, Person> personByEmployerIds;
105:
106: /* Employer accessors */
107: PrimaryIndex<Long, Employer> employerById;
108: SecondaryIndex<String, Long, Employer> employerByName;
109:
110: /* Opens all primary and secondary indices. */
111: public PersonAccessor(EntityStore store)
112: throws DatabaseException {
113:
114: personBySsn = store.getPrimaryIndex(String.class,
115: Person.class);
116:
117: personByParentSsn = store.getSecondaryIndex(personBySsn,
118: String.class, "parentSsn");
119:
120: personByEmailAddresses = store.getSecondaryIndex(
121: personBySsn, String.class, "emailAddresses");
122:
123: personByEmployerIds = store.getSecondaryIndex(personBySsn,
124: Long.class, "employerIds");
125:
126: employerById = store.getPrimaryIndex(Long.class,
127: Employer.class);
128:
129: employerByName = store.getSecondaryIndex(employerById,
130: String.class, "name");
131: }
132: }
133:
134: public static void main(String[] args) throws DatabaseException {
135:
136: if (args.length != 2 || !"-h".equals(args[0])) {
137: System.err.println("Usage: java "
138: + PersonExample.class.getName() + " -h <envHome>");
139: System.exit(2);
140: }
141: PersonExample example = new PersonExample(new File(args[1]));
142: example.run();
143: example.close();
144: }
145:
146: private Environment env;
147: private EntityStore store;
148: private PersonAccessor dao;
149:
150: private PersonExample(File envHome) throws DatabaseException {
151:
152: /* Open a transactional Berkeley DB engine environment. */
153: EnvironmentConfig envConfig = new EnvironmentConfig();
154: envConfig.setAllowCreate(true);
155: envConfig.setTransactional(true);
156: env = new Environment(envHome, envConfig);
157:
158: /* Open a transactional entity store. */
159: StoreConfig storeConfig = new StoreConfig();
160: storeConfig.setAllowCreate(true);
161: storeConfig.setTransactional(true);
162: store = new EntityStore(env, "PersonStore", storeConfig);
163:
164: /* Initialize the data access object. */
165: dao = new PersonAccessor(store);
166: }
167:
168: private void run() throws DatabaseException {
169:
170: /*
171: * Add a parent and two children using the Person primary index.
172: * Specifying a non-null parentSsn adds the child Person to the
173: * sub-index of children for that parent key.
174: */
175: dao.personBySsn
176: .put(new Person("Bob Smith", "111-11-1111", null));
177: dao.personBySsn.put(new Person("Mary Smith", "333-33-3333",
178: "111-11-1111"));
179: dao.personBySsn.put(new Person("Jack Smith", "222-22-2222",
180: "111-11-1111"));
181:
182: /* Print the children of a parent using a sub-index and a cursor. */
183: EntityCursor<Person> children = dao.personByParentSsn.subIndex(
184: "111-11-1111").entities();
185: try {
186: for (Person child : children) {
187: System.out.println(child.ssn + ' ' + child.name);
188: }
189: } finally {
190: children.close();
191: }
192:
193: /* Get Bob by primary key using the primary index. */
194: Person bob = dao.personBySsn.get("111-11-1111");
195: assert bob != null;
196:
197: /*
198: * Create two employers if they do not already exist. Their primary
199: * keys are assigned from a sequence.
200: */
201: Employer gizmoInc = dao.employerByName.get("Gizmo Inc");
202: if (gizmoInc == null) {
203: gizmoInc = new Employer("Gizmo Inc");
204: dao.employerById.put(gizmoInc);
205: }
206: Employer gadgetInc = dao.employerByName.get("Gadget Inc");
207: if (gadgetInc == null) {
208: gadgetInc = new Employer("Gadget Inc");
209: dao.employerById.put(gadgetInc);
210: }
211:
212: /* Bob has two jobs and two email addresses. */
213: bob.employerIds.add(gizmoInc.id);
214: bob.employerIds.add(gadgetInc.id);
215: bob.emailAddresses.add("bob@bob.com");
216: bob.emailAddresses.add("bob@gmail.com");
217:
218: /* Update Bob's record. */
219: dao.personBySsn.put(bob);
220:
221: /* Bob can now be found by both email addresses. */
222: bob = dao.personByEmailAddresses.get("bob@bob.com");
223: assert bob != null;
224: bob = dao.personByEmailAddresses.get("bob@gmail.com");
225: assert bob != null;
226:
227: /* Bob can also be found as an employee of both employers. */
228: EntityIndex<String, Person> employees;
229: employees = dao.personByEmployerIds.subIndex(gizmoInc.id);
230: assert employees.contains("111-11-1111");
231: employees = dao.personByEmployerIds.subIndex(gadgetInc.id);
232: assert employees.contains("111-11-1111");
233:
234: /*
235: * When an employer is deleted, the onRelatedEntityDelete=NULLIFY for
236: * the employerIds key causes the deleted ID to be removed from Bob's
237: * employerIds.
238: */
239: dao.employerById.delete(gizmoInc.id);
240: bob = dao.personBySsn.get("111-11-1111");
241: assert bob != null;
242: assert !bob.employerIds.contains(gizmoInc.id);
243: }
244:
245: private void close() throws DatabaseException {
246:
247: store.close();
248: env.close();
249: }
250: }
|