001package com.avaje.ebean; 002 003import com.avaje.ebean.backgroundexecutor.ImmediateBackgroundExecutor; 004import com.avaje.ebean.cache.ServerCacheManager; 005import com.avaje.ebean.delegate.DelegateBulkUpdate; 006import com.avaje.ebean.delegate.DelegateDelete; 007import com.avaje.ebean.delegate.DelegateFind; 008import com.avaje.ebean.delegate.DelegateFindSqlQuery; 009import com.avaje.ebean.delegate.DelegatePublish; 010import com.avaje.ebean.delegate.DelegateQuery; 011import com.avaje.ebean.delegate.DelegateSave; 012import com.avaje.ebean.delegate.InterceptBulkUpdate; 013import com.avaje.ebean.delegate.InterceptDelete; 014import com.avaje.ebean.delegate.InterceptFind; 015import com.avaje.ebean.delegate.InterceptFindSqlQuery; 016import com.avaje.ebean.delegate.InterceptPublish; 017import com.avaje.ebean.delegate.InterceptSave; 018import com.avaje.ebean.meta.MetaInfoManager; 019import com.avaje.ebean.plugin.SpiServer; 020import com.avaje.ebean.text.csv.CsvReader; 021import com.avaje.ebean.text.json.JsonContext; 022import com.avaje.ebeaninternal.api.SpiQuery; 023 024import javax.persistence.OptimisticLockException; 025import javax.persistence.PersistenceException; 026import java.util.Collection; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030 031/** 032 * Wraps an underlying EbeanServer. 033 * <p> 034 * Can you used for testing purposes when you want to create a test double that 035 * only replaces some of the underlying functionality of the EbeanServer, for example 036 * only overwrites some of the find or save functionality but leaves the rest of the 037 * behavior to be handled normally by the underlying delegate. 038 * <p> 039 * The underlying delegate is most often a fully functional EbeanServer that is using H2 040 * as a test database. 041 * </p> 042 */ 043public class DelegateEbeanServer implements EbeanServer, DelegateAwareEbeanServer, DelegateMethodNames { 044 045 /** 046 * The list of methods calls made to this server. 047 */ 048 public MethodCalls methodCalls = new MethodCalls(); 049 050 /** 051 * The beans sent to the save(), delete() methods etc. 052 */ 053 public BeanCapture capturedBeans = new BeanCapture(); 054 055 /** 056 * Various find methods that have specific test responses. 057 */ 058 protected WhenFind whenFind = new WhenFind(); 059 060 /** 061 * Test double replacements for 'Finders' which are static fields on entity beans. 062 */ 063 protected WithStaticFinders withStaticFinders = new WithStaticFinders(); 064 065 /** 066 * The underlying EbeanServer we delegate to. 067 * <p/> 068 * This will often be a fully functional EbeanSever that uses H2. 069 */ 070 protected EbeanServer delegate; 071 072 /** 073 * Expect ImmediateBackgroundExecutor to be a good default. Can use IgnoreBackgroundExecutor or the delegates one. 074 */ 075 protected BackgroundExecutor backgroundExecutor = new ImmediateBackgroundExecutor(); 076 077 /** 078 * Constructs queries that will call back to this so not really expecting it to be overwritten. 079 */ 080 protected DelegateQuery delegateQuery; 081 082 protected InterceptSave save; 083 084 protected InterceptBulkUpdate bulkUpdate; 085 086 protected InterceptDelete delete; 087 088 protected InterceptFind find; 089 090 protected InterceptPublish publish; 091 092 protected InterceptFindSqlQuery findSqlQuery; 093 094 /** 095 * If set to true the 'bulk update' calls are passed through to the underlying delegate. 096 */ 097 protected boolean persistBulkUpdates; 098 099 /** 100 * If set to true the 'delete' calls are passed through to the underlying delegate. 101 */ 102 protected boolean persistDeletes; 103 104 /** 105 * If set to true the 'insert' calls are passed through to the underlying delegate. 106 */ 107 protected boolean persistInserts; 108 109 /** 110 * If set to true the 'save' calls are passed through to the underlying delegate. 111 */ 112 protected boolean persistSaves; 113 114 /** 115 * If set to true the 'update' calls are passed through to the underlying delegate. 116 */ 117 protected boolean persistUpdates; 118 119 /** 120 * If set to true the publish/draft calls are passed through to the underlying delegate. 121 */ 122 protected boolean persistPublish; 123 124 /** 125 * Construct with defaults. 126 */ 127 public DelegateEbeanServer() { 128 129 } 130 131 /** 132 * Construct with a EbeanServer to delegate and using ImmediateBackgroundExecutor. 133 * <p> 134 * This delegate will be used on all method calls that are not overwritten. 135 */ 136 public DelegateEbeanServer withDelegate(EbeanServer delegate) { 137 this.delegate = delegate; 138 this.delegateQuery = new DelegateQuery(delegate, this); 139 this.save = new DelegateSave(delegate); 140 this.delete = new DelegateDelete(delegate); 141 this.bulkUpdate = new DelegateBulkUpdate(delegate); 142 this.find = new DelegateFind(delegate); 143 this.findSqlQuery = new DelegateFindSqlQuery(delegate); 144 this.publish = new DelegatePublish(delegate); 145 return this; 146 } 147 148 @Override 149 public void beforeRun() { 150 withStaticFinders.beforeRun(); 151 } 152 153 @Override 154 public void afterRun() { 155 withStaticFinders.afterRun(); 156 } 157 158 public WhenFind whenFind() { 159 return whenFind; 160 } 161 162 /** 163 * Used to specify a test double to replace a static 'finder' field on the given beanType. 164 * <pre>{@code 165 * 166 * DelegateEbeanServer mock = new DelegateEbeanServer(); 167 * mock.withFinder(Customer.class).as(new TDCustomerFinder()); 168 * 169 * // Note: TDCustomerFinder not set onto Customer until runWithMock() 170 * 171 * MockiEbean.runWithMock(mock, new Runnable() { 172 * 173 * public void run() { 174 * ... 175 * // Customer.find now is our test double TDCustomerFinder 176 * Customer found = Customer.find.byUniqueName("foo"); 177 * } 178 * }); 179 * 180 * // Note: original Customer.find implementation is restored by MockiEbean 181 * 182 * }</pre> 183 */ 184 public <T> WithStaticFinder<T> withFinder(Class<T> beanType) { 185 return withStaticFinders.withFinder(beanType); 186 } 187 188 189 /** 190 * Set the underlying delegate to proxy requests to. 191 * <p/> 192 * Used with the default constructor such that this DelegateEbeanServer 193 * can be setup prior to having access to the underlying EbeanServer 194 * that we want to proxy through to. 195 * <p/> 196 * Return true if the underling ebeanServer was set. 197 */ 198 public boolean withDelegateIfRequired(EbeanServer delegate) { 199 if (this.delegate == null) { 200 withDelegate(delegate); 201 return true; 202 } 203 if (this.delegate instanceof DelegateAwareEbeanServer) { 204 // probably using ProxyEbeanServer to capture method calls etc 205 return ((DelegateAwareEbeanServer)this.delegate).withDelegateIfRequired(delegate); 206 } 207 // delegate was not set 208 return false; 209 } 210 211 public DelegateEbeanServer withInterceptFind(InterceptFind find) { 212 this.find = find; 213 return this; 214 } 215 216 /** 217 * Set to true for all the persisting calls skip/avoid calling the underlying delegate. 218 * <p> 219 * So when set to true then all the calls to save(), delete() etc do not get passed on the 220 * the underlying delegate. 221 */ 222 public DelegateEbeanServer withPersisting(boolean persisting) { 223 persistBulkUpdates = persisting; 224 persistDeletes = persisting; 225 persistInserts = persisting; 226 persistUpdates = persisting; 227 persistSaves = persisting; 228 return this; 229 } 230 231 @Override 232 public SpiServer getPluginApi() { 233 methodCalls.add(MethodCall.of("getPluginApi")); 234 return delegate.getPluginApi(); 235 } 236 237 @Override 238 public AutoTune getAutoTune() { 239 methodCalls.add(MethodCall.of("getAutoTune")); 240 return delegate.getAutoTune(); 241 } 242 243 @Override 244 public DocumentStore docStore() { 245 methodCalls.add(MethodCall.of("docStore")); 246 return delegate.docStore(); 247 } 248 249 /** 250 * Return the BackgroundExecutor. 251 * 252 * Typically for testing we either want these to run immediately or not at all. 253 * Defaults to use ImmediateBackgroundExecutor, use IgnoreBackgroundExecutor if desired. 254 */ 255 @Override 256 public BackgroundExecutor getBackgroundExecutor() { 257 methodCalls.add(MethodCall.of("getBackgroundExecutor")); 258 return backgroundExecutor; 259 } 260 261 @Override 262 public ServerCacheManager getServerCacheManager() { 263 methodCalls.add(MethodCall.of("getServerCacheManager")); 264 return delegate.getServerCacheManager(); 265 } 266 267 @Override 268 public void shutdown(boolean shutdownDataSource, boolean deregisterDriver) { 269 methodCalls.add(MethodCall.of("shutdown").with("shutdownDataSource", shutdownDataSource, "deregisterDriver", deregisterDriver)); 270 delegate.shutdown(shutdownDataSource, deregisterDriver); 271 } 272 273 @Override 274 public JsonContext json() { 275 methodCalls.add(MethodCall.of("json")); 276 return delegate.json(); 277 } 278 279 @Override 280 public String getName() { 281 methodCalls.add(MethodCall.of("getName")); 282 return delegate.getName(); 283 } 284 285 @Override 286 public ExpressionFactory getExpressionFactory() { 287 methodCalls.add(MethodCall.of("getExpressionFactory")); 288 return delegate.getExpressionFactory(); 289 } 290 291 @Override 292 public MetaInfoManager getMetaInfoManager() { 293 methodCalls.add(MethodCall.of("getMetaInfoManager")); 294 return delegate.getMetaInfoManager(); 295 } 296 297 @Override 298 public BeanState getBeanState(Object bean) { 299 methodCalls.add(MethodCall.of("getBeanState").with("bean", bean)); 300 return delegate.getBeanState(bean); 301 } 302 303 @Override 304 public Object getBeanId(Object bean) { 305 methodCalls.add(MethodCall.of("getBeanId").with("bean", bean)); 306 return delegate.getBeanId(bean); 307 } 308 309 @Override 310 public Object setBeanId(Object bean, Object id) { 311 methodCalls.add(MethodCall.of("setBeanId").with("bean", bean).with("id", id)); 312 return delegate.setBeanId(bean, id); 313 } 314 315 @Override 316 public Map<String, ValuePair> diff(Object a, Object b) { 317 methodCalls.add(MethodCall.of("diff").with("a", a, "b", b)); 318 return delegate.diff(a, b); 319 } 320 321 @Override 322 public <T> T createEntityBean(Class<T> beanType) { 323 methodCalls.add(MethodCall.of("createEntityBean").with("beanType", beanType)); 324 return delegate.createEntityBean(beanType); 325 } 326 327 @Override 328 public <T> CsvReader<T> createCsvReader(Class<T> beanType) { 329 methodCalls.add(MethodCall.of("createCsvReader").with("beanType", beanType)); 330 return delegate.createCsvReader(beanType); 331 } 332 333 @Override 334 public <T> Filter<T> filter(Class<T> beanType) { 335 methodCalls.add(MethodCall.of("filter").with("beanType", beanType)); 336 return delegate.filter(beanType); 337 } 338 339 @Override 340 public <T> void sort(List<T> list, String sortByClause) { 341 methodCalls.add(MethodCall.of("sort").with("list", list, "sortByClause", sortByClause)); 342 delegate.sort(list, sortByClause); 343 } 344 345 @Override 346 public void markAsDirty(Object bean) { 347 methodCalls.add(MethodCall.of("markAsDirty").with("bean", bean)); 348 delegate.markAsDirty(bean); 349 } 350 351 352 // -- create updates ------------------------ 353 354 @Override 355 public <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) { 356 methodCalls.add(MethodCall.of("createUpdate").with("beanType", beanType, "ormUpdate", ormUpdate)); 357 return delegate.createUpdate(beanType, ormUpdate); 358 } 359 360 @Override 361 public SqlUpdate createSqlUpdate(String sql) { 362 methodCalls.add(MethodCall.of("createSqlUpdate").with("sql", sql)); 363 return delegate.createSqlUpdate(sql); 364 } 365 366 @Override 367 public CallableSql createCallableSql(String callableSql) { 368 methodCalls.add(MethodCall.of("createCallableSql").with("callableSql", callableSql)); 369 return delegate.createCallableSql(callableSql); 370 } 371 372 // -- transaction ------------------------ 373 374 @Override 375 public void execute(TxScope scope, TxRunnable runnable) { 376 methodCalls.add(MethodCall.of("bulkUpdate").with("scope", scope, "runnable", runnable)); 377 delegate.execute(scope, runnable); 378 } 379 380 @Override 381 public void execute(TxRunnable runnable) { 382 methodCalls.add(MethodCall.of("bulkUpdate").with("runnable", runnable)); 383 delegate.execute(runnable); 384 } 385 386 @Override 387 public <T> T execute(TxScope scope, TxCallable<T> callable) { 388 methodCalls.add(MethodCall.of("bulkUpdate").with("scope", scope, "callable", callable)); 389 return delegate.execute(scope, callable); 390 } 391 392 @Override 393 public <T> T execute(TxCallable<T> callable) { 394 methodCalls.add(MethodCall.of("bulkUpdate").with("callable", callable)); 395 return delegate.execute(callable); 396 } 397 398 @Override 399 public void register(TransactionCallback transactionCallback) throws PersistenceException { 400 methodCalls.add(MethodCall.of("register").with("transactionCallback", transactionCallback)); 401 delegate.register(transactionCallback); 402 } 403 404 @Override 405 public Transaction createTransaction() { 406 methodCalls.add(MethodCall.of("createTransaction")); 407 return delegate.createTransaction(); 408 } 409 410 @Override 411 public Transaction createTransaction(TxIsolation isolation) { 412 methodCalls.add(MethodCall.of("createTransaction").with("isolation", isolation)); 413 return delegate.createTransaction(isolation); 414 } 415 416 @Override 417 public Transaction beginTransaction() { 418 methodCalls.add(MethodCall.of("beginTransaction")); 419 return delegate.beginTransaction(); 420 } 421 422 @Override 423 public Transaction beginTransaction(TxIsolation isolation) { 424 methodCalls.add(MethodCall.of("beginTransaction").with("isolation", isolation)); 425 return delegate.beginTransaction(isolation); 426 } 427 428 @Override 429 public Transaction beginTransaction(TxScope scope) { 430 methodCalls.add(MethodCall.of("beginTransaction").with("scope", scope)); 431 return delegate.beginTransaction(scope); 432 } 433 434 @Override 435 public Transaction currentTransaction() { 436 methodCalls.add(MethodCall.of("currentTransaction")); 437 return delegate.currentTransaction(); 438 } 439 440 @Override 441 public void commitTransaction() { 442 methodCalls.add(MethodCall.of("commitTransaction")); 443 delegate.commitTransaction(); 444 } 445 446 @Override 447 public void rollbackTransaction() { 448 methodCalls.add(MethodCall.of("rollbackTransaction")); 449 delegate.rollbackTransaction(); 450 } 451 452 @Override 453 public void endTransaction() { 454 methodCalls.add(MethodCall.of("endTransaction")); 455 delegate.endTransaction(); 456 } 457 458 // -- delegateQuery ------------------------ 459 460 @Override 461 public <T> T getReference(Class<T> beanType, Object id) { 462 methodCalls.add(MethodCall.of("getReference").with("beanType", beanType, "id", id)); 463 return delegateQuery.getReference(beanType, id); 464 } 465 466 @Override 467 public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) { 468 methodCalls.add(MethodCall.of("createNamedQuery").with("beanType", beanType).with("namedQuery", namedQuery)); 469 return delegateQuery.createNamedQuery(beanType, namedQuery); 470 } 471 472 @Override 473 public <T> Query<T> createQuery(Class<T> beanType, String eql) { 474 methodCalls.add(MethodCall.of("createQuery").with("beanType", beanType).with("eql", eql)); 475 return delegateQuery.createQuery(beanType, eql); 476 } 477 478 @Override 479 public <T> Query<T> createQuery(Class<T> beanType) { 480 methodCalls.add(MethodCall.of("createQuery").with("beanType", beanType)); 481 return delegateQuery.createQuery(beanType); 482 } 483 484 @Override 485 public <T> Set<String> validateQuery(Query<T> query) { 486 methodCalls.add(MethodCall.of("validateQuery").with("query", query)); 487 return delegateQuery.validateQuery(query); 488 } 489 490 @Override 491 public <T> Query<T> find(Class<T> beanType) { 492 methodCalls.add(MethodCall.of("find").with("beanType", beanType)); 493 return delegateQuery.find(beanType); 494 } 495 496 @Override 497 public SqlQuery createSqlQuery(String sql) { 498 methodCalls.add(MethodCall.of("createSqlQuery").with("sql", sql)); 499 return delegateQuery.createSqlQuery(sql); 500 } 501 502 // -- refresh ------------------------ 503 504 @Override 505 public void refresh(Object bean) { 506 methodCalls.add(MethodCall.of("refresh").with("bean", bean)); 507 find.refresh(bean); 508 } 509 510 @Override 511 public void refreshMany(Object bean, String propertyName) { 512 methodCalls.add(MethodCall.of("refreshMany").with("bean", bean, "propertyName", propertyName)); 513 find.refreshMany(bean, propertyName); 514 } 515 516 // -- find ------------------------ 517 518 @Override 519 public <T> T find(Class<T> beanType, Object id) { 520 methodCalls.add(MethodCall.of("find").with("beanType", beanType, "id", id)); 521 WhenBeanReturn match = whenFind.findMatchById(beanType, id); 522 if (match != null) { 523 return (T)match.val(); 524 } 525 return find.find(beanType, id, null); 526 } 527 528 @Override 529 public <T> T find(Class<T> beanType, Object id, Transaction transaction) { 530 methodCalls.add(MethodCall.of("find").with("beanType", beanType, "id", id, "transaction", transaction)); 531 WhenBeanReturn match = whenFind.findMatchById(beanType, id); 532 if (match != null) { 533 return (T)match.val(); 534 } 535 return find.find(beanType, id, transaction); 536 } 537 538 @Override 539 public <T> T findUnique(Query<T> query, Transaction transaction) { 540 methodCalls.add(MethodCall.of("findUnique").with("query", query, "transaction", transaction)); 541 WhenBeanReturn match = whenFind.findMatchByUnique(((SpiQuery)query).getBeanType()); 542 if (match != null) { 543 return (T)match.val(); 544 } 545 return find.findUnique(query, transaction); 546 } 547 548 @Override 549 public <T> int findRowCount(Query<T> query, Transaction transaction) { 550 methodCalls.add(MethodCall.of("findRowCount").with("query", query, "transaction", transaction)); 551 return find.findRowCount(query, transaction); 552 } 553 554 @Override 555 public <T> List<Object> findIds(Query<T> query, Transaction transaction) { 556 methodCalls.add(MethodCall.of("findIds").with("query", query, "transaction", transaction)); 557 return find.findIds(query, transaction); 558 } 559 560 @Override 561 public <T> void findEach(Query<T> query, QueryEachConsumer<T> consumer, Transaction transaction) { 562 methodCalls.add(MethodCall.of("findEach").with("query", query, "consumer", consumer, "transaction", transaction)); 563 find.findEach(query, consumer, transaction); 564 } 565 566 @Override 567 public <T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction transaction) { 568 methodCalls.add(MethodCall.of("findEachWhile").with("query", query, "consumer", consumer, "transaction", transaction)); 569 find.findEachWhile(query, consumer, transaction); 570 } 571 572 @Override 573 public <T> List<T> findList(Query<T> query, Transaction transaction) { 574 methodCalls.add(MethodCall.of("findList").with("query", query, "transaction", transaction)); 575 return find.findList(query, transaction); 576 } 577 578 @Override 579 public <T> FutureRowCount<T> findFutureRowCount(Query<T> query, Transaction transaction) { 580 methodCalls.add(MethodCall.of("findFutureRowCount").with("query", query, "transaction", transaction)); 581 return find.findFutureRowCount(query, transaction); 582 } 583 584 @Override 585 public <T> FutureIds<T> findFutureIds(Query<T> query, Transaction transaction) { 586 methodCalls.add(MethodCall.of("findFutureIds").with("query", query, "transaction", transaction)); 587 return find.findFutureIds(query, transaction); 588 } 589 590 @Override 591 public <T> FutureList<T> findFutureList(Query<T> query, Transaction transaction) { 592 methodCalls.add(MethodCall.of("findFutureList").with("query", query, "transaction", transaction)); 593 return find.findFutureList(query, transaction); 594 } 595 596 @Override 597 public <T> PagedList<T> findPagedList(Query<T> query, Transaction transaction) { 598 methodCalls.add(MethodCall.of("findPagedList").with("query", query, "transaction", transaction)); 599 return find.findPagedList(query, transaction); 600 } 601 602 @Override 603 public <T> Set<T> findSet(Query<T> query, Transaction transaction) { 604 methodCalls.add(MethodCall.of("findSet").with("query", query, "transaction", transaction)); 605 return find.findSet(query, transaction); 606 } 607 608 @Override 609 public <T> Map<?, T> findMap(Query<T> query, Transaction transaction) { 610 methodCalls.add(MethodCall.of("findMap").with("query", query, "transaction", transaction)); 611 return find.findMap(query, transaction); 612 } 613 614 @Override 615 public <T> List<Version<T>> findVersions(Query<T> query, Transaction transaction) { 616 methodCalls.add(MethodCall.of("findVersions").with("query", query, "transaction", transaction)); 617 return find.findVersions(query, transaction); 618 } 619 620 // -- find SqlQuery ------------------------ 621 622 @Override 623 public List<SqlRow> findList(SqlQuery sqlQuery, Transaction transaction) { 624 methodCalls.add(MethodCall.of("findList").with("sqlQuery", sqlQuery, "transaction", transaction)); 625 return findSqlQuery.findList(sqlQuery, transaction); 626 } 627 628 @Override 629 public SqlRow findUnique(SqlQuery sqlQuery, Transaction transaction) { 630 methodCalls.add(MethodCall.of("findUnique").with("sqlQuery", sqlQuery, "transaction", transaction)); 631 return findSqlQuery.findUnique(sqlQuery, transaction); 632 } 633 634 @Override 635 public void findEach(SqlQuery sqlQuery, QueryEachConsumer<SqlRow> consumer, Transaction transaction) { 636 methodCalls.add(MethodCall.of("findEach").with("sqlQuery", sqlQuery, "consumer", consumer, "transaction", transaction)); 637 findSqlQuery.findEach(sqlQuery, consumer, transaction); 638 } 639 640 @Override 641 public void findEachWhile(SqlQuery sqlQuery, QueryEachWhileConsumer<SqlRow> consumer, Transaction transaction) { 642 methodCalls.add(MethodCall.of("findEachWhile").with("sqlQuery", sqlQuery, "consumer", consumer, "transaction", transaction)); 643 findSqlQuery.findEachWhile(sqlQuery, consumer, transaction); 644 } 645 646 // -- save ------------------------ 647 648 @Override 649 public Object nextId(Class<?> beanType) { 650 methodCalls.add(MethodCall.of("nextId").with("beanType", beanType)); 651 return !persistSaves ? 0 : save.nextId(beanType); 652 } 653 654 655 @Override 656 public void save(Object bean) throws OptimisticLockException { 657 methodCalls.add(MethodCall.of(SAVE).with("bean", bean)); 658 capturedBeans.addSaved(bean); 659 if (persistSaves) { 660 save.save(bean, null); 661 } 662 } 663 664 @Override 665 public int saveAll(Collection<?> beans) throws OptimisticLockException { 666 methodCalls.add(MethodCall.of(SAVE_ALL).with("beans", beans)); 667 capturedBeans.addSavedAll(beans); 668 return !persistSaves ? 0 : save.saveAll(beans, null); 669 } 670 671 672 @Override 673 public void save(Object bean, Transaction transaction) throws OptimisticLockException { 674 methodCalls.add(MethodCall.of(SAVE).with("bean", bean, "transaction", transaction)); 675 capturedBeans.addSaved(bean); 676 if (persistSaves) { 677 save.save(bean, transaction); 678 } 679 } 680 681 @Override 682 public int saveAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException { 683 methodCalls.add(MethodCall.of(SAVE_ALL).with("beans", beans, "transaction", transaction)); 684 capturedBeans.addSavedAll(beans); 685 return !persistSaves ? 0 : save.saveAll(beans, transaction); 686 } 687 688 @Override 689 public <T> UpdateQuery<T> update(Class<T> beanType) { 690 methodCalls.add(MethodCall.of(UPDATE).with("beanType", beanType)); 691 return delegate.update(beanType); 692 } 693 694 @Override 695 public <T> int update(Query<T> query, Transaction transaction) { 696 methodCalls.add(MethodCall.of(UPDATE).with("query", query).with("transaction", transaction)); 697 if (persistUpdates) { 698 return delegate.update(query, transaction); 699 } 700 return 0; 701 } 702 703 @Override 704 public void update(Object bean) throws OptimisticLockException { 705 methodCalls.add(MethodCall.of(UPDATE).with("bean", bean)); 706 capturedBeans.addUpdated(bean); 707 if (persistUpdates) { 708 save.update(bean, null); 709 } 710 } 711 712 @Override 713 public void update(Object bean, Transaction transaction) throws OptimisticLockException { 714 methodCalls.add(MethodCall.of(UPDATE).with("bean", bean, "transaction", transaction)); 715 capturedBeans.addUpdated(bean); 716 if (persistUpdates) { 717 save.update(bean, transaction); 718 } 719 } 720 721 @Override 722 public void update(Object bean, Transaction transaction, boolean deleteMissingChildren) throws OptimisticLockException { 723 methodCalls.add(MethodCall.of(UPDATE).with("bean", bean, "transaction", transaction, "deleteMissingChildren", deleteMissingChildren)); 724 capturedBeans.addUpdated(bean); 725 if (persistUpdates) { 726 save.update(bean, transaction, deleteMissingChildren); 727 } 728 } 729 730 @Override 731 public void updateAll(Collection<?> beans) throws OptimisticLockException { 732 methodCalls.add(MethodCall.of(UPDATE_ALL).with("beans", beans)); 733 capturedBeans.addUpdatedAll(beans); 734 if (persistUpdates) { 735 save.updateAll(beans, null); 736 } 737 } 738 739 @Override 740 public void updateAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException { 741 methodCalls.add(MethodCall.of(UPDATE_ALL).with("beans", beans, "transaction", transaction)); 742 capturedBeans.addUpdatedAll(beans); 743 if (persistUpdates) { 744 save.updateAll(beans, transaction); 745 } 746 } 747 748 @Override 749 public void insert(Object bean) { 750 methodCalls.add(MethodCall.of(INSERT).with("bean", bean)); 751 capturedBeans.addInserted(bean); 752 if (persistInserts) { 753 save.insert(bean, null); 754 } 755 } 756 757 @Override 758 public void insert(Object bean, Transaction transaction) { 759 methodCalls.add(MethodCall.of(INSERT).with("bean", bean, "transaction", transaction)); 760 capturedBeans.addInserted(bean); 761 if (persistInserts) { 762 save.insert(bean, transaction); 763 } 764 } 765 766 @Override 767 public void insertAll(Collection<?> beans) { 768 methodCalls.add(MethodCall.of(INSERT_ALL).with("beans", beans)); 769 capturedBeans.addInsertedAll(beans); 770 if (persistInserts) { 771 save.insertAll(beans, null); 772 } 773 } 774 775 @Override 776 public void insertAll(Collection<?> beans, Transaction transaction) { 777 methodCalls.add(MethodCall.of(INSERT_ALL).with("beans", beans, "transaction", transaction)); 778 capturedBeans.addInsertedAll(beans); 779 if (persistInserts) { 780 save.insertAll(beans, transaction); 781 } 782 } 783 784 785 // -- delete ------------------------ 786 787 788 @Override 789 public boolean delete(Object bean) throws OptimisticLockException { 790 methodCalls.add(MethodCall.of("bean").with("bean", bean)); 791 capturedBeans.addDeleted(bean); 792 if (persistDeletes) { 793 return delete.delete(bean, null); 794 } 795 return true; 796 } 797 798 @Override 799 public int deleteAll(Collection<?> beans) throws OptimisticLockException { 800 methodCalls.add(MethodCall.of(DELETE_ALL).with("beans", beans)); 801 capturedBeans.addDeletedAll(beans); 802 return !persistDeletes ? 0 : delete.deleteAll(beans); 803 } 804 805 @Override 806 public int deleteAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException { 807 methodCalls.add(MethodCall.of(DELETE_ALL).with("beans", beans)); 808 capturedBeans.addDeletedAll(beans); 809 return !persistDeletes ? 0 : delete.deleteAll(beans, transaction); 810 } 811 812 @Override 813 public boolean deletePermanent(Object bean) throws OptimisticLockException { 814 methodCalls.add(MethodCall.of(DELETE_PERMANENT).with("bean", bean)); 815 capturedBeans.addDeletePermanent(bean); 816 return !persistDeletes ? true : delete.deletePermanent(bean); 817 } 818 819 @Override 820 public boolean deletePermanent(Object bean, Transaction transaction) throws OptimisticLockException { 821 methodCalls.add(MethodCall.of(DELETE_PERMANENT).with("bean", bean)); 822 capturedBeans.addDeletePermanent(bean); 823 return !persistDeletes ? true : delete.deletePermanent(bean, transaction); 824 } 825 826 @Override 827 public int deleteAllPermanent(Collection<?> beans) throws OptimisticLockException { 828 methodCalls.add(MethodCall.of(DELETE_ALL_PERMANENT).with("beans", beans)); 829 capturedBeans.addDeletedAllPermanent(beans); 830 return !persistDeletes ? 0 : delete.deleteAllPermanent(beans); 831 } 832 833 @Override 834 public int deleteAllPermanent(Collection<?> beans, Transaction transaction) throws OptimisticLockException { 835 methodCalls.add(MethodCall.of(DELETE_ALL_PERMANENT).with("beans", beans)); 836 capturedBeans.addDeletedAllPermanent(beans); 837 return !persistDeletes ? 0 : delete.deleteAllPermanent(beans, transaction); 838 } 839 840 @Override 841 public <T> int delete(Query<T> query, Transaction transaction) { 842 methodCalls.add(MethodCall.of(DELETE).with("query", query)); 843 return !persistDeletes ? 0 : delete.delete(query, transaction); 844 } 845 846 @Override 847 public int delete(Class<?> beanType, Object id) { 848 MethodCall deleteById = MethodCall.of(DELETE).with("beanType", beanType, "id", id); 849 methodCalls.add(deleteById); 850 capturedBeans.addDeleted(deleteById); 851 return !persistDeletes ? 0 : delete.delete(beanType, id, null); 852 } 853 854 @Override 855 public int delete(Class<?> beanType, Object id, Transaction transaction) { 856 MethodCall deleteById = MethodCall.of(DELETE).with("beanType", beanType, "id", id, "transaction", transaction); 857 methodCalls.add(deleteById); 858 capturedBeans.addDeleted(deleteById); 859 return !persistDeletes ? 0 : delete.delete(beanType, id, transaction); 860 } 861 862 @Override 863 public int deletePermanent(Class<?> beanType, Object id) { 864 MethodCall deleteById = MethodCall.of(DELETE_PERMANENT).with("beanType", beanType, "id", id); 865 methodCalls.add(deleteById); 866 capturedBeans.addDeleted(deleteById); 867 return !persistDeletes ? 0 : delete.deletePermanent(beanType, id); 868 } 869 870 @Override 871 public int deletePermanent(Class<?> beanType, Object id, Transaction transaction) { 872 MethodCall deleteById = MethodCall.of(DELETE_PERMANENT).with("beanType", beanType, "id", id, "transaction", transaction); 873 methodCalls.add(deleteById); 874 capturedBeans.addDeleted(deleteById); 875 return !persistDeletes ? 0 : delete.deletePermanent(beanType, id, transaction); 876 } 877 878 @Override 879 public int deleteAll(Class<?> beanType, Collection<?> ids) { 880 MethodCall deleteByIds = MethodCall.of(DELETE_ALL).with("beanType", beanType, "ids", ids); 881 methodCalls.add(deleteByIds); 882 capturedBeans.addDeleted(deleteByIds); 883 if (persistDeletes) { 884 return delete.deleteAll(beanType, ids, null); 885 } 886 return 0; 887 } 888 889 @Override 890 public int deleteAll(Class<?> beanType, Collection<?> ids, Transaction transaction) { 891 MethodCall deleteByIds = MethodCall.of(DELETE_ALL).with("beanType", beanType, "ids", ids, "transaction", transaction); 892 methodCalls.add(deleteByIds); 893 capturedBeans.addDeleted(deleteByIds); 894 if (persistDeletes) { 895 return delete.deleteAll(beanType, ids, transaction); 896 } 897 return 0; 898 } 899 900 @Override 901 public int deleteAllPermanent(Class<?> beanType, Collection<?> ids) { 902 MethodCall deleteByIds = MethodCall.of(DELETE_ALL_PERMANENT).with("beanType", beanType, "ids", ids); 903 methodCalls.add(deleteByIds); 904 capturedBeans.addDeleted(deleteByIds); 905 if (persistDeletes) { 906 return delete.deleteAllPermanent(beanType, ids); 907 } 908 return 0; 909 } 910 911 @Override 912 public int deleteAllPermanent(Class<?> beanType, Collection<?> ids, Transaction transaction) { 913 MethodCall deleteByIds = MethodCall.of(DELETE_ALL_PERMANENT).with("beanType", beanType, "ids", ids, "transaction", transaction); 914 methodCalls.add(deleteByIds); 915 capturedBeans.addDeleted(deleteByIds); 916 if (persistDeletes) { 917 return delete.deleteAllPermanent(beanType, ids, transaction); 918 } 919 return 0; 920 } 921 922 @Override 923 public boolean delete(Object bean, Transaction transaction) throws OptimisticLockException { 924 methodCalls.add(MethodCall.of(DELETE).with("bean", bean, "transaction", transaction)); 925 capturedBeans.addDeleted(bean); 926 if (persistDeletes) { 927 return delete.delete(bean, transaction); 928 } 929 return true; 930 } 931 932 933 // -- publish and restore --------------------------- 934 935 936 @Override 937 public <T> T publish(Class<T> beanType, Object id, Transaction transaction) { 938 methodCalls.add(MethodCall.of(PUBLISH).with("beanType", beanType).with("id", id)); 939 return !persistPublish ? null : publish.publish(beanType, id, transaction); 940 } 941 942 @Override 943 public <T> T publish(Class<T> beanType, Object id) { 944 methodCalls.add(MethodCall.of(PUBLISH).with("beanType", beanType).with("id", id)); 945 return !persistPublish ? null : publish.publish(beanType, id); 946 } 947 948 @Override 949 public <T> List<T> publish(Query<T> query, Transaction transaction) { 950 methodCalls.add(MethodCall.of(PUBLISH).with("query", query)); 951 return !persistPublish ? null : publish.publish(query, transaction); 952 } 953 954 @Override 955 public <T> List<T> publish(Query<T> query) { 956 methodCalls.add(MethodCall.of(PUBLISH).with("query", query)); 957 return !persistPublish ? null : publish.publish(query); 958 } 959 960 @Override 961 public <T> T draftRestore(Class<T> beanType, Object id, Transaction transaction) { 962 methodCalls.add(MethodCall.of(DRAFT_RESTORE).with("beanType", beanType).with("id", id)); 963 return !persistPublish ? null : publish.draftRestore(beanType, id, transaction); 964 } 965 966 @Override 967 public <T> T draftRestore(Class<T> beanType, Object id) { 968 methodCalls.add(MethodCall.of(DRAFT_RESTORE).with("beanType", beanType).with("id", id)); 969 return !persistPublish ? null : publish.draftRestore(beanType, id); 970 } 971 972 @Override 973 public <T> List<T> draftRestore(Query<T> query, Transaction transaction) { 974 methodCalls.add(MethodCall.of(DRAFT_RESTORE).with("query", query)); 975 return !persistPublish ? null : publish.draftRestore(query, transaction); 976 } 977 978 @Override 979 public <T> List<T> draftRestore(Query<T> query) { 980 methodCalls.add(MethodCall.of(DRAFT_RESTORE).with("query", query)); 981 return !persistPublish ? null : publish.draftRestore(query); 982 } 983 984 985 // -- bulkUpdate bulkUpdates ------------------------ 986 987 988 @Override 989 public int execute(SqlUpdate sqlUpdate) { 990 methodCalls.add(MethodCall.of("bulkUpdate").with("sqlUpdate", sqlUpdate)); 991 return !persistBulkUpdates ? 0 : bulkUpdate.execute(sqlUpdate); 992 } 993 994 @Override 995 public int execute(Update<?> update) { 996 methodCalls.add(MethodCall.of("bulkUpdate").with("update", update)); 997 return !persistBulkUpdates ? 0 : bulkUpdate.execute(update); 998 } 999 1000 @Override 1001 public int execute(Update<?> update, Transaction transaction) { 1002 methodCalls.add(MethodCall.of("bulkUpdate").with("update", update, "transaction", transaction)); 1003 return !persistBulkUpdates ? 0 : bulkUpdate.execute(update, transaction); 1004 } 1005 1006 @Override 1007 public int execute(CallableSql callableSql) { 1008 methodCalls.add(MethodCall.of("bulkUpdate").with("callableSql", callableSql)); 1009 return !persistBulkUpdates ? 0 : bulkUpdate.execute(callableSql); 1010 } 1011 1012 @Override 1013 public int execute(SqlUpdate sqlUpdate, Transaction transaction) { 1014 methodCalls.add(MethodCall.of("bulkUpdate").with("sqlUpdate", sqlUpdate, "transaction", transaction)); 1015 return !persistBulkUpdates ? 0 : bulkUpdate.execute(sqlUpdate, transaction); 1016 } 1017 1018 @Override 1019 public int execute(CallableSql callableSql, Transaction transaction) { 1020 methodCalls.add(MethodCall.of("bulkUpdate").with("callableSql", callableSql, "transaction", transaction)); 1021 return !persistBulkUpdates ? 0 : bulkUpdate.execute(callableSql, transaction); 1022 } 1023 1024 @Override 1025 public void externalModification(String tableName, boolean inserted, boolean updated, boolean deleted) { 1026 1027 methodCalls.add(MethodCall.of("externalModification") 1028 .with("tableName", tableName) 1029 .with("inserted", inserted, "updated", updated, "deleted", deleted)); 1030 1031 if (persistBulkUpdates) { 1032 bulkUpdate.externalModification(tableName, inserted, updated, deleted); 1033 } 1034 } 1035 1036}