Skip to content

Method: savePoint(Transaction)

1: package de.fhdw.wtf.persistence.facade;
2:
3: import java.math.BigDecimal;
4: import java.math.BigInteger;
5: import java.sql.CallableStatement;
6: import java.sql.ResultSet;
7: import java.sql.SQLException;
8: import java.sql.Timestamp;
9: import java.util.ArrayList;
10: import java.util.Collection;
11: import java.util.Date;
12: import java.util.HashSet;
13:
14: import oracle.jdbc.OracleCallableStatement;
15: import oracle.jdbc.OracleTypes;
16: import de.fhdw.wtf.persistence.exception.BaseTypeNotFoundException;
17: import de.fhdw.wtf.persistence.exception.DuplicateEntryException;
18: import de.fhdw.wtf.persistence.exception.InvalidLinkException;
19: import de.fhdw.wtf.persistence.exception.NoValidTransactionException;
20: import de.fhdw.wtf.persistence.exception.NotInScopeException;
21: import de.fhdw.wtf.persistence.exception.NotInstantiatableException;
22: import de.fhdw.wtf.persistence.exception.ObjectNotFoundException;
23: import de.fhdw.wtf.persistence.exception.OtherSQLException;
24: import de.fhdw.wtf.persistence.exception.PersistenceException;
25: import de.fhdw.wtf.persistence.exception.ToManyObjectsException;
26: import de.fhdw.wtf.persistence.meta.AdhocTransaction;
27: import de.fhdw.wtf.persistence.meta.Association;
28: import de.fhdw.wtf.persistence.meta.IntegerValue;
29: import de.fhdw.wtf.persistence.meta.Link;
30: import de.fhdw.wtf.persistence.meta.MapAssociation;
31: import de.fhdw.wtf.persistence.meta.MapLink;
32: import de.fhdw.wtf.persistence.meta.Object;
33: import de.fhdw.wtf.persistence.meta.StringValue;
34: import de.fhdw.wtf.persistence.meta.Transaction;
35: import de.fhdw.wtf.persistence.meta.UnidirectionalAssociation;
36: import de.fhdw.wtf.persistence.meta.UnidirectionalLink;
37: import de.fhdw.wtf.persistence.meta.UserObject;
38: import de.fhdw.wtf.persistence.meta.UserType;
39: import de.fhdw.wtf.persistence.utils.DBConnectionIntegerHandler;
40: import de.fhdw.wtf.persistence.utils.DBConnectionObjectHandler;
41: import de.fhdw.wtf.persistence.utils.DBConnectionStringHandler;
42: import de.fhdw.wtf.persistence.utils.DBConnectionUserObjectHandler;
43: import de.fhdw.wtf.persistence.utils.IntegerConstants;
44: import de.fhdw.wtf.persistence.utils.StringConstants;
45: import de.fhdw.wtf.persistence.utils.Tuple;
46:
47: /**
48: * A class to represent the implementation of the Object Facade Interface for the Oracle Database.
49: *
50: */
51: public class OracleObjectFacadeImplementation implements ObjectFacade {
52:         
53:         private static final String CALL_SUFFIX = " end;";
54:         
55:         private static final String STORED_PROCEDURE_PREFIX = "begin ";
56:         
57:         private static final String STORED_FUNCTION_PREFIX = "begin ? := ";
58:         
59:         /**
60:          * The Oracle Database Manager which is needed to call stored procedures in the database.
61:          */
62:         private final OracleDatabaseManager database;
63:         
64:         /**
65:          * The Type Manager, which has the Information about all model items.
66:          */
67:         private final TypeManager typeManager;
68:         
69:         /**
70:          * Constructor for a new Oracle Object Facade Implementation class.
71:          *
72:          * @param database
73:          * An Oracle Database Manager, which is needed to access the Database.
74:          * @param typeManager
75:          * A type Manager needed to determine type information.
76:          */
77:         public OracleObjectFacadeImplementation(final OracleDatabaseManager database, final TypeManager typeManager) {
78:                 super();
79:                 this.database = database;
80:                 this.typeManager = typeManager;
81:                 IntegerValue.setObjectFacade(this);
82:                 StringValue.setObjectFacade(this);
83:         }
84:         
85:         @Override
86:         public Collection<UserObject> find(final Association association, final String string, final Date date)
87:                         throws PersistenceException {
88:                 try (final CallableStatement call =
89:                                 this.database.getConnection().prepareCall(
90:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.findString(?,?,?);"
91:                                                                 + CALL_SUFFIX)) {
92:                         call.registerOutParameter(1, OracleTypes.CURSOR);
93:                         call.setLong(IntegerConstants.TWO, association.getId());
94:                         call.setString(IntegerConstants.THREE, string);
95:                         call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
96:                         call.execute();
97:                         
98:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
99:                                 final Collection<UserObject> result = new HashSet<>();
100:                                 while (resultSet.next()) {
101:                                         result.add(UserObject.init(
102:                                                         resultSet.getLong(1),
103:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))));
104:                                 }
105:                                 return result;
106:                         }
107:                 } catch (final SQLException e) {
108:                         throw new OtherSQLException(e);
109:                 }
110:         }
111:         
112:         @Override
113:         public Collection<UserObject> find(final Association association, final BigInteger integer, final Date date)
114:                         throws PersistenceException {
115:                 try (final CallableStatement call =
116:                                 this.database.getConnection().prepareCall(
117:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.findInteger(?,?,?);"
118:                                                                 + CALL_SUFFIX)) {
119:                         call.registerOutParameter(1, OracleTypes.CURSOR);
120:                         call.setLong(2, association.getId());
121:                         final BigDecimal wrapper = new BigDecimal(integer);
122:                         call.setBigDecimal(IntegerConstants.THREE, wrapper);
123:                         call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
124:                         call.execute();
125:                         
126:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
127:                                 final Collection<UserObject> result = new HashSet<>();
128:                                 while (resultSet.next()) {
129:                                         result.add(UserObject.init(
130:                                                         resultSet.getLong(1),
131:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))));
132:                                 }
133:                                 return result;
134:                         }
135:                 } catch (final SQLException e) {
136:                         throw new OtherSQLException(e);
137:                 }
138:         }
139:         
140:         @Override
141:         public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
142:                         final UnidirectionalAssociation association,
143:                         final Date date) throws PersistenceException {
144:                 try (final CallableStatement call =
145:                                 this.database.getConnection().prepareCall(
146:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.get(?,?,?);"
147:                                                                 + CALL_SUFFIX)) {
148:                         call.registerOutParameter(1, OracleTypes.CURSOR);
149:                         call.setLong(2, owner.getId());
150:                         call.setLong(IntegerConstants.THREE, association.getId());
151:                         call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
152:                         call.execute();
153:                         
154:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
155:                                 final Collection<Tuple<UnidirectionalLink, Object>> result = new ArrayList<>();
156:                                 while (resultSet.next()) {
157:                                         final Object target =
158:                                                         Object.checkForBaseTypes(
159:                                                                         resultSet.getLong(3),
160:                                                                         this.typeManager.getTypeForId(resultSet.getLong(4)));
161:                                         result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
162:                                                         .getUnidirectionalAssociationForId(resultSet.getLong(2))), target));
163:                                 }
164:                                 return result;
165:                         }
166:                 } catch (final SQLException e) {
167:                         throw new OtherSQLException(e);
168:                 }
169:         }
170:         
171:         private Collection<Object> getWithKeyHelper(final UserObject owner,
172:                         final MapAssociation association,
173:                         final DBConnectionObjectHandler keyHandler,
174:                         final Date date) throws PersistenceException {
175:                 try (final CallableStatement call =
176:                                 this.database.getConnection().prepareCall(
177:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + StringConstants.OBJECTFACADEGETMAP
178:                                                                 + keyHandler.getObjectTypeString() + StringConstants.FOURQUESTIONMARKS + CALL_SUFFIX)) {
179:                         call.registerOutParameter(1, OracleTypes.CURSOR);
180:                         call.setLong(2, owner.getId());
181:                         call.setLong(IntegerConstants.THREE, association.getId());
182:                         keyHandler.handleCall(call, IntegerConstants.FOUR);
183:                         call.setTimestamp(IntegerConstants.FIVE, new Timestamp(date.getTime()));
184:                         call.execute();
185:                         
186:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
187:                                 final Collection<Object> result = new ArrayList<>();
188:                                 while (resultSet.next()) {
189:                                         if (!result.isEmpty()) {
190:                                                 throw new ToManyObjectsException();
191:                                         }
192:                                         final Object target =
193:                                                         Object.checkForBaseTypes(
194:                                                                         resultSet.getLong(1),
195:                                                                         this.typeManager.getTypeForId(resultSet.getLong(2)));
196:                                         result.add(target);
197:                                 }
198:                                 if (result.isEmpty()) {
199:                                         throw new ObjectNotFoundException();
200:                                 }
201:                                 return result;
202:                         }
203:                 } catch (final SQLException e) {
204:                         throw new OtherSQLException(e);
205:                 }
206:         }
207:         
208:         @Override
209:         public Collection<Object> get(final UserObject owner,
210:                         final MapAssociation association,
211:                         final String key,
212:                         final Date date) throws PersistenceException {
213:                 return this.getWithKeyHelper(owner, association, new DBConnectionStringHandler(key), date);
214:         }
215:         
216:         @Override
217:         public Collection<Object> get(final UserObject owner,
218:                         final MapAssociation association,
219:                         final BigInteger key,
220:                         final Date date) throws PersistenceException {
221:                 return this.getWithKeyHelper(owner, association, new DBConnectionIntegerHandler(key), date);
222:         }
223:         
224:         @Override
225:         public Collection<Object> get(final UserObject owner,
226:                         final MapAssociation association,
227:                         final UserObject key,
228:                         final Date date) throws PersistenceException {
229:                 return this.getWithKeyHelper(owner, association, new DBConnectionUserObjectHandler(key), date);
230:         }
231:         
232:         @Override
233:         public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
234:                         final UnidirectionalAssociation association,
235:                         final Date date) throws PersistenceException {
236:                 try (final CallableStatement call =
237:                                 this.database.getConnection().prepareCall(
238:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.inverseGet(?,?,?);"
239:                                                                 + CALL_SUFFIX)) {
240:                         call.registerOutParameter(1, OracleTypes.CURSOR);
241:                         call.setLong(2, target.getId());
242:                         call.setLong(IntegerConstants.THREE, association.getId());
243:                         call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
244:                         call.execute();
245:                         
246:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
247:                                 final Collection<Tuple<UnidirectionalLink, UserObject>> result = new ArrayList<>();
248:                                 while (resultSet.next()) {
249:                                         final UserObject owner =
250:                                                         UserObject.init(resultSet.getLong(3), this.typeManager.getTypeForId(resultSet.getLong(4)));
251:                                         result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
252:                                                         .getUnidirectionalAssociationForId(resultSet.getLong(2))), owner));
253:                                 }
254:                                 return result;
255:                         }
256:                 } catch (final SQLException e) {
257:                         throw new OtherSQLException(e);
258:                 }
259:         }
260:         
261:         private Collection<Tuple<UserObject, Object>> inverseGetWithKeyHelper(final DBConnectionObjectHandler targetHandler,
262:                         final MapAssociation association,
263:                         final Date date) throws PersistenceException {
264:                 try (final CallableStatement call =
265:                                 this.database.getConnection().prepareCall(
266:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
267:                                                                 + StringConstants.OBJECTFACADEINVERSEGETMAP + targetHandler.getObjectTypeString()
268:                                                                 + "(?,?,?);" + CALL_SUFFIX)) {
269:                         call.registerOutParameter(1, OracleTypes.CURSOR);
270:                         targetHandler.handleCall(call, 2);
271:                         call.setLong(IntegerConstants.THREE, association.getId());
272:                         call.setTimestamp(IntegerConstants.FOUR, new Timestamp(date.getTime()));
273:                         call.execute();
274:                         
275:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
276:                                 final Collection<Tuple<UserObject, Object>> owners = new ArrayList<>();
277:                                 while (resultSet.next()) {
278:                                         owners.add(new Tuple<>(UserObject.init(
279:                                                         resultSet.getLong(1),
280:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))), Object.checkForBaseTypes(
281:                                                         resultSet.getLong(IntegerConstants.THREE),
282:                                                         this.typeManager.getTypeForId(resultSet.getLong(IntegerConstants.FOUR)))));
283:                                 }
284:                                 return owners;
285:                         }
286:                 } catch (final SQLException e) {
287:                         throw new OtherSQLException(e);
288:                 }
289:         }
290:         
291:         @Override
292:         public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
293:                         final MapAssociation association,
294:                         final Date date) throws PersistenceException {
295:                 return this.inverseGetWithKeyHelper(new DBConnectionUserObjectHandler(target), association, date);
296:         }
297:         
298:         @Override
299:         public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
300:                         final MapAssociation association,
301:                         final Date date) throws PersistenceException {
302:                 return this.inverseGetWithKeyHelper(new DBConnectionStringHandler(target), association, date);
303:         }
304:         
305:         @Override
306:         public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
307:                         final MapAssociation association,
308:                         final Date date) throws PersistenceException {
309:                 return this.inverseGetWithKeyHelper(new DBConnectionIntegerHandler(target), association, date);
310:         }
311:         
312:         @Override
313:         public Collection<UserObject> find(final Association association, final String string, final Transaction transaction)
314:                         throws PersistenceException {
315:                 this.checkTransaction(transaction);
316:                 try (final CallableStatement call =
317:                                 this.database.getConnection().prepareCall(
318:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
319:                                                                 + ".objectfacade.findStringTransaction(?,?,?);" + CALL_SUFFIX)) {
320:                         call.registerOutParameter(1, OracleTypes.CURSOR);
321:                         call.setLong(2, association.getId());
322:                         call.setString(IntegerConstants.THREE, string);
323:                         call.setLong(IntegerConstants.FOUR, transaction.getId());
324:                         call.execute();
325:                         
326:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
327:                                 final Collection<UserObject> result = new HashSet<>();
328:                                 while (resultSet.next()) {
329:                                         result.add(UserObject.init(
330:                                                         resultSet.getLong(1),
331:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))));
332:                                 }
333:                                 return result;
334:                         }
335:                 } catch (final SQLException e) {
336:                         throw new OtherSQLException(e);
337:                 }
338:         }
339:         
340:         /**
341:          * This method checks if a given transaction is really an open transaction and throws an exception if not.
342:          *
343:          * @param transaction
344:          * An Transaction.
345:          * @throws PersistenceException
346:          * This Exception occurs if there are any communicating issues.
347:          * @throws NoValidTransactionException
348:          * This Exception is the Transaction is not an open transaction.
349:          */
350:         private void checkTransaction(final Transaction transaction) throws PersistenceException,
351:                         NoValidTransactionException {
352:                 if (!this.isOpenTransaction(transaction)) {
353:                         throw new NoValidTransactionException();
354:                 }
355:         }
356:         
357:         @Override
358:         public Collection<UserObject> find(final Association association,
359:                         final BigInteger integer,
360:                         final Transaction transaction) throws PersistenceException {
361:                 this.checkTransaction(transaction);
362:                 try (final CallableStatement call =
363:                                 this.database.getConnection().prepareCall(
364:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
365:                                                                 + ".objectfacade.findIntegerTransaction(?,?,?);" + CALL_SUFFIX)) {
366:                         call.registerOutParameter(1, OracleTypes.CURSOR);
367:                         call.setLong(2, association.getId());
368:                         final BigDecimal wrapper = new BigDecimal(integer);
369:                         call.setBigDecimal(IntegerConstants.THREE, wrapper);
370:                         call.setLong(IntegerConstants.FOUR, transaction.getId());
371:                         call.execute();
372:                         
373:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
374:                                 final Collection<UserObject> result = new HashSet<>();
375:                                 while (resultSet.next()) {
376:                                         result.add(UserObject.init(
377:                                                         resultSet.getLong(1),
378:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))));
379:                                 }
380:                                 return result;
381:                         }
382:                 } catch (final SQLException e) {
383:                         throw new OtherSQLException(e);
384:                 }
385:         }
386:         
387:         @Override
388:         public Collection<Tuple<UnidirectionalLink, Object>> get(final UserObject owner,
389:                         final UnidirectionalAssociation association,
390:                         final Transaction transaction) throws PersistenceException {
391:                 this.checkTransaction(transaction);
392:                 try (final CallableStatement call =
393:                                 this.database.getConnection().prepareCall(
394:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getTransaction(?,?,?);"
395:                                                                 + CALL_SUFFIX)) {
396:                         call.registerOutParameter(1, OracleTypes.CURSOR);
397:                         call.setLong(2, owner.getId());
398:                         call.setLong(IntegerConstants.THREE, association.getId());
399:                         call.setLong(IntegerConstants.FOUR, transaction.getId());
400:                         call.execute();
401:                         
402:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
403:                                 final Collection<Tuple<UnidirectionalLink, Object>> result = new ArrayList<>();
404:                                 while (resultSet.next()) {
405:                                         final Object target =
406:                                                         Object.checkForBaseTypes(
407:                                                                         resultSet.getLong(3),
408:                                                                         this.typeManager.getTypeForId(resultSet.getLong(4)));
409:                                         result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
410:                                                         .getUnidirectionalAssociationForId(resultSet.getLong(2))), target));
411:                                 }
412:                                 return result;
413:                         }
414:                 } catch (final SQLException e) {
415:                         throw new OtherSQLException(e);
416:                 }
417:         }
418:         
419:         private Collection<Tuple<MapLink, Object>> getWithKeyHelper(final UserObject owner,
420:                         final MapAssociation a,
421:                         final DBConnectionObjectHandler keyHandler,
422:                         final Transaction transaction) throws PersistenceException {
423:                 this.checkTransaction(transaction);
424:                 try (final CallableStatement call =
425:                                 this.database.getConnection().prepareCall(
426:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getMap"
427:                                                                 + keyHandler.getObjectTypeString() + "Transaction(?,?,?,?);" + CALL_SUFFIX)) {
428:                         call.registerOutParameter(1, OracleTypes.CURSOR);
429:                         call.setLong(2, owner.getId());
430:                         call.setLong(IntegerConstants.THREE, a.getId());
431:                         keyHandler.handleCall(call, IntegerConstants.FOUR);
432:                         call.setLong(IntegerConstants.FIVE, transaction.getId());
433:                         call.execute();
434:                         
435:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
436:                                 final Collection<Tuple<MapLink, Object>> result = new ArrayList<>();
437:                                 while (resultSet.next()) {
438:                                         if (!result.isEmpty()) {
439:                                                 throw new ToManyObjectsException();
440:                                         }
441:                                         final Object target =
442:                                                         Object.checkForBaseTypes(
443:                                                                         resultSet.getLong(1),
444:                                                                         this.typeManager.getTypeForId(resultSet.getLong(2)));
445:                                         final MapLink link =
446:                                                         new MapLink(resultSet.getLong(IntegerConstants.FIVE), owner, target,
447:                                                                         keyHandler.getObject(), a);
448:                                         result.add(new Tuple<>(link, target));
449:                                 }
450:                                 if (result.isEmpty()) {
451:                                         throw new ObjectNotFoundException();
452:                                 }
453:                                 return result;
454:                         }
455:                 } catch (final SQLException e) {
456:                         throw new OtherSQLException(e);
457:                 }
458:         }
459:         
460:         @Override
461:         public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
462:                         final MapAssociation association,
463:                         final String key,
464:                         final Transaction transaction) throws PersistenceException {
465:                 return this.getWithKeyHelper(owner, association, new DBConnectionStringHandler(key), transaction);
466:         }
467:         
468:         @Override
469:         public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
470:                         final MapAssociation association,
471:                         final BigInteger key,
472:                         final Transaction transaction) throws PersistenceException {
473:                 return this.getWithKeyHelper(owner, association, new DBConnectionIntegerHandler(key), transaction);
474:         }
475:         
476:         @Override
477:         public Collection<Tuple<MapLink, Object>> get(final UserObject owner,
478:                         final MapAssociation association,
479:                         final UserObject key,
480:                         final Transaction transaction) throws PersistenceException {
481:                 return this.getWithKeyHelper(owner, association, new DBConnectionUserObjectHandler(key), transaction);
482:         }
483:         
484:         @Override
485:         public Collection<Tuple<UnidirectionalLink, UserObject>> inverseGet(final UserObject target,
486:                         final UnidirectionalAssociation association,
487:                         final Transaction transaction) throws PersistenceException {
488:                 this.checkTransaction(transaction);
489:                 try (final CallableStatement call =
490:                                 this.database.getConnection().prepareCall(
491:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
492:                                                                 + ".objectfacade.inverseGetTransaction(?,?,?);" + CALL_SUFFIX)) {
493:                         call.registerOutParameter(1, OracleTypes.CURSOR);
494:                         call.setLong(2, target.getId());
495:                         call.setLong(IntegerConstants.THREE, association.getId());
496:                         call.setLong(IntegerConstants.FOUR, transaction.getId());
497:                         call.execute();
498:                         
499:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
500:                                 final Collection<Tuple<UnidirectionalLink, UserObject>> result = new ArrayList<>();
501:                                 while (resultSet.next()) {
502:                                         final UserObject owner =
503:                                                         UserObject.init(resultSet.getLong(3), this.typeManager.getTypeForId(resultSet.getLong(4)));
504:                                         result.add(new Tuple<>(new UnidirectionalLink(resultSet.getLong(1), owner, target, this.typeManager
505:                                                         .getUnidirectionalAssociationForId(resultSet.getLong(2))), owner));
506:                                 }
507:                                 return result;
508:                         }
509:                 } catch (final SQLException e) {
510:                         throw new OtherSQLException(e);
511:                 }
512:         }
513:         
514:         private Collection<Tuple<UserObject, Object>> inverseGetWithKeyHelper(final DBConnectionObjectHandler targetHandler,
515:                         final MapAssociation association,
516:                         final Transaction transaction) throws PersistenceException {
517:                 this.checkTransaction(transaction);
518:                 try (final CallableStatement call =
519:                                 this.database.getConnection().prepareCall(
520:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.inverseGetMap"
521:                                                                 + targetHandler.getObjectTypeString() + "Transaction(?,?,?);" + CALL_SUFFIX)) {
522:                         call.registerOutParameter(1, OracleTypes.CURSOR);
523:                         targetHandler.handleCall(call, 2);
524:                         call.setLong(IntegerConstants.THREE, association.getId());
525:                         call.setLong(IntegerConstants.FOUR, transaction.getId());
526:                         call.execute();
527:                         
528:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
529:                                 final Collection<Tuple<UserObject, Object>> owners = new ArrayList<>();
530:                                 while (resultSet.next()) {
531:                                         owners.add(new Tuple<>(UserObject.init(
532:                                                         resultSet.getLong(1),
533:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))), Object.checkForBaseTypes(
534:                                                         resultSet.getLong(IntegerConstants.THREE),
535:                                                         this.typeManager.getTypeForId(resultSet.getLong(IntegerConstants.FOUR)))));
536:                                 }
537:                                 return owners;
538:                         }
539:                 } catch (final SQLException e) {
540:                         throw new OtherSQLException(e);
541:                 }
542:         }
543:         
544:         @Override
545:         public Collection<Tuple<UserObject, Object>> inverseGet(final UserObject target,
546:                         final MapAssociation association,
547:                         final Transaction transaction) throws PersistenceException {
548:                 return this.inverseGetWithKeyHelper(new DBConnectionUserObjectHandler(target), association, transaction);
549:         }
550:         
551:         @Override
552:         public Collection<Tuple<UserObject, Object>> inverseGet(final String target,
553:                         final MapAssociation association,
554:                         final Transaction transaction) throws PersistenceException {
555:                 return this.inverseGetWithKeyHelper(new DBConnectionStringHandler(target), association, transaction);
556:         }
557:         
558:         @Override
559:         public Collection<Tuple<UserObject, Object>> inverseGet(final BigInteger target,
560:                         final MapAssociation association,
561:                         final Transaction transaction) throws PersistenceException {
562:                 return this.inverseGetWithKeyHelper(new DBConnectionIntegerHandler(target), association, transaction);
563:         }
564:         
565:         @Override
566:         public boolean isInConflict(final Transaction transaction1, final Transaction transaction2)
567:                         throws PersistenceException {
568:                 this.checkTransaction(transaction1);
569:                 this.checkTransaction(transaction2);
570:                 try (final CallableStatement call =
571:                                 this.database.getConnection().prepareCall(
572:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
573:                                                                 + ".objectfacade.getConflictingTransactions(?);" + CALL_SUFFIX)) {
574:                         call.registerOutParameter(1, OracleTypes.CURSOR);
575:                         call.setLong(2, transaction1.getId());
576:                         call.execute();
577:                         
578:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
579:                                 while (resultSet.next()) {
580:                                         if (transaction2.getId() == resultSet.getLong(1)) {
581:                                                 return true;
582:                                         }
583:                                 }
584:                                 return false;
585:                         }
586:                 } catch (final SQLException e) {
587:                         throw new OtherSQLException(e);
588:                 }
589:         }
590:         
591:         @Override
592:         public boolean isOpenTransaction(final Transaction transaction) throws PersistenceException {
593:                 try (final CallableStatement call =
594:                                 this.database.getConnection().prepareCall(
595:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.isTransactionOpen(?);"
596:                                                                 + CALL_SUFFIX)) {
597:                         call.registerOutParameter(1, OracleTypes.NUMBER);
598:                         call.setLong(2, transaction.getId());
599:                         call.execute();
600:                         return call.getInt(1) == 1 ? true : false;
601:                 } catch (final SQLException e) {
602:                         throw new OtherSQLException(e);
603:                 }
604:         }
605:         
606:         @Override
607:         public UserObject create(final UserType type, final Transaction transaction) throws PersistenceException {
608:                 this.checkTransaction(transaction);
609:                 try (final CallableStatement call =
610:                                 this.database.getConnection().prepareCall(
611:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.createUserObject(?,?);"
612:                                                                 + CALL_SUFFIX)) {
613:                         call.registerOutParameter(1, OracleTypes.NUMBER);
614:                         call.setLong(2, type.getId());
615:                         call.setLong(IntegerConstants.THREE, transaction.getId());
616:                         call.execute();
617:                         return UserObject.init(call.getLong(1), type);
618:                 } catch (final SQLException e) {
619:                         if (e.getErrorCode() == NotInstantiatableException.ERRORCODE) {
620:                                 throw new NotInstantiatableException(e);
621:                         }
622:                         e.printStackTrace();
623:                         throw new OtherSQLException(e);
624:                 }
625:         }
626:         
627:         @Override
628:         public void delete(final UserObject object, final Transaction transaction) throws PersistenceException {
629:                 this.checkTransaction(transaction);
630:                 try (final CallableStatement call =
631:                                 this.database.getConnection().prepareCall(
632:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
633:                                                                 + ".objectfacade.deleteUserObject(?,?);" + CALL_SUFFIX)) {
634:                         call.setLong(1, object.getId());
635:                         call.setLong(2, transaction.getId());
636:                         call.execute();
637:                 } catch (final SQLException e) {
638:                         if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
639:                                 throw new InvalidLinkException(e);
640:                         }
641:                         throw new OtherSQLException(e);
642:                 }
643:         }
644:         
645:         private UnidirectionalLink setHelper(final UserObject owner,
646:                         final UnidirectionalAssociation association,
647:                         final DBConnectionObjectHandler targetHandler,
648:                         final Transaction transaction) throws PersistenceException {
649:                 this.checkTransaction(transaction);
650:                 try (final CallableStatement call =
651:                                 this.database.getConnection().prepareCall(
652:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.set"
653:                                                                 + targetHandler.getObjectTypeString() + "(?,?,?,?);" + CALL_SUFFIX)) {
654:                         call.registerOutParameter(1, OracleTypes.NUMBER);
655:                         call.setLong(2, owner.getId());
656:                         call.setLong(IntegerConstants.THREE, association.getId());
657:                         targetHandler.handleCall(call, IntegerConstants.FOUR);
658:                         call.setLong(IntegerConstants.FIVE, transaction.getId());
659:                         call.execute();
660:                         return new UnidirectionalLink(call.getLong(1), owner, targetHandler.getObject(), association);
661:                 } catch (final SQLException e) {
662:                         if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
663:                                 throw new InvalidLinkException(e);
664:                         }
665:                         if (e.getErrorCode() == NotInScopeException.ERRORCODE) {
666:                                 throw new NotInScopeException(e);
667:                         }
668:                         throw new OtherSQLException(e);
669:                 }
670:         }
671:         
672:         @Override
673:         public UnidirectionalLink set(final UserObject owner,
674:                         final UnidirectionalAssociation association,
675:                         final UserObject target,
676:                         final Transaction transaction) throws PersistenceException {
677:                 return this.setHelper(owner, association, new DBConnectionUserObjectHandler(target), transaction);
678:         }
679:         
680:         @Override
681:         public UnidirectionalLink set(final UserObject owner,
682:                         final UnidirectionalAssociation association,
683:                         final BigInteger target,
684:                         final Transaction transaction) throws PersistenceException {
685:                 return this.setHelper(owner, association, new DBConnectionIntegerHandler(target), transaction);
686:         }
687:         
688:         @Override
689:         public UnidirectionalLink set(final UserObject owner,
690:                         final UnidirectionalAssociation association,
691:                         final String target,
692:                         final Transaction transaction) throws PersistenceException {
693:                 return this.setHelper(owner, association, new DBConnectionStringHandler(target), transaction);
694:         }
695:         
696:         private MapLink putHelper(final UserObject owner,
697:                         final MapAssociation association,
698:                         final DBConnectionObjectHandler targetHandler,
699:                         final DBConnectionObjectHandler keyHandler,
700:                         final Transaction transaction) throws PersistenceException {
701:                 try (final CallableStatement call =
702:                                 this.database.getConnection().prepareCall(
703:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.put"
704:                                                                 + targetHandler.getObjectTypeString() + keyHandler.getObjectTypeString()
705:                                                                 + "(?,?,?,?,?);" + CALL_SUFFIX)) {
706:                         call.registerOutParameter(1, OracleTypes.NUMBER);
707:                         call.setLong(2, owner.getId());
708:                         call.setLong(IntegerConstants.THREE, association.getId());
709:                         targetHandler.handleCall(call, IntegerConstants.FOUR);
710:                         keyHandler.handleCall(call, IntegerConstants.FIVE);
711:                         call.setLong(IntegerConstants.SIX, transaction.getId());
712:                         call.execute();
713:                         return new MapLink(call.getLong(1), owner, targetHandler.getObject(), keyHandler.getObject(), association);
714:                 } catch (final SQLException e) {
715:                         if (e.getErrorCode() == InvalidLinkException.ERRORCODE) {
716:                                 throw new InvalidLinkException(e);
717:                         }
718:                         if (e.getErrorCode() == NotInScopeException.ERRORCODE) {
719:                                 throw new NotInScopeException(e);
720:                         }
721:                         if (e.getErrorCode() == DuplicateEntryException.ERRORCODE) {
722:                                 throw new DuplicateEntryException(e);
723:                         }
724:                         throw new OtherSQLException(e);
725:                 }
726:         }
727:         
728:         @Override
729:         public MapLink put(final UserObject owner,
730:                         final MapAssociation association,
731:                         final UserObject target,
732:                         final String key,
733:                         final Transaction transaction) throws PersistenceException {
734:                 return this.putHelper(
735:                                 owner,
736:                                 association,
737:                                 new DBConnectionUserObjectHandler(target),
738:                                 new DBConnectionStringHandler(key),
739:                                 transaction);
740:         }
741:         
742:         @Override
743:         public MapLink put(final UserObject owner,
744:                         final MapAssociation association,
745:                         final BigInteger target,
746:                         final String key,
747:                         final Transaction transaction) throws PersistenceException {
748:                 return this.putHelper(
749:                                 owner,
750:                                 association,
751:                                 new DBConnectionIntegerHandler(target),
752:                                 new DBConnectionStringHandler(key),
753:                                 transaction);
754:         }
755:         
756:         @Override
757:         public MapLink put(final UserObject owner,
758:                         final MapAssociation association,
759:                         final String target,
760:                         final String key,
761:                         final Transaction transaction) throws PersistenceException {
762:                 return this.putHelper(owner, association, new DBConnectionStringHandler(target), new DBConnectionStringHandler(
763:                                 key), transaction);
764:         }
765:         
766:         @Override
767:         public MapLink put(final UserObject owner,
768:                         final MapAssociation association,
769:                         final UserObject target,
770:                         final BigInteger key,
771:                         final Transaction transaction) throws PersistenceException {
772:                 return this.putHelper(
773:                                 owner,
774:                                 association,
775:                                 new DBConnectionUserObjectHandler(target),
776:                                 new DBConnectionIntegerHandler(key),
777:                                 transaction);
778:         }
779:         
780:         @Override
781:         public MapLink put(final UserObject owner,
782:                         final MapAssociation association,
783:                         final BigInteger target,
784:                         final BigInteger key,
785:                         final Transaction transaction) throws PersistenceException {
786:                 return this.putHelper(
787:                                 owner,
788:                                 association,
789:                                 new DBConnectionIntegerHandler(target),
790:                                 new DBConnectionIntegerHandler(key),
791:                                 transaction);
792:         }
793:         
794:         @Override
795:         public MapLink put(final UserObject owner,
796:                         final MapAssociation association,
797:                         final String target,
798:                         final BigInteger key,
799:                         final Transaction transaction) throws PersistenceException {
800:                 return this.putHelper(
801:                                 owner,
802:                                 association,
803:                                 new DBConnectionStringHandler(target),
804:                                 new DBConnectionIntegerHandler(key),
805:                                 transaction);
806:         }
807:         
808:         @Override
809:         public MapLink put(final UserObject owner,
810:                         final MapAssociation association,
811:                         final UserObject target,
812:                         final UserObject key,
813:                         final Transaction transaction) throws PersistenceException {
814:                 return this.putHelper(
815:                                 owner,
816:                                 association,
817:                                 new DBConnectionUserObjectHandler(target),
818:                                 new DBConnectionUserObjectHandler(key),
819:                                 transaction);
820:         }
821:         
822:         @Override
823:         public MapLink put(final UserObject owner,
824:                         final MapAssociation association,
825:                         final BigInteger target,
826:                         final UserObject key,
827:                         final Transaction transaction) throws PersistenceException {
828:                 return this.putHelper(
829:                                 owner,
830:                                 association,
831:                                 new DBConnectionIntegerHandler(target),
832:                                 new DBConnectionUserObjectHandler(key),
833:                                 transaction);
834:         }
835:         
836:         @Override
837:         public MapLink put(final UserObject owner,
838:                         final MapAssociation association,
839:                         final String target,
840:                         final UserObject key,
841:                         final Transaction transaction) throws PersistenceException {
842:                 return this.putHelper(
843:                                 owner,
844:                                 association,
845:                                 new DBConnectionStringHandler(target),
846:                                 new DBConnectionUserObjectHandler(key),
847:                                 transaction);
848:         }
849:         
850:         @Override
851:         public void unset(final Link link, final Transaction transaction) throws PersistenceException {
852:                 this.checkTransaction(transaction);
853:                 try (final CallableStatement call =
854:                                 this.database.getConnection().prepareCall(
855:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.unset(?,?);"
856:                                                                 + CALL_SUFFIX)) {
857:                         call.setLong(1, link.getId());
858:                         call.setLong(2, transaction.getId());
859:                         call.execute();
860:                 } catch (final SQLException e) {
861:                         throw new OtherSQLException(e);
862:                 }
863:         }
864:         
865:         @Override
866:         public void commit(final Transaction transaction) throws PersistenceException {
867:                 this.checkTransaction(transaction);
868:                 try (final CallableStatement call =
869:                                 this.database.getConnection().prepareCall(
870:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.commitTransaction(?);"
871:                                                                 + CALL_SUFFIX)) {
872:                         call.setLong(1, transaction.getId());
873:                         call.execute();
874:                 } catch (final SQLException e) {
875:                         throw new OtherSQLException(e);
876:                 }
877:         }
878:         
879:         @Override
880:         public void rollback(final Transaction transaction) throws PersistenceException {
881:                 this.checkTransaction(transaction);
882:                 try (final CallableStatement call =
883:                                 this.database.getConnection().prepareCall(
884:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
885:                                                                 + ".objectfacade.rollbackTransaction(?);" + CALL_SUFFIX)) {
886:                         call.setLong(1, transaction.getId());
887:                         call.execute();
888:                 } catch (final SQLException e) {
889:                         throw new OtherSQLException(e);
890:                 }
891:         }
892:         
893:         @Override
894:         public void savePoint(final Transaction transaction) throws PersistenceException {
895:                 this.checkTransaction(transaction);
896:                 try (final CallableStatement call =
897:                                 this.database.getConnection().prepareCall(
898:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.makeSavePoint(?);"
899:                                                                 + CALL_SUFFIX)) {
900:                         call.setLong(1, transaction.getId());
901:                         call.execute();
902:                 } catch (final SQLException e) {
903:                         throw new OtherSQLException(e);
904:                 }
905:         }
906:         
907:         @Override
908:         public void rollbackToSavePoint(final Transaction transaction) throws PersistenceException {
909:                 this.checkTransaction(transaction);
910:                 try (final CallableStatement call =
911:                                 this.database.getConnection().prepareCall(
912:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName()
913:                                                                 + ".objectfacade.rollbackToSavePoint(?);" + CALL_SUFFIX)) {
914:                         call.setLong(1, transaction.getId());
915:                         call.execute();
916:                 } catch (final SQLException e) {
917:                         throw new OtherSQLException(e);
918:                 }
919:         }
920:         
921:         @Override
922:         public BigInteger getIntForId(final long id) throws PersistenceException {
923:                 try (final CallableStatement call =
924:                                 this.database.getConnection().prepareCall(
925:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getInteger(?);"
926:                                                                 + CALL_SUFFIX)) {
927:                         call.registerOutParameter(1, OracleTypes.NUMBER);
928:                         call.setLong(2, id);
929:                         call.execute();
930:                         return BigInteger.valueOf(call.getLong(1));
931:                 } catch (final SQLException e) {
932:                         if (e.getErrorCode() == BaseTypeNotFoundException.ERRORCODE) {
933:                                 throw new BaseTypeNotFoundException();
934:                         }
935:                         throw new OtherSQLException(e);
936:                 }
937:         }
938:         
939:         @Override
940:         public String getStringForId(final long id) throws PersistenceException {
941:                 try (final CallableStatement call =
942:                                 this.database.getConnection().prepareCall(
943:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getString(?);"
944:                                                                 + CALL_SUFFIX)) {
945:                         call.registerOutParameter(1, OracleTypes.VARCHAR);
946:                         call.setLong(2, id);
947:                         call.execute();
948:                         return call.getString(1);
949:                 } catch (final SQLException e) {
950:                         if (e.getErrorCode() == BaseTypeNotFoundException.ERRORCODE) {
951:                                 throw new BaseTypeNotFoundException();
952:                         }
953:                         throw new OtherSQLException(e);
954:                 }
955:         }
956:         
957:         @Override
958:         public long getIdForString(final String string) throws PersistenceException {
959:                 try (final CallableStatement call =
960:                                 this.database.getConnection().prepareCall(
961:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getStringObject(?);"
962:                                                                 + CALL_SUFFIX)) {
963:                         call.registerOutParameter(1, OracleTypes.NUMBER);
964:                         call.setString(2, string);
965:                         call.execute();
966:                         return call.getLong(1);
967:                 } catch (final SQLException e) {
968:                         throw new OtherSQLException(e);
969:                 }
970:         }
971:         
972:         @Override
973:         public long getIdForInteger(final BigInteger integer) throws PersistenceException {
974:                 try (final CallableStatement call =
975:                                 this.database.getConnection().prepareCall(
976:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName() + ".objectfacade.getIntegerObject(?);"
977:                                                                 + CALL_SUFFIX)) {
978:                         call.registerOutParameter(1, OracleTypes.NUMBER);
979:                         final BigDecimal wrapper = new BigDecimal(integer);
980:                         call.setBigDecimal(2, wrapper);
981:                         call.execute();
982:                         return call.getLong(1);
983:                 } catch (final SQLException e) {
984:                         throw new OtherSQLException(e);
985:                 }
986:         }
987:         
988:         @Override
989:         public Transaction provideAdhocTransaction() throws PersistenceException {
990:                 try (final CallableStatement call =
991:                                 this.database.getConnection().prepareCall(
992:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
993:                                                                 + ".objectfacade.provideAdhocTransaction;" + CALL_SUFFIX)) {
994:                         call.registerOutParameter(1, OracleTypes.NUMBER);
995:                         call.execute();
996:                         return new AdhocTransaction(call.getLong(1));
997:                 } catch (final SQLException e) {
998:                         throw new OtherSQLException(e);
999:                 }
1000:         }
1001:         
1002:         @Override
1003:         public TypeManager getTypeManager() {
1004:                 return this.typeManager;
1005:         }
1006:         
1007:         @Override
1008:         public void clear() throws PersistenceException {
1009:                 try (final CallableStatement call =
1010:                                 this.database.getConnection().prepareCall(
1011:                                                 STORED_PROCEDURE_PREFIX + this.database.getSchemaName() + ".objectfacade.clear;" + CALL_SUFFIX)) {
1012:                         call.execute();
1013:                 } catch (final SQLException e) {
1014:                         e.printStackTrace();
1015:                         throw new OtherSQLException(e);
1016:                 }
1017:         }
1018:         
1019:         @Override
1020:         public Collection<UserObject> findAllObjects(final UserType type, final Transaction transaction)
1021:                         throws PersistenceException {
1022:                 final Collection<UserObject> result = new HashSet<>();
1023:                 try (final CallableStatement call =
1024:                                 this.database.getConnection().prepareCall(
1025:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
1026:                                                                 + ".objectfacade.findUserObjectByType(?,?);" + CALL_SUFFIX)) {
1027:                         call.registerOutParameter(1, OracleTypes.CURSOR);
1028:                         call.setLong(2, type.getId());
1029:                         call.setLong(IntegerConstants.THREE, transaction.getId());
1030:                         call.execute();
1031:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
1032:                                 while (resultSet.next()) {
1033:                                         result.add(UserObject.init(
1034:                                                         resultSet.getLong(1),
1035:                                                         this.typeManager.getTypeForId(resultSet.getLong(2))));
1036:                                 }
1037:                         }
1038:                 } catch (final SQLException e) {
1039:                         throw new OtherSQLException(e);
1040:                 }
1041:                 return result;
1042:         }
1043:         
1044:         @Override
1045:         public UserObject checkUserObjectOut(final long id, final Transaction transaction) throws PersistenceException {
1046:                 try (final CallableStatement call =
1047:                                 this.database.getConnection().prepareCall(
1048:                                                 STORED_FUNCTION_PREFIX + this.database.getSchemaName()
1049:                                                                 + ".objectfacade.checkUserObjectOut(?,?);" + CALL_SUFFIX)) {
1050:                         call.registerOutParameter(1, OracleTypes.CURSOR);
1051:                         call.setLong(2, id);
1052:                         call.setLong(IntegerConstants.THREE, transaction.getId());
1053:                         call.execute();
1054:                         try (final ResultSet resultSet = ((OracleCallableStatement) call).getCursor(1)) {
1055:                                 if (resultSet.next()) {
1056:                                         return UserObject.init(resultSet.getLong(1), this.typeManager.getTypeForId(resultSet.getLong(2)));
1057:                                 } else {
1058:                                         throw new ObjectNotFoundException();
1059:                                 }
1060:                         }
1061:                 } catch (final SQLException e) {
1062:                         throw new OtherSQLException(e);
1063:                 }
1064:         }
1065: }