1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: PersonExample.java,v 1.1 2008/02/07 17:12:24 mark Exp $ 7 */ 8 9package persist; 10 11import java.io.File; 12import java.io.FileNotFoundException; 13import java.util.HashSet; 14import java.util.Set; 15 16import com.sleepycat.db.DatabaseException; 17import com.sleepycat.db.Environment; 18import com.sleepycat.db.EnvironmentConfig; 19import com.sleepycat.persist.EntityCursor; 20import com.sleepycat.persist.EntityIndex; 21import com.sleepycat.persist.EntityStore; 22import com.sleepycat.persist.PrimaryIndex; 23import com.sleepycat.persist.SecondaryIndex; 24import com.sleepycat.persist.StoreConfig; 25import com.sleepycat.persist.model.Entity; 26import com.sleepycat.persist.model.Persistent; 27import com.sleepycat.persist.model.PrimaryKey; 28import com.sleepycat.persist.model.SecondaryKey; 29import static com.sleepycat.persist.model.DeleteAction.NULLIFY; 30import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE; 31import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY; 32import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE; 33import static com.sleepycat.persist.model.Relationship.MANY_TO_MANY; 34 35public class PersonExample { 36 37 /* An entity class. */ 38 @Entity 39 static class Person { 40 41 @PrimaryKey 42 String ssn; 43 44 String name; 45 Address address; 46 47 @SecondaryKey(relate=MANY_TO_ONE, relatedEntity=Person.class) 48 String parentSsn; 49 50 @SecondaryKey(relate=ONE_TO_MANY) 51 Set<String> emailAddresses = new HashSet<String>(); 52 53 @SecondaryKey(relate=MANY_TO_MANY, 54 relatedEntity=Employer.class, 55 onRelatedEntityDelete=NULLIFY) 56 Set<Long> employerIds = new HashSet<Long>(); 57 58 Person(String name, String ssn, String parentSsn) { 59 this.name = name; 60 this.ssn = ssn; 61 this.parentSsn = parentSsn; 62 } 63 64 private Person() {} // For deserialization 65 } 66 67 /* Another entity class. */ 68 @Entity 69 static class Employer { 70 71 @PrimaryKey(sequence="ID") 72 long id; 73 74 @SecondaryKey(relate=ONE_TO_ONE) 75 String name; 76 77 Address address; 78 79 Employer(String name) { 80 this.name = name; 81 } 82 83 private Employer() {} // For deserialization 84 } 85 86 /* A persistent class used in other classes. */ 87 @Persistent 88 static class Address { 89 String street; 90 String city; 91 String state; 92 int zipCode; 93 private Address() {} // For deserialization 94 } 95 96 /* The data accessor class for the entity model. */ 97 static class PersonAccessor { 98 99 /* Person accessors */ 100 PrimaryIndex<String,Person> personBySsn; 101 SecondaryIndex<String,String,Person> personByParentSsn; 102 SecondaryIndex<String,String,Person> personByEmailAddresses; 103 SecondaryIndex<Long,String,Person> personByEmployerIds; 104 105 /* Employer accessors */ 106 PrimaryIndex<Long,Employer> employerById; 107 SecondaryIndex<String,Long,Employer> employerByName; 108 109 /* Opens all primary and secondary indices. */ 110 public PersonAccessor(EntityStore store) 111 throws DatabaseException { 112 113 personBySsn = store.getPrimaryIndex( 114 String.class, Person.class); 115 116 personByParentSsn = store.getSecondaryIndex( 117 personBySsn, String.class, "parentSsn"); 118 119 personByEmailAddresses = store.getSecondaryIndex( 120 personBySsn, String.class, "emailAddresses"); 121 122 personByEmployerIds = store.getSecondaryIndex( 123 personBySsn, Long.class, "employerIds"); 124 125 employerById = store.getPrimaryIndex( 126 Long.class, Employer.class); 127 128 employerByName = store.getSecondaryIndex( 129 employerById, String.class, "name"); 130 } 131 } 132 133 public static void main(String[] args) 134 throws DatabaseException, FileNotFoundException { 135 136 if (args.length != 2 || !"-h".equals(args[0])) { 137 System.err.println 138 ("Usage: java " + PersonExample.class.getName() + 139 " -h <envHome>"); 140 System.exit(2); 141 } 142 PersonExample example = new PersonExample(new File(args[1])); 143 example.run(); 144 example.close(); 145 } 146 147 private Environment env; 148 private EntityStore store; 149 private PersonAccessor dao; 150 151 private PersonExample(File envHome) 152 throws DatabaseException, FileNotFoundException { 153 154 /* Open a transactional Berkeley DB engine environment. */ 155 EnvironmentConfig envConfig = new EnvironmentConfig(); 156 envConfig.setAllowCreate(true); 157 envConfig.setTransactional(true); 158 envConfig.setInitializeCache(true); 159 envConfig.setInitializeLocking(true); 160 env = new Environment(envHome, envConfig); 161 162 /* Open a transactional entity store. */ 163 StoreConfig storeConfig = new StoreConfig(); 164 storeConfig.setAllowCreate(true); 165 storeConfig.setTransactional(true); 166 store = new EntityStore(env, "PersonStore", storeConfig); 167 168 /* Initialize the data access object. */ 169 dao = new PersonAccessor(store); 170 } 171 172 private void run() 173 throws DatabaseException { 174 175 /* 176 * Add a parent and two children using the Person primary index. 177 * Specifying a non-null parentSsn adds the child Person to the 178 * sub-index of children for that parent key. 179 */ 180 dao.personBySsn.put 181 (new Person("Bob Smith", "111-11-1111", null)); 182 dao.personBySsn.put 183 (new Person("Mary Smith", "333-33-3333", "111-11-1111")); 184 dao.personBySsn.put 185 (new Person("Jack Smith", "222-22-2222", "111-11-1111")); 186 187 /* Print the children of a parent using a sub-index and a cursor. */ 188 EntityCursor<Person> children = 189 dao.personByParentSsn.subIndex("111-11-1111").entities(); 190 try { 191 for (Person child : children) { 192 System.out.println(child.ssn + ' ' + child.name); 193 } 194 } finally { 195 children.close(); 196 } 197 198 /* Get Bob by primary key using the primary index. */ 199 Person bob = dao.personBySsn.get("111-11-1111"); 200 assert bob != null; 201 202 /* 203 * Create two employers if they do not already exist. Their primary 204 * keys are assigned from a sequence. 205 */ 206 Employer gizmoInc = dao.employerByName.get("Gizmo Inc"); 207 if (gizmoInc == null) { 208 gizmoInc = new Employer("Gizmo Inc"); 209 dao.employerById.put(gizmoInc); 210 } 211 Employer gadgetInc = dao.employerByName.get("Gadget Inc"); 212 if (gadgetInc == null) { 213 gadgetInc = new Employer("Gadget Inc"); 214 dao.employerById.put(gadgetInc); 215 } 216 217 /* Bob has two jobs and two email addresses. */ 218 bob.employerIds.add(gizmoInc.id); 219 bob.employerIds.add(gadgetInc.id); 220 bob.emailAddresses.add("bob@bob.com"); 221 bob.emailAddresses.add("bob@gmail.com"); 222 223 /* Update Bob's record. */ 224 dao.personBySsn.put(bob); 225 226 /* Bob can now be found by both email addresses. */ 227 bob = dao.personByEmailAddresses.get("bob@bob.com"); 228 assert bob != null; 229 bob = dao.personByEmailAddresses.get("bob@gmail.com"); 230 assert bob != null; 231 232 /* Bob can also be found as an employee of both employers. */ 233 EntityIndex<String,Person> employees; 234 employees = dao.personByEmployerIds.subIndex(gizmoInc.id); 235 assert employees.contains("111-11-1111"); 236 employees = dao.personByEmployerIds.subIndex(gadgetInc.id); 237 assert employees.contains("111-11-1111"); 238 239 /* 240 * When an employer is deleted, the onRelatedEntityDelete=NULLIFY for 241 * the employerIds key causes the deleted ID to be removed from Bob's 242 * employerIds. 243 */ 244 dao.employerById.delete(gizmoInc.id); 245 bob = dao.personBySsn.get("111-11-1111"); 246 assert bob != null; 247 assert !bob.employerIds.contains(gizmoInc.id); 248 } 249 250 private void close() 251 throws DatabaseException { 252 253 store.close(); 254 env.close(); 255 } 256} 257