001package io.ebean.config;
002
003import com.fasterxml.jackson.core.JsonFactory;
004import io.avaje.config.Config;
005import io.ebean.DatabaseFactory;
006import io.ebean.PersistenceContextScope;
007import io.ebean.Query;
008import io.ebean.Transaction;
009import io.ebean.annotation.Encrypted;
010import io.ebean.annotation.PersistBatch;
011import io.ebean.annotation.Platform;
012import io.ebean.cache.ServerCachePlugin;
013import io.ebean.config.dbplatform.DatabasePlatform;
014import io.ebean.config.dbplatform.DbEncrypt;
015import io.ebean.config.dbplatform.DbType;
016import io.ebean.config.dbplatform.IdType;
017import io.ebean.datasource.DataSourceConfig;
018import io.ebean.event.BeanFindController;
019import io.ebean.event.BeanPersistController;
020import io.ebean.event.BeanPersistListener;
021import io.ebean.event.BeanPostConstructListener;
022import io.ebean.event.BeanPostLoad;
023import io.ebean.event.BeanQueryAdapter;
024import io.ebean.event.BulkTableEventListener;
025import io.ebean.event.ServerConfigStartup;
026import io.ebean.event.changelog.ChangeLogListener;
027import io.ebean.event.changelog.ChangeLogPrepare;
028import io.ebean.event.changelog.ChangeLogRegister;
029import io.ebean.event.readaudit.ReadAuditLogger;
030import io.ebean.event.readaudit.ReadAuditPrepare;
031import io.ebean.migration.MigrationRunner;
032import io.ebean.util.StringHelper;
033
034import javax.persistence.EnumType;
035import javax.sql.DataSource;
036import java.time.Clock;
037import java.util.ArrayList;
038import java.util.Collections;
039import java.util.HashMap;
040import java.util.Iterator;
041import java.util.List;
042import java.util.Map;
043import java.util.Properties;
044import java.util.ServiceLoader;
045
046/**
047 * The configuration used for creating a Database.
048 * <p>
049 * Used to programmatically construct an Database and optionally register it
050 * with the DB singleton.
051 * </p>
052 * <p>
053 * If you just use DB thout this programmatic configuration Ebean will read
054 * the application.properties file and take the configuration from there. This usually
055 * includes searching the class path and automatically registering any entity
056 * classes and listeners etc.
057 * </p>
058 * <pre>{@code
059 *
060 * DatabaseConfig config = new DatabaseConfig();
061 *
062 * // read the ebean.properties and load
063 * // those settings into this DatabaseConfig object
064 * config.loadFromProperties();
065 *
066 * // explicitly register the entity beans to avoid classpath scanning
067 * config.addClass(Customer.class);
068 * config.addClass(User.class);
069 *
070 * Database db = DatabaseFactory.create(config);
071 *
072 * }</pre>
073 *
074 * <p>
075 * Note that DatabaseConfigProvider provides a standard Java ServiceLoader mechanism that can
076 * be used to apply configuration to the DatabaseConfig.
077 * </p>
078 *
079 * @author emcgreal
080 * @author rbygrave
081 * @see DatabaseFactory
082 */
083public class DatabaseConfig {
084
085
086  /**
087   * The Database name.
088   */
089  private String name = "db";
090
091  /**
092   * Typically configuration type objects that are passed by this DatabaseConfig
093   * to plugins. For example - IgniteConfiguration passed to Ignite plugin.
094   */
095  private final Map<String, Object> serviceObject = new HashMap<>();
096
097  private ContainerConfig containerConfig;
098
099  /**
100   * The underlying properties that were used during configuration.
101   */
102  private Properties properties;
103
104  /**
105   * The resource directory.
106   */
107  private String resourceDirectory;
108
109  /**
110   * Set to true to register this Database with the DB singleton.
111   */
112  private boolean register = true;
113
114  /**
115   * Set to true if this is the default/primary database.
116   */
117  private boolean defaultServer = true;
118
119  /**
120   * Set this to true to disable class path search.
121   */
122  private boolean disableClasspathSearch;
123
124  private TenantMode tenantMode = TenantMode.NONE;
125
126  private String tenantPartitionColumn = "tenant_id";
127
128  private CurrentTenantProvider currentTenantProvider;
129
130  private TenantDataSourceProvider tenantDataSourceProvider;
131
132  private TenantSchemaProvider tenantSchemaProvider;
133
134  private TenantCatalogProvider tenantCatalogProvider;
135
136  /**
137   * When true will load entity classes via ModuleInfoLoader.
138   * <p>
139   * NB: ModuleInfoLoader implementations are generated by querybean generator.
140   * Having this on and registering entity classes means we don't need to manually
141   * write that code or use classpath scanning to find entity classes.
142   */
143  private boolean loadModuleInfo = true;
144
145  /**
146   * List of interesting classes such as entities, embedded, ScalarTypes,
147   * Listeners, Finders, Controllers etc.
148   */
149  private List<Class<?>> classes = new ArrayList<>();
150
151  /**
152   * The packages that are searched for interesting classes. Only used when
153   * classes is empty/not explicitly specified.
154   */
155  private List<String> packages = new ArrayList<>();
156
157  /**
158   * Configuration for the ElasticSearch integration.
159   */
160  private DocStoreConfig docStoreConfig = new DocStoreConfig();
161
162  /**
163   * Set to true when the Database only uses Document store.
164   */
165  private boolean docStoreOnly;
166
167  /**
168   * This is used to populate @WhoCreated, @WhoModified and
169   * support other audit features (who executed a query etc).
170   */
171  private CurrentUserProvider currentUserProvider;
172
173  /**
174   * Config controlling the AutoTune behaviour.
175   */
176  private AutoTuneConfig autoTuneConfig = new AutoTuneConfig();
177
178  /**
179   * The JSON format used for DateTime types. Default to millis.
180   */
181  private JsonConfig.DateTime jsonDateTime = JsonConfig.DateTime.ISO8601;
182
183  /**
184   * The JSON format used for Date types. Default to millis.
185   */
186  private JsonConfig.Date jsonDate = JsonConfig.Date.ISO8601;
187
188  /**
189   * For writing JSON specify if null values or empty collections should be excluded.
190   * By default all values are included.
191   */
192  private JsonConfig.Include jsonInclude = JsonConfig.Include.ALL;
193
194  /**
195   * The database platform name. Used to imply a DatabasePlatform to use.
196   */
197  private String databasePlatformName;
198
199  /**
200   * The database platform.
201   */
202  private DatabasePlatform databasePlatform;
203
204  /**
205   * JDBC fetchSize hint when using findList.  Defaults to 0 leaving it up to the JDBC driver.
206   */
207  private int jdbcFetchSizeFindList;
208
209  /**
210   * JDBC fetchSize hint when using findEach/findEachWhile.  Defaults to 100. Note that this does
211   * not apply to MySql as that gets special treatment (forward only etc).
212   */
213  private int jdbcFetchSizeFindEach = 100;
214
215  /**
216   * Suffix appended to the base table to derive the view that contains the union
217   * of the base table and the history table in order to support asOf queries.
218   */
219  private String asOfViewSuffix = "_with_history";
220
221  /**
222   * Column used to support history and 'As of' queries. This column is a timestamp range
223   * or equivalent.
224   */
225  private String asOfSysPeriod = "sys_period";
226
227  /**
228   * Suffix appended to the base table to derive the view that contains the union
229   * of the base table and the history table in order to support asOf queries.
230   */
231  private String historyTableSuffix = "_history";
232
233  /**
234   * Use for transaction scoped batch mode.
235   */
236  private PersistBatch persistBatch = PersistBatch.NONE;
237
238  /**
239   * Use for cascade persist JDBC batch mode. INHERIT means use the platform default
240   * which is ALL except for SQL Server where it is NONE (as getGeneratedKeys isn't
241   * supported on SQL Server with JDBC batch).
242   */
243  private PersistBatch persistBatchOnCascade = PersistBatch.INHERIT;
244
245  private int persistBatchSize = 20;
246
247  private EnumType defaultEnumType = EnumType.ORDINAL;
248
249  private boolean disableLazyLoading;
250
251  /**
252   * The default batch size for lazy loading
253   */
254  private int lazyLoadBatchSize = 10;
255
256  /**
257   * The default batch size for 'query joins'.
258   */
259  private int queryBatchSize = 100;
260
261  private boolean eagerFetchLobs;
262
263  /**
264   * Timezone used to get/set Timestamp values via JDBC.
265   */
266  private String dataTimeZone;
267
268  private boolean ddlGenerate;
269
270  private boolean ddlRun;
271
272  private boolean ddlExtra = true;
273
274  private boolean ddlCreateOnly;
275
276  private String ddlInitSql;
277
278  private String ddlSeedSql;
279
280  /**
281   * When true L2 bean cache use is skipped after a write has occurred on a transaction.
282   */
283  private boolean skipCacheAfterWrite = true;
284
285  private boolean useJtaTransactionManager;
286
287  /**
288   * The external transaction manager (like Spring).
289   */
290  private ExternalTransactionManager externalTransactionManager;
291
292  /**
293   * The data source (if programmatically provided).
294   */
295  private DataSource dataSource;
296
297  /**
298   * The read only data source (can be null).
299   */
300  private DataSource readOnlyDataSource;
301
302  /**
303   * The data source config.
304   */
305  private DataSourceConfig dataSourceConfig = new DataSourceConfig();
306
307  /**
308   * When true create a read only DataSource using readOnlyDataSourceConfig defaulting values from dataSourceConfig.
309   * I believe this will default to true in some future release (as it has a nice performance benefit).
310   * <p>
311   * autoReadOnlyDataSource is an unfortunate name for this config option but I haven't come up with a better one.
312   */
313  private boolean autoReadOnlyDataSource;
314
315  /**
316   * Optional configuration for a read only data source.
317   */
318  private DataSourceConfig readOnlyDataSourceConfig = new DataSourceConfig();
319
320  /**
321   * Optional - the database schema that should be used to own the tables etc.
322   */
323  private String dbSchema;
324
325  /**
326   * The db migration config (migration resource path etc).
327   */
328  private DbMigrationConfig migrationConfig = new DbMigrationConfig();
329
330  /**
331   * The ClassLoadConfig used to detect Joda, Java8, Jackson etc and create plugin instances given a className.
332   */
333  private ClassLoadConfig classLoadConfig = new ClassLoadConfig();
334
335  /**
336   * The data source JNDI name if using a JNDI DataSource.
337   */
338  private String dataSourceJndiName;
339
340  /**
341   * The naming convention.
342   */
343  private NamingConvention namingConvention = new UnderscoreNamingConvention();
344
345  /**
346   * Behaviour of updates in JDBC batch to by default include all properties.
347   */
348  private boolean updateAllPropertiesInBatch;
349
350  /**
351   * Database platform configuration.
352   */
353  private PlatformConfig platformConfig = new PlatformConfig();
354
355  /**
356   * The UUID version to use.
357   */
358  private UuidVersion uuidVersion = UuidVersion.VERSION4;
359
360  /**
361   * The UUID state file (for Version 1 UUIDs). By default, the file is created in
362   * ${HOME}/.ebean/${servername}-uuid.state
363   */
364  private String uuidStateFile;
365
366  /**
367   * The clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
368   */
369  private Clock clock = Clock.systemUTC();
370
371  private List<IdGenerator> idGenerators = new ArrayList<>();
372  private List<BeanFindController> findControllers = new ArrayList<>();
373  private List<BeanPersistController> persistControllers = new ArrayList<>();
374  private List<BeanPostLoad> postLoaders = new ArrayList<>();
375  private List<BeanPostConstructListener> postConstructListeners = new ArrayList<>();
376  private List<BeanPersistListener> persistListeners = new ArrayList<>();
377  private List<BeanQueryAdapter> queryAdapters = new ArrayList<>();
378  private List<BulkTableEventListener> bulkTableEventListeners = new ArrayList<>();
379  private List<ServerConfigStartup> configStartupListeners = new ArrayList<>();
380
381  /**
382   * By default inserts are included in the change log.
383   */
384  private boolean changeLogIncludeInserts = true;
385
386  private ChangeLogPrepare changeLogPrepare;
387
388  private ChangeLogListener changeLogListener;
389
390  private ChangeLogRegister changeLogRegister;
391
392  private boolean changeLogAsync = true;
393
394  private ReadAuditLogger readAuditLogger;
395
396  private ReadAuditPrepare readAuditPrepare;
397
398  private EncryptKeyManager encryptKeyManager;
399
400  private EncryptDeployManager encryptDeployManager;
401
402  private Encryptor encryptor;
403
404  private boolean dbOffline;
405
406  private DbEncrypt dbEncrypt;
407
408  private ServerCachePlugin serverCachePlugin;
409
410  /**
411   * The default PersistenceContextScope used if one is not explicitly set on a query.
412   */
413  private PersistenceContextScope persistenceContextScope = PersistenceContextScope.TRANSACTION;
414
415  private JsonFactory jsonFactory;
416
417  private boolean localTimeWithNanos;
418
419  private boolean durationWithNanos;
420
421  private int maxCallStack = 5;
422
423  private boolean transactionRollbackOnChecked = true;
424
425  // configuration for the background executor service (thread pool)
426
427  private int backgroundExecutorSchedulePoolSize = 1;
428  private int backgroundExecutorShutdownSecs = 30;
429
430  // defaults for the L2 bean caching
431
432  private int cacheMaxSize = 10000;
433  private int cacheMaxIdleTime = 600;
434  private int cacheMaxTimeToLive = 60 * 60 * 6;
435
436  // defaults for the L2 query caching
437
438  private int queryCacheMaxSize = 1000;
439  private int queryCacheMaxIdleTime = 600;
440  private int queryCacheMaxTimeToLive = 60 * 60 * 6;
441  private Object objectMapper;
442
443  /**
444   * Set to true if you want eq("someProperty", null) to generate 1=1 rather than "is null" sql expression.
445   */
446  private boolean expressionEqualsWithNullAsNoop;
447
448  /**
449   * Set to true to use native ILIKE expression (if support by database platform / like Postgres).
450   */
451  private boolean expressionNativeIlike;
452
453  private String jodaLocalTimeMode;
454
455  /**
456   * Time to live for query plans - defaults to 5 minutes.
457   */
458  private int queryPlanTTLSeconds = 60 * 5;
459
460  /**
461   * Set to true to globally disable L2 caching (typically for performance testing).
462   */
463  private boolean disableL2Cache;
464
465  private String enabledL2Regions;
466
467  /**
468   * Set to true to effectively disable L2 cache plugins.
469   */
470  private boolean localOnlyL2Cache;
471
472  /**
473   * Should the javax.validation.constraints.NotNull enforce a notNull column in DB.
474   * If set to false, use io.ebean.annotation.NotNull or Column(nullable=true).
475   */
476  private boolean useJavaxValidationNotNull = true;
477
478  /**
479   * Generally we want to perform L2 cache notification in the background and not impact
480   * the performance of executing transactions.
481   */
482  private boolean notifyL2CacheInForeground;
483
484  /**
485   * Set to true to support query plan capture.
486   */
487  private boolean collectQueryPlans;
488
489  /**
490   * The default threshold in micros for collecting query plans.
491   */
492  private long collectQueryPlanThresholdMicros = Long.MAX_VALUE;
493
494  /**
495   * The time in millis used to determine when a query is alerted for being slow.
496   */
497  private long slowQueryMillis;
498
499  /**
500   * The listener for processing slow query events.
501   */
502  private SlowQueryListener slowQueryListener;
503
504  private ProfilingConfig profilingConfig = new ProfilingConfig();
505
506  /**
507   * Controls the default order by id setting of queries. See {@link Query#orderById(boolean)}
508   */
509  private boolean defaultOrderById;
510
511  /**
512   * The mappingLocations for searching xml mapping.
513   */
514  private List<String> mappingLocations = new ArrayList<>();
515
516  /**
517   * When true we do not need explicit GeneratedValue mapping.
518   */
519  private boolean idGeneratorAutomatic = true;
520
521  private boolean dumpMetricsOnShutdown;
522
523  private String dumpMetricsOptions;
524
525  /**
526   * Construct a Database Configuration for programmatically creating an Database.
527   */
528  public DatabaseConfig() {
529  }
530
531  /**
532   * Get the clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
533   */
534  public Clock getClock() {
535    return clock;
536  }
537
538  /**
539   * Set the clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
540   */
541  public void setClock(final Clock clock) {
542    this.clock = clock;
543  }
544
545  /**
546   * Return the slow query time in millis.
547   */
548  public long getSlowQueryMillis() {
549    return slowQueryMillis;
550  }
551
552  /**
553   * Set the slow query time in millis.
554   */
555  public void setSlowQueryMillis(long slowQueryMillis) {
556    this.slowQueryMillis = slowQueryMillis;
557  }
558
559  /**
560   * Return the slow query event listener.
561   */
562  public SlowQueryListener getSlowQueryListener() {
563    return slowQueryListener;
564  }
565
566  /**
567   * Set the slow query event listener.
568   */
569  public void setSlowQueryListener(SlowQueryListener slowQueryListener) {
570    this.slowQueryListener = slowQueryListener;
571  }
572
573
574  /**
575   * Deprecated - look to have explicit order by. Sets the default orderById setting for queries.
576   */
577  @Deprecated
578  public void setDefaultOrderById(boolean defaultOrderById) {
579    this.defaultOrderById = defaultOrderById;
580  }
581
582  /**
583   * Returns the default orderById setting for queries.
584   */
585  public boolean isDefaultOrderById() {
586    return defaultOrderById;
587  }
588
589  /**
590   * Put a service object into configuration such that it can be passed to a plugin.
591   * <p>
592   * For example, put IgniteConfiguration in to be passed to the Ignite plugin.
593   */
594  public void putServiceObject(String key, Object configObject) {
595    serviceObject.put(key, configObject);
596  }
597
598  /**
599   * Return the service object given the key.
600   */
601  public Object getServiceObject(String key) {
602    return serviceObject.get(key);
603  }
604
605  /**
606   * Put a service object into configuration such that it can be passed to a plugin.
607   *
608   * <pre>{@code
609   *
610   *   JedisPool jedisPool = ..
611   *
612   *   config.putServiceObject(jedisPool);
613   *
614   * }</pre>
615   */
616  public void putServiceObject(Object configObject) {
617    String key = serviceObjectKey(configObject);
618    serviceObject.put(key, configObject);
619  }
620
621  private String serviceObjectKey(Object configObject) {
622    return serviceObjectKey(configObject.getClass());
623  }
624
625  private String serviceObjectKey(Class<?> cls) {
626    String simpleName = cls.getSimpleName();
627    return Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
628  }
629
630  /**
631   * Used by plugins to obtain service objects.
632   *
633   * <pre>{@code
634   *
635   *   JedisPool jedisPool = config.getServiceObject(JedisPool.class);
636   *
637   * }</pre>
638   *
639   * @param cls The type of the service object to obtain
640   * @return The service object given the class type
641   */
642  @SuppressWarnings("unchecked")
643  public <P> P getServiceObject(Class<P> cls) {
644    return (P) serviceObject.get(serviceObjectKey(cls));
645  }
646
647  /**
648   * Return the Jackson JsonFactory to use.
649   * <p>
650   * If not set a default implementation will be used.
651   */
652  public JsonFactory getJsonFactory() {
653    return jsonFactory;
654  }
655
656  /**
657   * Set the Jackson JsonFactory to use.
658   * <p>
659   * If not set a default implementation will be used.
660   */
661  public void setJsonFactory(JsonFactory jsonFactory) {
662    this.jsonFactory = jsonFactory;
663  }
664
665  /**
666   * Return the JSON format used for DateTime types.
667   */
668  public JsonConfig.DateTime getJsonDateTime() {
669    return jsonDateTime;
670  }
671
672  /**
673   * Set the JSON format to use for DateTime types.
674   */
675  public void setJsonDateTime(JsonConfig.DateTime jsonDateTime) {
676    this.jsonDateTime = jsonDateTime;
677  }
678
679  /**
680   * Return the JSON format used for Date types.
681   */
682  public JsonConfig.Date getJsonDate() {
683    return jsonDate;
684  }
685
686  /**
687   * Set the JSON format to use for Date types.
688   */
689  public void setJsonDate(JsonConfig.Date jsonDate) {
690    this.jsonDate = jsonDate;
691  }
692
693  /**
694   * Return the JSON include mode used when writing JSON.
695   */
696  public JsonConfig.Include getJsonInclude() {
697    return jsonInclude;
698  }
699
700  /**
701   * Set the JSON include mode used when writing JSON.
702   * <p>
703   * Set to NON_NULL or NON_EMPTY to suppress nulls or null and empty collections respectively.
704   */
705  public void setJsonInclude(JsonConfig.Include jsonInclude) {
706    this.jsonInclude = jsonInclude;
707  }
708
709  /**
710   * Return the name of the Database.
711   */
712  public String getName() {
713    return name;
714  }
715
716  /**
717   * Set the name of the Database.
718   */
719  public void setName(String name) {
720    this.name = name;
721  }
722
723  /**
724   * Return the container / clustering configuration.
725   * <p/>
726   * The container holds all the Database instances and provides clustering communication
727   * services to all the Database instances.
728   */
729  public ContainerConfig getContainerConfig() {
730    return containerConfig;
731  }
732
733  /**
734   * Set the container / clustering configuration.
735   * <p/>
736   * The container holds all the Database instances and provides clustering communication
737   * services to all the Database instances.
738   */
739  public void setContainerConfig(ContainerConfig containerConfig) {
740    this.containerConfig = containerConfig;
741  }
742
743  /**
744   * Return true if this server should be registered with the Ebean singleton
745   * when it is created.
746   * <p>
747   * By default this is set to true.
748   */
749  public boolean isRegister() {
750    return register;
751  }
752
753  /**
754   * Set to false if you do not want this server to be registered with the Ebean
755   * singleton when it is created.
756   * <p>
757   * By default this is set to true.
758   */
759  public void setRegister(boolean register) {
760    this.register = register;
761  }
762
763  /**
764   * Return true if this server should be registered as the "default" server
765   * with the Ebean singleton.
766   * <p>
767   * This is only used when {@link #setRegister(boolean)} is also true.
768   */
769  public boolean isDefaultServer() {
770    return defaultServer;
771  }
772
773  /**
774   * Set false if you do not want this Database to be registered as the "default" database
775   * with the DB singleton.
776   * <p>
777   * This is only used when {@link #setRegister(boolean)} is also true.
778   */
779  public void setDefaultServer(boolean defaultServer) {
780    this.defaultServer = defaultServer;
781  }
782
783  /**
784   * Return the CurrentUserProvider. This is used to populate @WhoCreated, @WhoModified and
785   * support other audit features (who executed a query etc).
786   */
787  public CurrentUserProvider getCurrentUserProvider() {
788    return currentUserProvider;
789  }
790
791  /**
792   * Set the CurrentUserProvider. This is used to populate @WhoCreated, @WhoModified and
793   * support other audit features (who executed a query etc).
794   */
795  public void setCurrentUserProvider(CurrentUserProvider currentUserProvider) {
796    this.currentUserProvider = currentUserProvider;
797  }
798
799  /**
800   * Return the tenancy mode used.
801   */
802  public TenantMode getTenantMode() {
803    return tenantMode;
804  }
805
806  /**
807   * Set the tenancy mode to use.
808   */
809  public void setTenantMode(TenantMode tenantMode) {
810    this.tenantMode = tenantMode;
811  }
812
813  /**
814   * Return the column name used for TenantMode.PARTITION.
815   */
816  public String getTenantPartitionColumn() {
817    return tenantPartitionColumn;
818  }
819
820  /**
821   * Set the column name used for TenantMode.PARTITION.
822   */
823  public void setTenantPartitionColumn(String tenantPartitionColumn) {
824    this.tenantPartitionColumn = tenantPartitionColumn;
825  }
826
827  /**
828   * Return the current tenant provider.
829   */
830  public CurrentTenantProvider getCurrentTenantProvider() {
831    return currentTenantProvider;
832  }
833
834  /**
835   * Set the current tenant provider.
836   */
837  public void setCurrentTenantProvider(CurrentTenantProvider currentTenantProvider) {
838    this.currentTenantProvider = currentTenantProvider;
839  }
840
841  /**
842   * Return the tenancy datasource provider.
843   */
844  public TenantDataSourceProvider getTenantDataSourceProvider() {
845    return tenantDataSourceProvider;
846  }
847
848  /**
849   * Set the tenancy datasource provider.
850   */
851  public void setTenantDataSourceProvider(TenantDataSourceProvider tenantDataSourceProvider) {
852    this.tenantDataSourceProvider = tenantDataSourceProvider;
853  }
854
855  /**
856   * Return the tenancy schema provider.
857   */
858  public TenantSchemaProvider getTenantSchemaProvider() {
859    return tenantSchemaProvider;
860  }
861
862  /**
863   * Set the tenancy schema provider.
864   */
865  public void setTenantSchemaProvider(TenantSchemaProvider tenantSchemaProvider) {
866    this.tenantSchemaProvider = tenantSchemaProvider;
867  }
868
869  /**
870   * Return the tenancy catalog provider.
871   */
872  public TenantCatalogProvider getTenantCatalogProvider() {
873    return tenantCatalogProvider;
874  }
875
876  /**
877   * Set the tenancy catalog provider.
878   */
879  public void setTenantCatalogProvider(TenantCatalogProvider tenantCatalogProvider) {
880    this.tenantCatalogProvider = tenantCatalogProvider;
881  }
882
883  /**
884   * Return the PersistBatch mode to use by default at the transaction level.
885   * <p>
886   * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into
887   * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends
888   * or the batch size is meet.
889   */
890  public PersistBatch getPersistBatch() {
891    return persistBatch;
892  }
893
894  /**
895   * Set the JDBC batch mode to use at the transaction level.
896   * <p>
897   * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into
898   * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends
899   * or the batch size is meet.
900   */
901  public void setPersistBatch(PersistBatch persistBatch) {
902    this.persistBatch = persistBatch;
903  }
904
905  /**
906   * Return the JDBC batch mode to use per save(), delete(), insert() or update() request.
907   * <p>
908   * This makes sense when a save() or delete() cascades and executes multiple child statements. The best case
909   * for this is when saving a master/parent bean this cascade inserts many detail/child beans.
910   * <p>
911   * This only takes effect when the persistBatch mode at the transaction level does not take effect.
912   */
913  public PersistBatch getPersistBatchOnCascade() {
914    return persistBatchOnCascade;
915  }
916
917  /**
918   * Set the JDBC batch mode to use per save(), delete(), insert() or update() request.
919   * <p>
920   * This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase
921   * for this is when saving a master/parent bean this cascade inserts many detail/child beans.
922   * <p>
923   * This only takes effect when the persistBatch mode at the transaction level does not take effect.
924   */
925  public void setPersistBatchOnCascade(PersistBatch persistBatchOnCascade) {
926    this.persistBatchOnCascade = persistBatchOnCascade;
927  }
928
929  /**
930   * Deprecated, please migrate to using setPersistBatch().
931   * <p>
932   * Set to true if you what to use JDBC batching for persisting and deleting beans.
933   * <p>
934   * With this Ebean will batch up persist requests and use the JDBC batch api.
935   * This is a performance optimisation designed to reduce the network chatter.
936   * <p>
937   * When true this is equivalent to {@code setPersistBatch(PersistBatch.ALL)} or
938   * when false to {@code setPersistBatch(PersistBatch.NONE)}
939   */
940  public void setPersistBatching(boolean persistBatching) {
941    this.persistBatch = (persistBatching) ? PersistBatch.ALL : PersistBatch.NONE;
942  }
943
944  /**
945   * Return the batch size used for JDBC batching. This defaults to 20.
946   */
947  public int getPersistBatchSize() {
948    return persistBatchSize;
949  }
950
951  /**
952   * Set the batch size used for JDBC batching. If unset this defaults to 20.
953   * <p>
954   * You can also set the batch size on the transaction.
955   *
956   * @see Transaction#setBatchSize(int)
957   */
958  public void setPersistBatchSize(int persistBatchSize) {
959    this.persistBatchSize = persistBatchSize;
960  }
961
962  /**
963   * Gets the query batch size. This defaults to 100.
964   *
965   * @return the query batch size
966   */
967  public int getQueryBatchSize() {
968    return queryBatchSize;
969  }
970
971  /**
972   * Sets the query batch size. This defaults to 100.
973   *
974   * @param queryBatchSize the new query batch size
975   */
976  public void setQueryBatchSize(int queryBatchSize) {
977    this.queryBatchSize = queryBatchSize;
978  }
979
980  public EnumType getDefaultEnumType() {
981    return defaultEnumType;
982  }
983
984  public void setDefaultEnumType(EnumType defaultEnumType) {
985    this.defaultEnumType = defaultEnumType;
986  }
987
988  /**
989   * Return true if lazy loading is disabled on queries by default.
990   */
991  public boolean isDisableLazyLoading() {
992    return disableLazyLoading;
993  }
994
995  /**
996   * Set to true to disable lazy loading by default.
997   * <p>
998   * It can be turned on per query via {@link Query#setDisableLazyLoading(boolean)}.
999   */
1000  public void setDisableLazyLoading(boolean disableLazyLoading) {
1001    this.disableLazyLoading = disableLazyLoading;
1002  }
1003
1004  /**
1005   * Return the default batch size for lazy loading of beans and collections.
1006   */
1007  public int getLazyLoadBatchSize() {
1008    return lazyLoadBatchSize;
1009  }
1010
1011  /**
1012   * Set the default batch size for lazy loading.
1013   * <p>
1014   * This is the number of beans or collections loaded when lazy loading is
1015   * invoked by default.
1016   * <p>
1017   * The default value is for this is 10 (load 10 beans or collections).
1018   * <p>
1019   * You can explicitly control the lazy loading batch size for a given join on
1020   * a query using +lazy(batchSize) or JoinConfig.
1021   */
1022  public void setLazyLoadBatchSize(int lazyLoadBatchSize) {
1023    this.lazyLoadBatchSize = lazyLoadBatchSize;
1024  }
1025
1026  /**
1027   * Set the number of sequences to fetch/preallocate when using DB sequences.
1028   * <p>
1029   * This is a performance optimisation to reduce the number times Ebean
1030   * requests a sequence to be used as an Id for a bean (aka reduce network
1031   * chatter).
1032
1033   */
1034  public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) {
1035    platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
1036  }
1037
1038  /**
1039   * Return the default JDBC fetchSize hint for findList queries.
1040   */
1041  public int getJdbcFetchSizeFindList() {
1042    return jdbcFetchSizeFindList;
1043  }
1044
1045  /**
1046   * Set the default JDBC fetchSize hint for findList queries.
1047   */
1048  public void setJdbcFetchSizeFindList(int jdbcFetchSizeFindList) {
1049    this.jdbcFetchSizeFindList = jdbcFetchSizeFindList;
1050  }
1051
1052  /**
1053   * Return the default JDBC fetchSize hint for findEach/findEachWhile queries.
1054   */
1055  public int getJdbcFetchSizeFindEach() {
1056    return jdbcFetchSizeFindEach;
1057  }
1058
1059  /**
1060   * Set the default JDBC fetchSize hint for findEach/findEachWhile queries.
1061   */
1062  public void setJdbcFetchSizeFindEach(int jdbcFetchSizeFindEach) {
1063    this.jdbcFetchSizeFindEach = jdbcFetchSizeFindEach;
1064  }
1065
1066  /**
1067   * Return the ChangeLogPrepare.
1068   * <p>
1069   * This is used to set user context information to the ChangeSet in the
1070   * foreground thread prior to the logging occurring in a background thread.
1071   */
1072  public ChangeLogPrepare getChangeLogPrepare() {
1073    return changeLogPrepare;
1074  }
1075
1076  /**
1077   * Set the ChangeLogPrepare.
1078   * <p>
1079   * This is used to set user context information to the ChangeSet in the
1080   * foreground thread prior to the logging occurring in a background thread.
1081   */
1082  public void setChangeLogPrepare(ChangeLogPrepare changeLogPrepare) {
1083    this.changeLogPrepare = changeLogPrepare;
1084  }
1085
1086  /**
1087   * Return the ChangeLogListener which actually performs the logging of change sets
1088   * in the background.
1089   */
1090  public ChangeLogListener getChangeLogListener() {
1091    return changeLogListener;
1092  }
1093
1094  /**
1095   * Set the ChangeLogListener which actually performs the logging of change sets
1096   * in the background.
1097   */
1098  public void setChangeLogListener(ChangeLogListener changeLogListener) {
1099    this.changeLogListener = changeLogListener;
1100  }
1101
1102  /**
1103   * Return the ChangeLogRegister which controls which ChangeLogFilter is used for each
1104   * bean type and in this way provide fine grained control over which persist requests
1105   * are included in the change log.
1106   */
1107  public ChangeLogRegister getChangeLogRegister() {
1108    return changeLogRegister;
1109  }
1110
1111  /**
1112   * Set the ChangeLogRegister which controls which ChangeLogFilter is used for each
1113   * bean type and in this way provide fine grained control over which persist requests
1114   * are included in the change log.
1115   */
1116  public void setChangeLogRegister(ChangeLogRegister changeLogRegister) {
1117    this.changeLogRegister = changeLogRegister;
1118  }
1119
1120  /**
1121   * Return true if inserts should be included in the change log by default.
1122   */
1123  public boolean isChangeLogIncludeInserts() {
1124    return changeLogIncludeInserts;
1125  }
1126
1127  /**
1128   * Set if inserts should be included in the change log by default.
1129   */
1130  public void setChangeLogIncludeInserts(boolean changeLogIncludeInserts) {
1131    this.changeLogIncludeInserts = changeLogIncludeInserts;
1132  }
1133
1134  /**
1135   * Return true (default) if the changelog should be written async.
1136   */
1137  public boolean isChangeLogAsync() {
1138    return changeLogAsync;
1139  }
1140
1141  /**
1142   * Sets if the changelog should be written async (default = true).
1143   */
1144  public void setChangeLogAsync(boolean changeLogAsync) {
1145    this.changeLogAsync = changeLogAsync;
1146  }
1147
1148  /**
1149   * Return the ReadAuditLogger to use.
1150   */
1151  public ReadAuditLogger getReadAuditLogger() {
1152    return readAuditLogger;
1153  }
1154
1155  /**
1156   * Set the ReadAuditLogger to use. If not set the default implementation is used
1157   * which logs the read events in JSON format to a standard named SLF4J logger
1158   * (which can be configured in say logback to log to a separate log file).
1159   */
1160  public void setReadAuditLogger(ReadAuditLogger readAuditLogger) {
1161    this.readAuditLogger = readAuditLogger;
1162  }
1163
1164  /**
1165   * Return the ReadAuditPrepare to use.
1166   */
1167  public ReadAuditPrepare getReadAuditPrepare() {
1168    return readAuditPrepare;
1169  }
1170
1171  /**
1172   * Set the ReadAuditPrepare to use.
1173   * <p>
1174   * It is expected that an implementation is used that read user context information
1175   * (user id, user ip address etc) and sets it on the ReadEvent bean before it is sent
1176   * to the ReadAuditLogger.
1177   */
1178  public void setReadAuditPrepare(ReadAuditPrepare readAuditPrepare) {
1179    this.readAuditPrepare = readAuditPrepare;
1180  }
1181
1182  /**
1183   * Return the configuration for profiling.
1184   */
1185  public ProfilingConfig getProfilingConfig() {
1186    return profilingConfig;
1187  }
1188
1189  /**
1190   * Set the configuration for profiling.
1191   */
1192  public void setProfilingConfig(ProfilingConfig profilingConfig) {
1193    this.profilingConfig = profilingConfig;
1194  }
1195
1196  /**
1197   * Return the DB schema to use.
1198   */
1199  public String getDbSchema() {
1200    return dbSchema;
1201  }
1202
1203  /**
1204   * Set the DB schema to use. This specifies to use this schema for:
1205   * <ul>
1206   * <li>Running Database migrations - Create and use the DB schema</li>
1207   * <li>Testing DDL - Create-all.sql DDL execution creates and uses schema</li>
1208   * <li>Testing Docker - Set default schema on connection URL</li>
1209   * </ul>
1210   */
1211  public void setDbSchema(String dbSchema) {
1212    this.dbSchema = dbSchema;
1213  }
1214
1215  /**
1216   * Return the DB migration configuration.
1217   */
1218  public DbMigrationConfig getMigrationConfig() {
1219    return migrationConfig;
1220  }
1221
1222  /**
1223   * Set the DB migration configuration.
1224   */
1225  public void setMigrationConfig(DbMigrationConfig migrationConfig) {
1226    this.migrationConfig = migrationConfig;
1227  }
1228
1229  /**
1230   * Return the Geometry SRID.
1231   */
1232  public int getGeometrySRID() {
1233    return platformConfig.getGeometrySRID();
1234  }
1235
1236  /**
1237   * Set the Geometry SRID.
1238   */
1239  public void setGeometrySRID(int geometrySRID) {
1240    platformConfig.setGeometrySRID(geometrySRID);
1241  }
1242
1243  /**
1244   * Return the time zone to use when reading/writing Timestamps via JDBC.
1245   * <p>
1246   * When set a Calendar object is used in JDBC calls when reading/writing Timestamp objects.
1247   */
1248  public String getDataTimeZone() {
1249    return System.getProperty("ebean.dataTimeZone", dataTimeZone);
1250  }
1251
1252  /**
1253   * Set the time zone to use when reading/writing Timestamps via JDBC.
1254   */
1255  public void setDataTimeZone(String dataTimeZone) {
1256    this.dataTimeZone = dataTimeZone;
1257  }
1258
1259  /**
1260   * Return the suffix appended to the base table to derive the view that contains the union
1261   * of the base table and the history table in order to support asOf queries.
1262   */
1263  public String getAsOfViewSuffix() {
1264    return asOfViewSuffix;
1265  }
1266
1267  /**
1268   * Set the suffix appended to the base table to derive the view that contains the union
1269   * of the base table and the history table in order to support asOf queries.
1270   */
1271  public void setAsOfViewSuffix(String asOfViewSuffix) {
1272    this.asOfViewSuffix = asOfViewSuffix;
1273  }
1274
1275  /**
1276   * Return the database column used to support history and 'As of' queries. This column is a timestamp range
1277   * or equivalent.
1278   */
1279  public String getAsOfSysPeriod() {
1280    return asOfSysPeriod;
1281  }
1282
1283  /**
1284   * Set the database column used to support history and 'As of' queries. This column is a timestamp range
1285   * or equivalent.
1286   */
1287  public void setAsOfSysPeriod(String asOfSysPeriod) {
1288    this.asOfSysPeriod = asOfSysPeriod;
1289  }
1290
1291  /**
1292   * Return the history table suffix (defaults to _history).
1293   */
1294  public String getHistoryTableSuffix() {
1295    return historyTableSuffix;
1296  }
1297
1298  /**
1299   * Set the history table suffix.
1300   */
1301  public void setHistoryTableSuffix(String historyTableSuffix) {
1302    this.historyTableSuffix = historyTableSuffix;
1303  }
1304
1305  /**
1306   * Return true if we are running in a JTA Transaction manager.
1307   */
1308  public boolean isUseJtaTransactionManager() {
1309    return useJtaTransactionManager;
1310  }
1311
1312  /**
1313   * Set to true if we are running in a JTA Transaction manager.
1314   */
1315  public void setUseJtaTransactionManager(boolean useJtaTransactionManager) {
1316    this.useJtaTransactionManager = useJtaTransactionManager;
1317  }
1318
1319  /**
1320   * Return the external transaction manager.
1321   */
1322  public ExternalTransactionManager getExternalTransactionManager() {
1323    return externalTransactionManager;
1324  }
1325
1326  /**
1327   * Set the external transaction manager.
1328   */
1329  public void setExternalTransactionManager(ExternalTransactionManager externalTransactionManager) {
1330    this.externalTransactionManager = externalTransactionManager;
1331  }
1332
1333  /**
1334   * Return the ServerCachePlugin.
1335   */
1336  public ServerCachePlugin getServerCachePlugin() {
1337    return serverCachePlugin;
1338  }
1339
1340  /**
1341   * Set the ServerCachePlugin to use.
1342   */
1343  public void setServerCachePlugin(ServerCachePlugin serverCachePlugin) {
1344    this.serverCachePlugin = serverCachePlugin;
1345  }
1346
1347  /**
1348   * Return true if LOB's should default to fetch eager.
1349   * By default this is set to false and LOB's must be explicitly fetched.
1350   */
1351  public boolean isEagerFetchLobs() {
1352    return eagerFetchLobs;
1353  }
1354
1355  /**
1356   * Set to true if you want LOB's to be fetch eager by default.
1357   * By default this is set to false and LOB's must be explicitly fetched.
1358   */
1359  public void setEagerFetchLobs(boolean eagerFetchLobs) {
1360    this.eagerFetchLobs = eagerFetchLobs;
1361  }
1362
1363  /**
1364   * Return the max call stack to use for origin location.
1365   */
1366  public int getMaxCallStack() {
1367    return maxCallStack;
1368  }
1369
1370  /**
1371   * Set the max call stack to use for origin location.
1372   */
1373  public void setMaxCallStack(int maxCallStack) {
1374    this.maxCallStack = maxCallStack;
1375  }
1376
1377  /**
1378   * Return true if transactions should rollback on checked exceptions.
1379   */
1380  public boolean isTransactionRollbackOnChecked() {
1381    return transactionRollbackOnChecked;
1382  }
1383
1384  /**
1385   * Set to true if transactions should by default rollback on checked exceptions.
1386   */
1387  public void setTransactionRollbackOnChecked(boolean transactionRollbackOnChecked) {
1388    this.transactionRollbackOnChecked = transactionRollbackOnChecked;
1389  }
1390
1391  /**
1392   * Return the Background executor schedule pool size. Defaults to 1.
1393   */
1394  public int getBackgroundExecutorSchedulePoolSize() {
1395    return backgroundExecutorSchedulePoolSize;
1396  }
1397
1398  /**
1399   * Set the Background executor schedule pool size.
1400   */
1401  public void setBackgroundExecutorSchedulePoolSize(int backgroundExecutorSchedulePoolSize) {
1402    this.backgroundExecutorSchedulePoolSize = backgroundExecutorSchedulePoolSize;
1403  }
1404
1405  /**
1406   * Return the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely
1407   * before it is forced shutdown.
1408   */
1409  public int getBackgroundExecutorShutdownSecs() {
1410    return backgroundExecutorShutdownSecs;
1411  }
1412
1413  /**
1414   * Set the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely
1415   * before it is forced shutdown.
1416   */
1417  public void setBackgroundExecutorShutdownSecs(int backgroundExecutorShutdownSecs) {
1418    this.backgroundExecutorShutdownSecs = backgroundExecutorShutdownSecs;
1419  }
1420
1421  /**
1422   * Return the L2 cache default max size.
1423   */
1424  public int getCacheMaxSize() {
1425    return cacheMaxSize;
1426  }
1427
1428  /**
1429   * Set the L2 cache default max size.
1430   */
1431  public void setCacheMaxSize(int cacheMaxSize) {
1432    this.cacheMaxSize = cacheMaxSize;
1433  }
1434
1435  /**
1436   * Return the L2 cache default max idle time in seconds.
1437   */
1438  public int getCacheMaxIdleTime() {
1439    return cacheMaxIdleTime;
1440  }
1441
1442  /**
1443   * Set the L2 cache default max idle time in seconds.
1444   */
1445  public void setCacheMaxIdleTime(int cacheMaxIdleTime) {
1446    this.cacheMaxIdleTime = cacheMaxIdleTime;
1447  }
1448
1449  /**
1450   * Return the L2 cache default max time to live in seconds.
1451   */
1452  public int getCacheMaxTimeToLive() {
1453    return cacheMaxTimeToLive;
1454  }
1455
1456  /**
1457   * Set the L2 cache default max time to live in seconds.
1458   */
1459  public void setCacheMaxTimeToLive(int cacheMaxTimeToLive) {
1460    this.cacheMaxTimeToLive = cacheMaxTimeToLive;
1461  }
1462
1463  /**
1464   * Return the L2 query cache default max size.
1465   */
1466  public int getQueryCacheMaxSize() {
1467    return queryCacheMaxSize;
1468  }
1469
1470  /**
1471   * Set the L2 query cache default max size.
1472   */
1473  public void setQueryCacheMaxSize(int queryCacheMaxSize) {
1474    this.queryCacheMaxSize = queryCacheMaxSize;
1475  }
1476
1477  /**
1478   * Return the L2 query cache default max idle time in seconds.
1479   */
1480  public int getQueryCacheMaxIdleTime() {
1481    return queryCacheMaxIdleTime;
1482  }
1483
1484  /**
1485   * Set the L2 query cache default max idle time in seconds.
1486   */
1487  public void setQueryCacheMaxIdleTime(int queryCacheMaxIdleTime) {
1488    this.queryCacheMaxIdleTime = queryCacheMaxIdleTime;
1489  }
1490
1491  /**
1492   * Return the L2 query cache default max time to live in seconds.
1493   */
1494  public int getQueryCacheMaxTimeToLive() {
1495    return queryCacheMaxTimeToLive;
1496  }
1497
1498  /**
1499   * Set the L2 query cache default max time to live in seconds.
1500   */
1501  public void setQueryCacheMaxTimeToLive(int queryCacheMaxTimeToLive) {
1502    this.queryCacheMaxTimeToLive = queryCacheMaxTimeToLive;
1503  }
1504
1505  /**
1506   * Return the NamingConvention.
1507   * <p>
1508   * If none has been set the default UnderscoreNamingConvention is used.
1509   */
1510  public NamingConvention getNamingConvention() {
1511    return namingConvention;
1512  }
1513
1514  /**
1515   * Set the NamingConvention.
1516   * <p>
1517   * If none is set the default UnderscoreNamingConvention is used.
1518   */
1519  public void setNamingConvention(NamingConvention namingConvention) {
1520    this.namingConvention = namingConvention;
1521  }
1522
1523  /**
1524   * Return true if all DB column and table names should use quoted identifiers.
1525   */
1526  public boolean isAllQuotedIdentifiers() {
1527    return platformConfig.isAllQuotedIdentifiers();
1528  }
1529
1530  /**
1531   * Set to true if all DB column and table names should use quoted identifiers.
1532   */
1533  public void setAllQuotedIdentifiers(boolean allQuotedIdentifiers) {
1534    platformConfig.setAllQuotedIdentifiers(allQuotedIdentifiers);
1535    if (allQuotedIdentifiers) {
1536      adjustNamingConventionForAllQuoted();
1537    }
1538  }
1539
1540  private void adjustNamingConventionForAllQuoted() {
1541    if (namingConvention instanceof UnderscoreNamingConvention) {
1542      // we need to use matching naming convention
1543      this.namingConvention = new MatchingNamingConvention();
1544    }
1545  }
1546
1547  /**
1548   * Return true if this Database is a Document store only instance (has no JDBC DB).
1549   */
1550  public boolean isDocStoreOnly() {
1551    return docStoreOnly;
1552  }
1553
1554  /**
1555   * Set to true if this Database is Document store only instance (has no JDBC DB).
1556   */
1557  public void setDocStoreOnly(boolean docStoreOnly) {
1558    this.docStoreOnly = docStoreOnly;
1559  }
1560
1561  /**
1562   * Return the configuration for the ElasticSearch integration.
1563   */
1564  public DocStoreConfig getDocStoreConfig() {
1565    return docStoreConfig;
1566  }
1567
1568  /**
1569   * Set the configuration for the ElasticSearch integration.
1570   */
1571  public void setDocStoreConfig(DocStoreConfig docStoreConfig) {
1572    this.docStoreConfig = docStoreConfig;
1573  }
1574
1575  /**
1576   * Return the constraint naming convention used in DDL generation.
1577   */
1578  public DbConstraintNaming getConstraintNaming() {
1579    return platformConfig.getConstraintNaming();
1580  }
1581
1582  /**
1583   * Set the constraint naming convention used in DDL generation.
1584   */
1585  public void setConstraintNaming(DbConstraintNaming constraintNaming) {
1586    platformConfig.setConstraintNaming(constraintNaming);
1587  }
1588
1589  /**
1590   * Return the configuration for AutoTune.
1591   */
1592  public AutoTuneConfig getAutoTuneConfig() {
1593    return autoTuneConfig;
1594  }
1595
1596  /**
1597   * Set the configuration for AutoTune.
1598   */
1599  public void setAutoTuneConfig(AutoTuneConfig autoTuneConfig) {
1600    this.autoTuneConfig = autoTuneConfig;
1601  }
1602
1603  /**
1604   * Return the DataSource.
1605   */
1606  public DataSource getDataSource() {
1607    return dataSource;
1608  }
1609
1610  /**
1611   * Set a DataSource.
1612   */
1613  public void setDataSource(DataSource dataSource) {
1614    this.dataSource = dataSource;
1615  }
1616
1617  /**
1618   * Return the read only DataSource.
1619   */
1620  public DataSource getReadOnlyDataSource() {
1621    return readOnlyDataSource;
1622  }
1623
1624  /**
1625   * Set the read only DataSource.
1626   * <p>
1627   * Note that the DataSource is expected to use AutoCommit true mode avoiding the need
1628   * for explicit commit (or rollback).
1629   * <p>
1630   * This read only DataSource will be used for implicit query only transactions. It is not
1631   * used if the transaction is created explicitly or if the query is an update or delete query.
1632   */
1633  public void setReadOnlyDataSource(DataSource readOnlyDataSource) {
1634    this.readOnlyDataSource = readOnlyDataSource;
1635  }
1636
1637  /**
1638   * Return the configuration to build a DataSource using Ebean's own DataSource
1639   * implementation.
1640   */
1641  public DataSourceConfig getDataSourceConfig() {
1642    return dataSourceConfig;
1643  }
1644
1645  /**
1646   * Set the configuration required to build a DataSource using Ebean's own
1647   * DataSource implementation.
1648   */
1649  public void setDataSourceConfig(DataSourceConfig dataSourceConfig) {
1650    this.dataSourceConfig = dataSourceConfig;
1651  }
1652
1653  /**
1654   * Return true if Ebean should create a DataSource for use with implicit read only transactions.
1655   */
1656  public boolean isAutoReadOnlyDataSource() {
1657    return autoReadOnlyDataSource;
1658  }
1659
1660  /**
1661   * Set to true if Ebean should create a DataSource for use with implicit read only transactions.
1662   */
1663  public void setAutoReadOnlyDataSource(boolean autoReadOnlyDataSource) {
1664    this.autoReadOnlyDataSource = autoReadOnlyDataSource;
1665  }
1666
1667  /**
1668   * Return the configuration for the read only DataSource.
1669   * <p>
1670   * This is only used if autoReadOnlyDataSource is true.
1671   * <p>
1672   * The driver, url, username and password default to the configuration for the main DataSource if they are not
1673   * set on this configuration. This means there is actually no need to set any configuration here and we only
1674   * set configuration for url, username and password etc if it is different from the main DataSource.
1675   */
1676  public DataSourceConfig getReadOnlyDataSourceConfig() {
1677    return readOnlyDataSourceConfig;
1678  }
1679
1680  /**
1681   * Set the configuration for the read only DataSource.
1682   */
1683  public void setReadOnlyDataSourceConfig(DataSourceConfig readOnlyDataSourceConfig) {
1684    this.readOnlyDataSourceConfig = readOnlyDataSourceConfig;
1685  }
1686
1687  /**
1688   * Return the JNDI name of the DataSource to use.
1689   */
1690  public String getDataSourceJndiName() {
1691    return dataSourceJndiName;
1692  }
1693
1694  /**
1695   * Set the JNDI name of the DataSource to use.
1696   * <p>
1697   * By default a prefix of "java:comp/env/jdbc/" is used to lookup the
1698   * DataSource. This prefix is not used if dataSourceJndiName starts with
1699   * "java:".
1700   */
1701  public void setDataSourceJndiName(String dataSourceJndiName) {
1702    this.dataSourceJndiName = dataSourceJndiName;
1703  }
1704
1705  /**
1706   * Return a value used to represent TRUE in the database.
1707   * <p>
1708   * This is used for databases that do not support boolean natively.
1709   * <p>
1710   * The value returned is either a Integer or a String (e.g. "1", or "T").
1711   */
1712  public String getDatabaseBooleanTrue() {
1713    return platformConfig.getDatabaseBooleanTrue();
1714  }
1715
1716  /**
1717   * Set the value to represent TRUE in the database.
1718   * <p>
1719   * This is used for databases that do not support boolean natively.
1720   * <p>
1721   * The value set is either a Integer or a String (e.g. "1", or "T").
1722   */
1723  public void setDatabaseBooleanTrue(String databaseTrue) {
1724    platformConfig.setDatabaseBooleanTrue(databaseTrue);
1725  }
1726
1727  /**
1728   * Return a value used to represent FALSE in the database.
1729   * <p>
1730   * This is used for databases that do not support boolean natively.
1731   * <p>
1732   * The value returned is either a Integer or a String (e.g. "0", or "F").
1733   */
1734  public String getDatabaseBooleanFalse() {
1735    return platformConfig.getDatabaseBooleanFalse();
1736  }
1737
1738  /**
1739   * Set the value to represent FALSE in the database.
1740   * <p>
1741   * This is used for databases that do not support boolean natively.
1742   * <p>
1743   * The value set is either a Integer or a String (e.g. "0", or "F").
1744   */
1745  public void setDatabaseBooleanFalse(String databaseFalse) {
1746    this.platformConfig.setDatabaseBooleanFalse(databaseFalse);
1747  }
1748
1749  /**
1750   * Return the number of DB sequence values that should be preallocated.
1751   */
1752  public int getDatabaseSequenceBatchSize() {
1753    return platformConfig.getDatabaseSequenceBatchSize();
1754  }
1755
1756  /**
1757   * Set the number of DB sequence values that should be preallocated and cached
1758   * by Ebean.
1759   * <p>
1760   * This is only used for DB's that use sequences and is a performance
1761   * optimisation. This reduces the number of times Ebean needs to get a
1762   * sequence value from the Database reducing network chatter.
1763   * <p>
1764   * By default this value is 10 so when we need another Id (and don't have one
1765   * in our cache) Ebean will fetch 10 id's from the database. Note that when
1766   * the cache drops to have full (which is 5 by default) Ebean will fetch
1767   * another batch of Id's in a background thread.
1768   */
1769  public void setDatabaseSequenceBatch(int databaseSequenceBatchSize) {
1770    this.platformConfig.setDatabaseSequenceBatchSize(databaseSequenceBatchSize);
1771  }
1772
1773  /**
1774   * Return the database platform name (can be null).
1775   * <p>
1776   * If null then the platform is determined automatically via the JDBC driver
1777   * information.
1778   */
1779  public String getDatabasePlatformName() {
1780    return databasePlatformName;
1781  }
1782
1783  /**
1784   * Explicitly set the database platform name
1785   * <p>
1786   * If none is set then the platform is determined automatically via the JDBC
1787   * driver information.
1788   * <p>
1789   * This can be used when the Database Platform can not be automatically
1790   * detected from the JDBC driver (possibly 3rd party JDBC driver). It is also
1791   * useful when you want to do offline DDL generation for a database platform
1792   * that you don't have access to.
1793   * <p>
1794   * Values are oracle, h2, postgres, mysql, sqlserver16, sqlserver17.
1795   */
1796  public void setDatabasePlatformName(String databasePlatformName) {
1797    this.databasePlatformName = databasePlatformName;
1798  }
1799
1800  /**
1801   * Return the database platform to use for this database.
1802   */
1803  public DatabasePlatform getDatabasePlatform() {
1804    return databasePlatform;
1805  }
1806
1807  /**
1808   * Explicitly set the database platform to use.
1809   * <p>
1810   * If none is set then the platform is determined via the databasePlatformName
1811   * or automatically via the JDBC driver information.
1812   */
1813  public void setDatabasePlatform(DatabasePlatform databasePlatform) {
1814    this.databasePlatform = databasePlatform;
1815  }
1816
1817  /**
1818   * Return the preferred DB platform IdType.
1819   */
1820  public IdType getIdType() {
1821    return platformConfig.getIdType();
1822  }
1823
1824  /**
1825   * Set the preferred DB platform IdType.
1826   */
1827  public void setIdType(IdType idType) {
1828    this.platformConfig.setIdType(idType);
1829  }
1830
1831  /**
1832   * Return the EncryptKeyManager.
1833   */
1834  public EncryptKeyManager getEncryptKeyManager() {
1835    return encryptKeyManager;
1836  }
1837
1838  /**
1839   * Set the EncryptKeyManager.
1840   * <p>
1841   * This is required when you want to use encrypted properties.
1842   * <p>
1843   * You can also set this in ebean.proprerties:
1844   * <p>
1845   * <pre>{@code
1846   * # set via ebean.properties
1847   * ebean.encryptKeyManager=org.avaje.tests.basic.encrypt.BasicEncyptKeyManager
1848   * }</pre>
1849   */
1850  public void setEncryptKeyManager(EncryptKeyManager encryptKeyManager) {
1851    this.encryptKeyManager = encryptKeyManager;
1852  }
1853
1854  /**
1855   * Return the EncryptDeployManager.
1856   * <p>
1857   * This is optionally used to programmatically define which columns are
1858   * encrypted instead of using the {@link Encrypted} Annotation.
1859   */
1860  public EncryptDeployManager getEncryptDeployManager() {
1861    return encryptDeployManager;
1862  }
1863
1864  /**
1865   * Set the EncryptDeployManager.
1866   * <p>
1867   * This is optionally used to programmatically define which columns are
1868   * encrypted instead of using the {@link Encrypted} Annotation.
1869   */
1870  public void setEncryptDeployManager(EncryptDeployManager encryptDeployManager) {
1871    this.encryptDeployManager = encryptDeployManager;
1872  }
1873
1874  /**
1875   * Return the Encryptor used to encrypt data on the java client side (as
1876   * opposed to DB encryption functions).
1877   */
1878  public Encryptor getEncryptor() {
1879    return encryptor;
1880  }
1881
1882  /**
1883   * Set the Encryptor used to encrypt data on the java client side (as opposed
1884   * to DB encryption functions).
1885   * <p>
1886   * Ebean has a default implementation that it will use if you do not set your
1887   * own Encryptor implementation.
1888   */
1889  public void setEncryptor(Encryptor encryptor) {
1890    this.encryptor = encryptor;
1891  }
1892
1893  /**
1894   * Return true if the Database instance should be created in offline mode.
1895   */
1896  public boolean isDbOffline() {
1897    return dbOffline;
1898  }
1899
1900  /**
1901   * Set to true if the Database instance should be created in offline mode.
1902   * <p>
1903   * Typically used to create an Database instance for DDL Migration generation
1904   * without requiring a real DataSource / Database to connect to.
1905   */
1906  public void setDbOffline(boolean dbOffline) {
1907    this.dbOffline = dbOffline;
1908  }
1909
1910  /**
1911   * Return the DbEncrypt used to encrypt and decrypt properties.
1912   * <p>
1913   * Note that if this is not set then the DbPlatform may already have a
1914   * DbEncrypt set and that will be used.
1915   */
1916  public DbEncrypt getDbEncrypt() {
1917    return dbEncrypt;
1918  }
1919
1920  /**
1921   * Set the DbEncrypt used to encrypt and decrypt properties.
1922   * <p>
1923   * Note that if this is not set then the DbPlatform may already have a
1924   * DbEncrypt set (H2, MySql, Postgres and Oracle platforms have a DbEncrypt)
1925   */
1926  public void setDbEncrypt(DbEncrypt dbEncrypt) {
1927    this.dbEncrypt = dbEncrypt;
1928  }
1929
1930  /**
1931   * Return the configuration for DB types (such as UUID and custom mappings).
1932   */
1933  public PlatformConfig getPlatformConfig() {
1934    return platformConfig;
1935  }
1936
1937  /**
1938   * Set the configuration for DB platform (such as UUID and custom mappings).
1939   */
1940  public void setPlatformConfig(PlatformConfig platformConfig) {
1941    this.platformConfig = platformConfig;
1942  }
1943
1944  /**
1945   * Set the DB type used to store UUID.
1946   */
1947  public void setDbUuid(PlatformConfig.DbUuid dbUuid) {
1948    this.platformConfig.setDbUuid(dbUuid);
1949  }
1950
1951  /**
1952   * Returns the UUID version mode.
1953   */
1954  public UuidVersion getUuidVersion() {
1955    return uuidVersion;
1956  }
1957
1958  /**
1959   * Sets the UUID version mode.
1960   */
1961  public void setUuidVersion(UuidVersion uuidVersion) {
1962    this.uuidVersion = uuidVersion;
1963  }
1964
1965  /**
1966   * Return the UUID state file.
1967   */
1968  public String getUuidStateFile() {
1969    if (uuidStateFile == null || uuidStateFile.isEmpty()) {
1970      // by default, add servername...
1971      uuidStateFile = name + "-uuid.state";
1972      // and store it in the user's home directory
1973      String homeDir = System.getProperty("user.home");
1974      if (homeDir != null && homeDir.isEmpty()) {
1975        uuidStateFile = homeDir + "/.ebean/" + uuidStateFile;
1976      }
1977    }
1978    return uuidStateFile;
1979  }
1980
1981  /**
1982   * Set the UUID state file.
1983   */
1984  public void setUuidStateFile(String uuidStateFile) {
1985    this.uuidStateFile = uuidStateFile;
1986  }
1987
1988  /**
1989   * Return true if LocalTime should be persisted with nanos precision.
1990   */
1991  public boolean isLocalTimeWithNanos() {
1992    return localTimeWithNanos;
1993  }
1994
1995  /**
1996   * Set to true if LocalTime should be persisted with nanos precision.
1997   * <p>
1998   * Otherwise it is persisted using java.sql.Time which is seconds precision.
1999   */
2000  public void setLocalTimeWithNanos(boolean localTimeWithNanos) {
2001    this.localTimeWithNanos = localTimeWithNanos;
2002  }
2003
2004  /**
2005   * Return true if Duration should be persisted with nanos precision (SQL DECIMAL).
2006   * <p>
2007   * Otherwise it is persisted with second precision (SQL INTEGER).
2008   */
2009  public boolean isDurationWithNanos() {
2010    return durationWithNanos;
2011  }
2012
2013  /**
2014   * Set to true if Duration should be persisted with nanos precision (SQL DECIMAL).
2015   * <p>
2016   * Otherwise it is persisted with second precision (SQL INTEGER).
2017   */
2018  public void setDurationWithNanos(boolean durationWithNanos) {
2019    this.durationWithNanos = durationWithNanos;
2020  }
2021
2022  /**
2023   * Set to true to run DB migrations on server start.
2024   * <p>
2025   * This is the same as config.getMigrationConfig().setRunMigration(). We have added this method here
2026   * as it is often the only thing we need to configure for migrations.
2027   */
2028  public void setRunMigration(boolean runMigration) {
2029    migrationConfig.setRunMigration(runMigration);
2030  }
2031
2032  /**
2033   * Set to true to generate the "create all" DDL on startup.
2034   * <p>
2035   * Typically we want this on when we are running tests locally (and often using H2)
2036   * and we want to create the full DB schema from scratch to run tests.
2037   */
2038  public void setDdlGenerate(boolean ddlGenerate) {
2039    this.ddlGenerate = ddlGenerate;
2040  }
2041
2042  /**
2043   * Set to true to run the generated "create all DDL" on startup.
2044   * <p>
2045   * Typically we want this on when we are running tests locally (and often using H2)
2046   * and we want to create the full DB schema from scratch to run tests.
2047   */
2048  public void setDdlRun(boolean ddlRun) {
2049    this.ddlRun = ddlRun;
2050  }
2051
2052  /**
2053   * Set to false if you not want to run the extra-ddl.xml scripts. (default = true)
2054   * <p>
2055   * Typically we want this on when we are running tests.
2056   */
2057  public void setDdlExtra(boolean ddlExtra) {
2058    this.ddlExtra = ddlExtra;
2059  }
2060
2061
2062  /**
2063   * Return true if the "drop all ddl" should be skipped.
2064   * <p>
2065   * Typically we want to do this when using H2 (in memory) as our test database and the drop statements
2066   * are not required so skipping the drop table statements etc makes it faster with less noise in the logs.
2067   */
2068  public boolean isDdlCreateOnly() {
2069    return ddlCreateOnly;
2070  }
2071
2072  /**
2073   * Set to true if the "drop all ddl" should be skipped.
2074   * <p>
2075   * Typically we want to do this when using H2 (in memory) as our test database and the drop statements
2076   * are not required so skipping the drop table statements etc makes it faster with less noise in the logs.
2077   */
2078  public void setDdlCreateOnly(boolean ddlCreateOnly) {
2079    this.ddlCreateOnly = ddlCreateOnly;
2080  }
2081
2082  /**
2083   * Return SQL script to execute after the "create all" DDL has been run.
2084   * <p>
2085   * Typically this is a sql script that inserts test seed data when running tests.
2086   * Place a sql script in src/test/resources that inserts test seed data.
2087   */
2088  public String getDdlSeedSql() {
2089    return ddlSeedSql;
2090  }
2091
2092  /**
2093   * Set a SQL script to execute after the "create all" DDL has been run.
2094   * <p>
2095   * Typically this is a sql script that inserts test seed data when running tests.
2096   * Place a sql script in src/test/resources that inserts test seed data.
2097   */
2098  public void setDdlSeedSql(String ddlSeedSql) {
2099    this.ddlSeedSql = ddlSeedSql;
2100  }
2101
2102  /**
2103   * Return a SQL script to execute before the "create all" DDL has been run.
2104   */
2105  public String getDdlInitSql() {
2106    return ddlInitSql;
2107  }
2108
2109  /**
2110   * Set a SQL script to execute before the "create all" DDL has been run.
2111   */
2112  public void setDdlInitSql(String ddlInitSql) {
2113    this.ddlInitSql = ddlInitSql;
2114  }
2115
2116  /**
2117   * Return true if the DDL should be generated.
2118   */
2119  public boolean isDdlGenerate() {
2120    return ddlGenerate;
2121  }
2122
2123  /**
2124   * Return true if the DDL should be run.
2125   */
2126  public boolean isDdlRun() {
2127    return ddlRun;
2128  }
2129
2130  /**
2131   * Return true, if extra-ddl.xml should be executed.
2132   */
2133  public boolean isDdlExtra() {
2134    return ddlExtra;
2135  }
2136
2137  /**
2138   * Return true if the class path search should be disabled.
2139   */
2140  public boolean isDisableClasspathSearch() {
2141    return disableClasspathSearch;
2142  }
2143
2144  /**
2145   * Set to true to disable the class path search even for the case where no entity bean classes
2146   * have been registered. This can be used to start an Database instance just to use the
2147   * SQL functions such as SqlQuery, SqlUpdate etc.
2148   */
2149  public void setDisableClasspathSearch(boolean disableClasspathSearch) {
2150    this.disableClasspathSearch = disableClasspathSearch;
2151  }
2152
2153  /**
2154   * Return the mode to use for Joda LocalTime support 'normal' or 'utc'.
2155   */
2156  public String getJodaLocalTimeMode() {
2157    return jodaLocalTimeMode;
2158  }
2159
2160  /**
2161   * Set the mode to use for Joda LocalTime support 'normal' or 'utc'.
2162   */
2163  public void setJodaLocalTimeMode(String jodaLocalTimeMode) {
2164    this.jodaLocalTimeMode = jodaLocalTimeMode;
2165  }
2166
2167  /**
2168   * Programmatically add classes (typically entities) that this server should
2169   * use.
2170   * <p>
2171   * The class can be an Entity, Embedded type, ScalarType, BeanPersistListener,
2172   * BeanFinder or BeanPersistController.
2173   * <p>
2174   * If no classes are specified then the classes are found automatically via
2175   * searching the class path.
2176   * <p>
2177   * Alternatively the classes can be added via {@link #setClasses(List)}.
2178   *
2179   * @param cls the entity type (or other type) that should be registered by this
2180   *            database.
2181   */
2182  public void addClass(Class<?> cls) {
2183    classes.add(cls);
2184  }
2185
2186  /**
2187   * Register all the classes (typically entity classes).
2188   */
2189  public void addAll(List<Class<?>> classList) {
2190    if (classList != null && !classList.isEmpty()) {
2191      classes.addAll(classList);
2192    }
2193  }
2194
2195  /**
2196   * Add a package to search for entities via class path search.
2197   * <p>
2198   * This is only used if classes have not been explicitly specified.
2199   */
2200  public void addPackage(String packageName) {
2201    packages.add(packageName);
2202  }
2203
2204  /**
2205   * Return packages to search for entities via class path search.
2206   * <p>
2207   * This is only used if classes have not been explicitly specified.
2208   */
2209  public List<String> getPackages() {
2210    return packages;
2211  }
2212
2213  /**
2214   * Set packages to search for entities via class path search.
2215   * <p>
2216   * This is only used if classes have not been explicitly specified.
2217   */
2218  public void setPackages(List<String> packages) {
2219    this.packages = packages;
2220  }
2221
2222  /**
2223   * Set the list of classes (entities, listeners, scalarTypes etc) that should
2224   * be used for this database.
2225   * <p>
2226   * If no classes are specified then the classes are found automatically via
2227   * searching the class path.
2228   * <p>
2229   * Alternatively the classes can contain added via {@link #addClass(Class)}.
2230   */
2231  public void setClasses(List<Class<?>> classes) {
2232    this.classes = classes;
2233  }
2234
2235  /**
2236   * Return the classes registered for this database. Typically this includes
2237   * entities and perhaps listeners.
2238   */
2239  public List<Class<?>> getClasses() {
2240    return classes;
2241  }
2242
2243  /**
2244   * Return true if L2 bean cache should be skipped once writes have occurred on a transaction.
2245   * <p>
2246   * This defaults to true and means that for "find by id" and "find by natural key"
2247   * queries that normally hit L2 bean cache automatically will not do so after a write/persist
2248   * on the transaction.
2249   * <p>
2250   * <pre>{@code
2251   *
2252   *   // assume Customer has L2 bean caching enabled ...
2253   *
2254   *   try (Transaction transaction = DB.beginTransaction()) {
2255   *
2256   *     // this uses L2 bean cache as the transaction
2257   *     // ... is considered "query only" at this point
2258   *     Customer.find.byId(42);
2259   *
2260   *     // transaction no longer "query only" once
2261   *     // ... a bean has been saved etc
2262   *     DB.save(someBean);
2263   *
2264   *     // will NOT use L2 bean cache as the transaction
2265   *     // ... is no longer considered "query only"
2266   *     Customer.find.byId(55);
2267   *
2268   *
2269   *
2270   *     // explicit control - please use L2 bean cache
2271   *
2272   *     transaction.setSkipCache(false);
2273   *     Customer.find.byId(77); // hit the l2 bean cache
2274   *
2275   *
2276   *     // explicit control - please don't use L2 bean cache
2277   *
2278   *     transaction.setSkipCache(true);
2279   *     Customer.find.byId(99); // skips l2 bean cache
2280   *
2281   *   }
2282   *
2283   * }</pre>
2284   *
2285   * @see Transaction#setSkipCache(boolean)
2286   */
2287  public boolean isSkipCacheAfterWrite() {
2288    return skipCacheAfterWrite;
2289  }
2290
2291  /**
2292   * Set to false when we still want to hit the cache after a write has occurred on a transaction.
2293   */
2294  public void setSkipCacheAfterWrite(boolean skipCacheAfterWrite) {
2295    this.skipCacheAfterWrite = skipCacheAfterWrite;
2296  }
2297
2298  /**
2299   * Returns true if updates in JDBC batch default to include all properties by default.
2300   */
2301  public boolean isUpdateAllPropertiesInBatch() {
2302    return updateAllPropertiesInBatch;
2303  }
2304
2305  /**
2306   * Set to false if by default updates in JDBC batch should not include all properties.
2307   * <p>
2308   * This mode can be explicitly set per transaction.
2309   *
2310   * @see Transaction#setUpdateAllLoadedProperties(boolean)
2311   */
2312  public void setUpdateAllPropertiesInBatch(boolean updateAllPropertiesInBatch) {
2313    this.updateAllPropertiesInBatch = updateAllPropertiesInBatch;
2314  }
2315
2316  /**
2317   * Returns the resource directory.
2318   */
2319  public String getResourceDirectory() {
2320    return resourceDirectory;
2321  }
2322
2323  /**
2324   * Sets the resource directory.
2325   */
2326  public void setResourceDirectory(String resourceDirectory) {
2327    this.resourceDirectory = resourceDirectory;
2328  }
2329
2330  /**
2331   * Add a custom type mapping.
2332   * <p>
2333   * <pre>{@code
2334   *
2335   *   // set the default mapping for BigDecimal.class/decimal
2336   *   config.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
2337   *
2338   *   // set the default mapping for String.class/varchar but only for Postgres
2339   *   config.addCustomMapping(DbType.VARCHAR, "text", Platform.POSTGRES);
2340   *
2341   * }</pre>
2342   *
2343   * @param type             The DB type this mapping should apply to
2344   * @param columnDefinition The column definition that should be used
2345   * @param platform         Optionally specify the platform this mapping should apply to.
2346   */
2347  public void addCustomMapping(DbType type, String columnDefinition, Platform platform) {
2348    platformConfig.addCustomMapping(type, columnDefinition, platform);
2349  }
2350
2351  /**
2352   * Add a custom type mapping that applies to all platforms.
2353   * <p>
2354   * <pre>{@code
2355   *
2356   *   // set the default mapping for BigDecimal/decimal
2357   *   config.addCustomMapping(DbType.DECIMAL, "decimal(18,6)");
2358   *
2359   *   // set the default mapping for String/varchar
2360   *   config.addCustomMapping(DbType.VARCHAR, "text");
2361   *
2362   * }</pre>
2363   *
2364   * @param type             The DB type this mapping should apply to
2365   * @param columnDefinition The column definition that should be used
2366   */
2367  public void addCustomMapping(DbType type, String columnDefinition) {
2368    platformConfig.addCustomMapping(type, columnDefinition);
2369  }
2370
2371  /**
2372   * Register a BeanQueryAdapter instance.
2373   * <p>
2374   * Note alternatively you can use {@link #setQueryAdapters(List)} to set all
2375   * the BeanQueryAdapter instances.
2376   */
2377  public void add(BeanQueryAdapter beanQueryAdapter) {
2378    queryAdapters.add(beanQueryAdapter);
2379  }
2380
2381  /**
2382   * Return the BeanQueryAdapter instances.
2383   */
2384  public List<BeanQueryAdapter> getQueryAdapters() {
2385    return queryAdapters;
2386  }
2387
2388  /**
2389   * Register all the BeanQueryAdapter instances.
2390   * <p>
2391   * Note alternatively you can use {@link #add(BeanQueryAdapter)} to add
2392   * BeanQueryAdapter instances one at a time.
2393   */
2394  public void setQueryAdapters(List<BeanQueryAdapter> queryAdapters) {
2395    this.queryAdapters = queryAdapters;
2396  }
2397
2398  /**
2399   * Return the custom IdGenerator instances.
2400   */
2401  public List<IdGenerator> getIdGenerators() {
2402    return idGenerators;
2403  }
2404
2405  /**
2406   * Set the custom IdGenerator instances.
2407   */
2408  public void setIdGenerators(List<IdGenerator> idGenerators) {
2409    this.idGenerators = idGenerators;
2410  }
2411
2412  /**
2413   * Register a customer IdGenerator instance.
2414   */
2415  public void add(IdGenerator idGenerator) {
2416    idGenerators.add(idGenerator);
2417  }
2418
2419  /**
2420   * Register a BeanPersistController instance.
2421   * <p>
2422   * Note alternatively you can use {@link #setPersistControllers(List)} to set
2423   * all the BeanPersistController instances.
2424   */
2425  public void add(BeanPersistController beanPersistController) {
2426    persistControllers.add(beanPersistController);
2427  }
2428
2429  /**
2430   * Register a BeanPostLoad instance.
2431   * <p>
2432   * Note alternatively you can use {@link #setPostLoaders(List)} to set
2433   * all the BeanPostLoad instances.
2434   */
2435  public void add(BeanPostLoad postLoad) {
2436    postLoaders.add(postLoad);
2437  }
2438
2439  /**
2440   * Register a BeanPostConstructListener instance.
2441   * <p>
2442   * Note alternatively you can use {@link #setPostConstructListeners(List)} to set
2443   * all the BeanPostConstructListener instances.
2444   */
2445  public void add(BeanPostConstructListener listener) {
2446    postConstructListeners.add(listener);
2447  }
2448
2449  /**
2450   * Return the list of BeanFindController instances.
2451   */
2452  public List<BeanFindController> getFindControllers() {
2453    return findControllers;
2454  }
2455
2456  /**
2457   * Set the list of BeanFindController instances.
2458   */
2459  public void setFindControllers(List<BeanFindController> findControllers) {
2460    this.findControllers = findControllers;
2461  }
2462
2463  /**
2464   * Return the list of BeanPostLoader instances.
2465   */
2466  public List<BeanPostLoad> getPostLoaders() {
2467    return postLoaders;
2468  }
2469
2470  /**
2471   * Set the list of BeanPostLoader instances.
2472   */
2473  public void setPostLoaders(List<BeanPostLoad> postLoaders) {
2474    this.postLoaders = postLoaders;
2475  }
2476
2477  /**
2478   * Return the list of BeanPostLoader instances.
2479   */
2480  public List<BeanPostConstructListener> getPostConstructListeners() {
2481    return postConstructListeners;
2482  }
2483
2484  /**
2485   * Set the list of BeanPostLoader instances.
2486   */
2487  public void setPostConstructListeners(List<BeanPostConstructListener> listeners) {
2488    this.postConstructListeners = listeners;
2489  }
2490
2491  /**
2492   * Return the BeanPersistController instances.
2493   */
2494  public List<BeanPersistController> getPersistControllers() {
2495    return persistControllers;
2496  }
2497
2498  /**
2499   * Register all the BeanPersistController instances.
2500   * <p>
2501   * Note alternatively you can use {@link #add(BeanPersistController)} to add
2502   * BeanPersistController instances one at a time.
2503   */
2504  public void setPersistControllers(List<BeanPersistController> persistControllers) {
2505    this.persistControllers = persistControllers;
2506  }
2507
2508  /**
2509   * Register a BeanPersistListener instance.
2510   * <p>
2511   * Note alternatively you can use {@link #setPersistListeners(List)} to set
2512   * all the BeanPersistListener instances.
2513   */
2514  public void add(BeanPersistListener beanPersistListener) {
2515    persistListeners.add(beanPersistListener);
2516  }
2517
2518  /**
2519   * Return the BeanPersistListener instances.
2520   */
2521  public List<BeanPersistListener> getPersistListeners() {
2522    return persistListeners;
2523  }
2524
2525  /**
2526   * Add a BulkTableEventListener
2527   */
2528  public void add(BulkTableEventListener bulkTableEventListener) {
2529    bulkTableEventListeners.add(bulkTableEventListener);
2530  }
2531
2532  /**
2533   * Return the list of BulkTableEventListener instances.
2534   */
2535  public List<BulkTableEventListener> getBulkTableEventListeners() {
2536    return bulkTableEventListeners;
2537  }
2538
2539  /**
2540   * Add a ServerConfigStartup.
2541   */
2542  public void addServerConfigStartup(ServerConfigStartup configStartupListener) {
2543    configStartupListeners.add(configStartupListener);
2544  }
2545
2546  /**
2547   * Return the list of ServerConfigStartup instances.
2548   */
2549  public List<ServerConfigStartup> getServerConfigStartupListeners() {
2550    return configStartupListeners;
2551  }
2552
2553  /**
2554   * Register all the BeanPersistListener instances.
2555   * <p>
2556   * Note alternatively you can use {@link #add(BeanPersistListener)} to add
2557   * BeanPersistListener instances one at a time.
2558   */
2559  public void setPersistListeners(List<BeanPersistListener> persistListeners) {
2560    this.persistListeners = persistListeners;
2561  }
2562
2563  /**
2564   * Return the default PersistenceContextScope to be used if one is not explicitly set on a query.
2565   * <p/>
2566   * The PersistenceContextScope can specified on each query via {@link io.ebean
2567   * .Query#setPersistenceContextScope(io.ebean.PersistenceContextScope)}. If it
2568   * is not set on the query this default scope is used.
2569   *
2570   * @see Query#setPersistenceContextScope(PersistenceContextScope)
2571   */
2572  public PersistenceContextScope getPersistenceContextScope() {
2573    // if somehow null return TRANSACTION scope
2574    return persistenceContextScope == null ? PersistenceContextScope.TRANSACTION : persistenceContextScope;
2575  }
2576
2577  /**
2578   * Set the PersistenceContext scope to be used if one is not explicitly set on a query.
2579   * <p/>
2580   * This defaults to {@link PersistenceContextScope#TRANSACTION}.
2581   * <p/>
2582   * The PersistenceContextScope can specified on each query via {@link io.ebean
2583   * .Query#setPersistenceContextScope(io.ebean.PersistenceContextScope)}. If it
2584   * is not set on the query this scope is used.
2585   *
2586   * @see Query#setPersistenceContextScope(PersistenceContextScope)
2587   */
2588  public void setPersistenceContextScope(PersistenceContextScope persistenceContextScope) {
2589    this.persistenceContextScope = persistenceContextScope;
2590  }
2591
2592  /**
2593   * Return the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
2594   * create new instances of plugins given a className.
2595   */
2596  public ClassLoadConfig getClassLoadConfig() {
2597    return classLoadConfig;
2598  }
2599
2600  /**
2601   * Set the ClassLoadConfig which is used to detect Joda, Java8 types etc and also
2602   * create new instances of plugins given a className.
2603   */
2604  public void setClassLoadConfig(ClassLoadConfig classLoadConfig) {
2605    this.classLoadConfig = classLoadConfig;
2606  }
2607
2608  /**
2609   * Return the service loader using the classLoader defined in ClassLoadConfig.
2610   */
2611  public <T> ServiceLoader<T> serviceLoad(Class<T> spiService) {
2612    return ServiceLoader.load(spiService, classLoadConfig.getClassLoader());
2613  }
2614
2615  /**
2616   * Return the first service using the service loader (or null).
2617   */
2618  public <T> T service(Class<T> spiService) {
2619    ServiceLoader<T> load = serviceLoad(spiService);
2620    Iterator<T> serviceInstances = load.iterator();
2621    return serviceInstances.hasNext() ? serviceInstances.next() : null;
2622  }
2623
2624  /**
2625   * Load settings from ebean.properties.
2626   */
2627  public void loadFromProperties() {
2628    this.properties = Config.asProperties();
2629    configureFromProperties();
2630  }
2631
2632  /**
2633   * Load the settings from the given properties
2634   */
2635  public void loadFromProperties(Properties properties) {
2636    // keep the properties used for configuration so that these are available for plugins
2637    this.properties = Config.asConfiguration().eval(properties);
2638    configureFromProperties();
2639  }
2640
2641  /**
2642   * Load the settings from the given properties
2643   */
2644  private void configureFromProperties() {
2645    List<AutoConfigure> autoConfigures = autoConfiguration();
2646    loadSettings(new PropertiesWrapper("ebean", name, properties, classLoadConfig));
2647    for (AutoConfigure autoConfigure : autoConfigures) {
2648      autoConfigure.postConfigure(this);
2649    }
2650  }
2651
2652  /**
2653   * Use a 'plugin' to provide automatic configuration. Intended for automatic testing
2654   * configuration with Docker containers via ebean-test-config.
2655   */
2656  private List<AutoConfigure> autoConfiguration() {
2657    List<AutoConfigure> list = new ArrayList<>();
2658    for (AutoConfigure autoConfigure : serviceLoad(AutoConfigure.class)) {
2659      autoConfigure.preConfigure(this);
2660      list.add(autoConfigure);
2661    }
2662    return list;
2663  }
2664
2665  /**
2666   * Return the properties that we used for configuration and were set via a call to loadFromProperties().
2667   */
2668  public Properties getProperties() {
2669    return properties;
2670  }
2671
2672  /**
2673   * loads the data source settings to preserve existing behaviour. IMHO, if someone has set the datasource config already,
2674   * they don't want the settings to be reloaded and reset. This allows a descending class to override this behaviour and prevent it
2675   * from happening.
2676   *
2677   * @param p - The defined property source passed to load settings
2678   */
2679  protected void loadDataSourceSettings(PropertiesWrapper p) {
2680    dataSourceConfig.loadSettings(p.properties, name);
2681    readOnlyDataSourceConfig.loadSettings(p.properties, name + "-ro");
2682  }
2683
2684  /**
2685   * This is broken out to allow overridden behaviour.
2686   */
2687  protected void loadDocStoreSettings(PropertiesWrapper p) {
2688    docStoreConfig.loadSettings(p);
2689  }
2690
2691  /**
2692   * This is broken out to allow overridden behaviour.
2693   */
2694  protected void loadAutoTuneSettings(PropertiesWrapper p) {
2695    autoTuneConfig.loadSettings(p);
2696  }
2697
2698  /**
2699   * Load the configuration settings from the properties file.
2700   */
2701  protected void loadSettings(PropertiesWrapper p) {
2702
2703    dbSchema = p.get("dbSchema", dbSchema);
2704    if (dbSchema != null) {
2705      migrationConfig.setDefaultDbSchema(dbSchema);
2706    }
2707    profilingConfig.loadSettings(p, name);
2708    migrationConfig.loadSettings(p, name);
2709    platformConfig.loadSettings(p);
2710    if (platformConfig.isAllQuotedIdentifiers()) {
2711      adjustNamingConventionForAllQuoted();
2712    }
2713    namingConvention = createNamingConvention(p, namingConvention);
2714    if (namingConvention != null) {
2715      namingConvention.loadFromProperties(p);
2716    }
2717    if (autoTuneConfig == null) {
2718      autoTuneConfig = new AutoTuneConfig();
2719    }
2720    loadAutoTuneSettings(p);
2721
2722    if (dataSourceConfig == null) {
2723      dataSourceConfig = new DataSourceConfig();
2724    }
2725    loadDataSourceSettings(p);
2726
2727    if (docStoreConfig == null) {
2728      docStoreConfig = new DocStoreConfig();
2729    }
2730    loadDocStoreSettings(p);
2731
2732    loadModuleInfo = p.getBoolean("loadModuleInfo", loadModuleInfo);
2733    maxCallStack = p.getInt("maxCallStack", maxCallStack);
2734    dumpMetricsOnShutdown = p.getBoolean("dumpMetricsOnShutdown", dumpMetricsOnShutdown);
2735    dumpMetricsOptions = p.get("dumpMetricsOptions", dumpMetricsOptions);
2736    queryPlanTTLSeconds = p.getInt("queryPlanTTLSeconds", queryPlanTTLSeconds);
2737    slowQueryMillis = p.getLong("slowQueryMillis", slowQueryMillis);
2738    collectQueryPlans = p.getBoolean("collectQueryPlans", collectQueryPlans);
2739    collectQueryPlanThresholdMicros = p.getLong("collectQueryPlanThresholdMicros", collectQueryPlanThresholdMicros);
2740    docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
2741    disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
2742    localOnlyL2Cache = p.getBoolean("localOnlyL2Cache", localOnlyL2Cache);
2743    enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
2744    notifyL2CacheInForeground = p.getBoolean("notifyL2CacheInForeground", notifyL2CacheInForeground);
2745    useJtaTransactionManager = p.getBoolean("useJtaTransactionManager", useJtaTransactionManager);
2746    useJavaxValidationNotNull = p.getBoolean("useJavaxValidationNotNull", useJavaxValidationNotNull);
2747    autoReadOnlyDataSource = p.getBoolean("autoReadOnlyDataSource", autoReadOnlyDataSource);
2748    idGeneratorAutomatic = p.getBoolean("idGeneratorAutomatic", idGeneratorAutomatic);
2749
2750    backgroundExecutorSchedulePoolSize = p.getInt("backgroundExecutorSchedulePoolSize", backgroundExecutorSchedulePoolSize);
2751    backgroundExecutorShutdownSecs = p.getInt("backgroundExecutorShutdownSecs", backgroundExecutorShutdownSecs);
2752    disableClasspathSearch = p.getBoolean("disableClasspathSearch", disableClasspathSearch);
2753    currentUserProvider = p.createInstance(CurrentUserProvider.class, "currentUserProvider", currentUserProvider);
2754    databasePlatform = p.createInstance(DatabasePlatform.class, "databasePlatform", databasePlatform);
2755    encryptKeyManager = p.createInstance(EncryptKeyManager.class, "encryptKeyManager", encryptKeyManager);
2756    encryptDeployManager = p.createInstance(EncryptDeployManager.class, "encryptDeployManager", encryptDeployManager);
2757    encryptor = p.createInstance(Encryptor.class, "encryptor", encryptor);
2758    dbEncrypt = p.createInstance(DbEncrypt.class, "dbEncrypt", dbEncrypt);
2759    dbOffline = p.getBoolean("dbOffline", dbOffline);
2760    serverCachePlugin = p.createInstance(ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
2761
2762    String packagesProp = p.get("search.packages", p.get("packages", null));
2763    packages = getSearchList(packagesProp, packages);
2764
2765    skipCacheAfterWrite = p.getBoolean("skipCacheAfterWrite", skipCacheAfterWrite);
2766    updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
2767
2768    if (p.get("batch.mode") != null || p.get("persistBatching") != null) {
2769      throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'");
2770    }
2771
2772    persistBatch = p.getEnum(PersistBatch.class, "persistBatch", persistBatch);
2773    persistBatchOnCascade = p.getEnum(PersistBatch.class, "persistBatchOnCascade", persistBatchOnCascade);
2774
2775    int batchSize = p.getInt("batch.size", persistBatchSize);
2776    persistBatchSize = p.getInt("persistBatchSize", batchSize);
2777
2778    persistenceContextScope = PersistenceContextScope.valueOf(p.get("persistenceContextScope", "TRANSACTION"));
2779
2780    changeLogAsync = p.getBoolean("changeLogAsync", changeLogAsync);
2781    changeLogIncludeInserts = p.getBoolean("changeLogIncludeInserts", changeLogIncludeInserts);
2782    expressionEqualsWithNullAsNoop = p.getBoolean("expressionEqualsWithNullAsNoop", expressionEqualsWithNullAsNoop);
2783    expressionNativeIlike = p.getBoolean("expressionNativeIlike", expressionNativeIlike);
2784
2785    dataTimeZone = p.get("dataTimeZone", dataTimeZone);
2786    asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
2787    asOfSysPeriod = p.get("asOfSysPeriod", asOfSysPeriod);
2788    historyTableSuffix = p.get("historyTableSuffix", historyTableSuffix);
2789    dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName);
2790    jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
2791    jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
2792    databasePlatformName = p.get("databasePlatformName", databasePlatformName);
2793    defaultOrderById = p.getBoolean("defaultOrderById", defaultOrderById);
2794
2795    uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
2796    uuidStateFile = p.get("uuidStateFile", uuidStateFile);
2797
2798    localTimeWithNanos = p.getBoolean("localTimeWithNanos", localTimeWithNanos);
2799    jodaLocalTimeMode = p.get("jodaLocalTimeMode", jodaLocalTimeMode);
2800
2801    defaultEnumType = p.getEnum(EnumType.class, "defaultEnumType", defaultEnumType);
2802    disableLazyLoading = p.getBoolean("disableLazyLoading", disableLazyLoading);
2803    lazyLoadBatchSize = p.getInt("lazyLoadBatchSize", lazyLoadBatchSize);
2804    queryBatchSize = p.getInt("queryBatchSize", queryBatchSize);
2805
2806    jsonInclude = p.getEnum(JsonConfig.Include.class, "jsonInclude", jsonInclude);
2807    jsonDateTime = p.getEnum(JsonConfig.DateTime.class, "jsonDateTime", jsonDateTime);
2808    jsonDate = p.getEnum(JsonConfig.Date.class, "jsonDate", jsonDate);
2809
2810    ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
2811    ddlRun = p.getBoolean("ddl.run", ddlRun);
2812    ddlExtra = p.getBoolean("ddl.extra", ddlExtra);
2813    ddlCreateOnly = p.getBoolean("ddl.createOnly", ddlCreateOnly);
2814    ddlInitSql = p.get("ddl.initSql", ddlInitSql);
2815    ddlSeedSql = p.get("ddl.seedSql", ddlSeedSql);
2816
2817    // read tenant-configuration from config:
2818    // tenant.mode = NONE | DB | SCHEMA | CATALOG | PARTITION
2819    String mode = p.get("tenant.mode");
2820    if (mode != null) {
2821      for (TenantMode value : TenantMode.values()) {
2822        if (value.name().equalsIgnoreCase(mode)) {
2823          tenantMode = value;
2824          break;
2825        }
2826      }
2827    }
2828
2829    currentTenantProvider = p.createInstance(CurrentTenantProvider.class, "tenant.currentTenantProvider", currentTenantProvider);
2830    tenantCatalogProvider = p.createInstance(TenantCatalogProvider.class, "tenant.catalogProvider", tenantCatalogProvider);
2831    tenantSchemaProvider = p.createInstance(TenantSchemaProvider.class, "tenant.schemaProvider", tenantSchemaProvider);
2832    tenantPartitionColumn = p.get("tenant.partitionColumn", tenantPartitionColumn);
2833    classes = getClasses(p);
2834
2835    String mappingsProp = p.get("mappingLocations", null);
2836    mappingLocations = getSearchList(mappingsProp, mappingLocations);
2837  }
2838
2839  private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) {
2840    NamingConvention nc = properties.createInstance(NamingConvention.class, "namingConvention", null);
2841    return (nc != null) ? nc : namingConvention;
2842  }
2843
2844  /**
2845   * Build the list of classes from the comma delimited string.
2846   *
2847   * @param properties the properties
2848   * @return the classes
2849   */
2850  private List<Class<?>> getClasses(PropertiesWrapper properties) {
2851    String classNames = properties.get("classes", null);
2852    if (classNames == null) {
2853      return classes;
2854    }
2855
2856    List<Class<?>> classList = new ArrayList<>();
2857    String[] split = StringHelper.splitNames(classNames);
2858    for (String cn : split) {
2859      if (!"class".equalsIgnoreCase(cn)) {
2860        try {
2861          classList.add(Class.forName(cn));
2862        } catch (ClassNotFoundException e) {
2863          String msg = "Error registering class [" + cn + "] from [" + classNames + "]";
2864          throw new RuntimeException(msg, e);
2865        }
2866      }
2867    }
2868    return classList;
2869  }
2870
2871  private List<String> getSearchList(String searchNames, List<String> defaultValue) {
2872    if (searchNames != null) {
2873      String[] entries = StringHelper.splitNames(searchNames);
2874      List<String> hitList = new ArrayList<>(entries.length);
2875      Collections.addAll(hitList, entries);
2876      return hitList;
2877    } else {
2878      return defaultValue;
2879    }
2880  }
2881
2882  /**
2883   * Return the PersistBatch mode to use for 'batchOnCascade' taking into account if the database
2884   * platform supports getGeneratedKeys in batch mode.
2885   */
2886  public PersistBatch appliedPersistBatchOnCascade() {
2887    if (persistBatchOnCascade == PersistBatch.INHERIT) {
2888      // use the platform default (ALL except SQL Server which has NONE)
2889      return databasePlatform.getPersistBatchOnCascade();
2890    }
2891    return persistBatchOnCascade;
2892  }
2893
2894  /**
2895   * Return the Jackson ObjectMapper.
2896   * <p>
2897   * Note that this is not strongly typed as Jackson ObjectMapper is an optional dependency.
2898   */
2899  public Object getObjectMapper() {
2900    return objectMapper;
2901  }
2902
2903  /**
2904   * Set the Jackson ObjectMapper.
2905   * <p>
2906   * Note that this is not strongly typed as Jackson ObjectMapper is an optional dependency.
2907   */
2908  public void setObjectMapper(Object objectMapper) {
2909    this.objectMapper = objectMapper;
2910  }
2911
2912  /**
2913   * Return true if eq("someProperty", null) should to generate "1=1" rather than "is null" sql expression.
2914   */
2915  public boolean isExpressionEqualsWithNullAsNoop() {
2916    return expressionEqualsWithNullAsNoop;
2917  }
2918
2919  /**
2920   * Set to true if you want eq("someProperty", null) to generate "1=1" rather than "is null" sql expression.
2921   * <p>
2922   * Setting this to true has the effect that eq(propertyName, value), ieq(propertyName, value) and
2923   * ne(propertyName, value) have no effect when the value is null. The expression factory adds a NoopExpression
2924   * which will add "1=1" into the SQL rather than "is null".
2925   */
2926  public void setExpressionEqualsWithNullAsNoop(boolean expressionEqualsWithNullAsNoop) {
2927    this.expressionEqualsWithNullAsNoop = expressionEqualsWithNullAsNoop;
2928  }
2929
2930  /**
2931   * Return true if native ILIKE expression should be used if supported by the database platform (e.g. Postgres).
2932   */
2933  public boolean isExpressionNativeIlike() {
2934    return expressionNativeIlike;
2935  }
2936
2937  /**
2938   * Set to true to use native ILIKE expression if supported by the database platform (e.g. Postgres).
2939   */
2940  public void setExpressionNativeIlike(boolean expressionNativeIlike) {
2941    this.expressionNativeIlike = expressionNativeIlike;
2942  }
2943
2944  /**
2945   * Return the enabled L2 cache regions.
2946   */
2947  public String getEnabledL2Regions() {
2948    return enabledL2Regions;
2949  }
2950
2951  /**
2952   * Set the enabled L2 cache regions (comma delimited).
2953   */
2954  public void setEnabledL2Regions(String enabledL2Regions) {
2955    this.enabledL2Regions = enabledL2Regions;
2956  }
2957
2958  /**
2959   * Return true if L2 cache is disabled.
2960   */
2961  public boolean isDisableL2Cache() {
2962    return disableL2Cache;
2963  }
2964
2965  /**
2966   * Set to true to disable L2 caching. Typically useful in performance testing.
2967   */
2968  public void setDisableL2Cache(boolean disableL2Cache) {
2969    this.disableL2Cache = disableL2Cache;
2970  }
2971
2972  /**
2973   * Return true to use local only L2 cache. Effectively ignore l2 cache plugin like ebean-redis etc.
2974   */
2975  public boolean isLocalOnlyL2Cache() {
2976    return localOnlyL2Cache;
2977  }
2978
2979  /**
2980   * Force the use of local only L2 cache. Effectively ignore l2 cache plugin like ebean-redis etc.
2981   */
2982  public void setLocalOnlyL2Cache(boolean localOnlyL2Cache) {
2983    this.localOnlyL2Cache = localOnlyL2Cache;
2984  }
2985
2986  /**
2987   * Returns if we use javax.validation.constraints.NotNull
2988   */
2989  public boolean isUseJavaxValidationNotNull() {
2990    return useJavaxValidationNotNull;
2991  }
2992
2993  /**
2994   * Controls if Ebean should ignore <code>&x64;javax.validation.contstraints.NotNull</code>
2995   * with respect to generating a <code>NOT NULL</code> column.
2996   * <p>
2997   * Normally when Ebean sees javax NotNull annotation it means that column is defined as NOT NULL.
2998   * Set this to <code>false</code> and the javax NotNull annotation is effectively ignored (and
2999   * we instead use Ebean's own NotNull annotation or JPA Column(nullable=false) annotation.
3000   */
3001  public void setUseJavaxValidationNotNull(boolean useJavaxValidationNotNull) {
3002    this.useJavaxValidationNotNull = useJavaxValidationNotNull;
3003  }
3004
3005  /**
3006   * Return true if L2 cache notification should run in the foreground.
3007   */
3008  public boolean isNotifyL2CacheInForeground() {
3009    return notifyL2CacheInForeground;
3010  }
3011
3012  /**
3013   * Set this to true to run L2 cache notification in the foreground.
3014   * <p>
3015   * In general we don't want to do that as when we use a distributed cache (like Ignite, Hazelcast etc)
3016   * we are making network calls and we prefer to do this in background and not impact the response time
3017   * of the executing transaction.
3018   */
3019  public void setNotifyL2CacheInForeground(boolean notifyL2CacheInForeground) {
3020    this.notifyL2CacheInForeground = notifyL2CacheInForeground;
3021  }
3022
3023  /**
3024   * Return the query plan time to live.
3025   */
3026  public int getQueryPlanTTLSeconds() {
3027    return queryPlanTTLSeconds;
3028  }
3029
3030  /**
3031   * Set the query plan time to live.
3032   */
3033  public void setQueryPlanTTLSeconds(int queryPlanTTLSeconds) {
3034    this.queryPlanTTLSeconds = queryPlanTTLSeconds;
3035  }
3036
3037  /**
3038   * Run the DB migration against the DataSource.
3039   */
3040  public DataSource runDbMigration(DataSource dataSource) {
3041    if (migrationConfig.isRunMigration()) {
3042      MigrationRunner runner = migrationConfig.createRunner(getClassLoadConfig().getClassLoader(), properties);
3043      runner.run(dataSource);
3044    }
3045    return dataSource;
3046  }
3047
3048  /**
3049   * Create a new PlatformConfig based of the one held but with overridden properties by reading
3050   * properties with the given path and prefix.
3051   * <p>
3052   * Typically used in Db Migration generation for many platform targets that might have different
3053   * configuration for IdType, UUID, quoted identifiers etc.
3054   *
3055   * @param propertiesPath The properties path used for loading and setting properties
3056   * @param platformPrefix The prefix used for loading and setting properties
3057   * @return A copy of the PlatformConfig with overridden properties
3058   */
3059  public PlatformConfig newPlatformConfig(String propertiesPath, String platformPrefix) {
3060    if (properties == null) {
3061      properties = new Properties();
3062    }
3063    PropertiesWrapper p = new PropertiesWrapper(propertiesPath, platformPrefix, properties, classLoadConfig);
3064    PlatformConfig config = new PlatformConfig(platformConfig);
3065    config.loadSettings(p);
3066    return config;
3067  }
3068
3069  /**
3070   * Add a mapping location to search for xml mapping via class path search.
3071   */
3072  public void addMappingLocation(String mappingLocation) {
3073    if (mappingLocations == null) {
3074      mappingLocations = new ArrayList<>();
3075    }
3076    mappingLocations.add(mappingLocation);
3077  }
3078
3079  /**
3080   * Return mapping locations to search for xml mapping via class path search.
3081   */
3082  public List<String> getMappingLocations() {
3083    return mappingLocations;
3084  }
3085
3086  /**
3087   * Set mapping locations to search for xml mapping via class path search.
3088   * <p>
3089   * This is only used if classes have not been explicitly specified.
3090   */
3091  public void setMappingLocations(List<String> mappingLocations) {
3092    this.mappingLocations = mappingLocations;
3093  }
3094
3095  /**
3096   * When false we need explicit <code>@GeneratedValue</code> mapping to assign
3097   * Identity or Sequence generated values. When true Id properties are automatically
3098   * assigned Identity or Sequence without the GeneratedValue mapping.
3099   */
3100  public boolean isIdGeneratorAutomatic() {
3101    return idGeneratorAutomatic;
3102  }
3103
3104  /**
3105   * Set to false such that Id properties require explicit <code>@GeneratedValue</code>
3106   * mapping before they are assigned Identity or Sequence generation based on platform.
3107   */
3108  public void setIdGeneratorAutomatic(boolean idGeneratorAutomatic) {
3109    this.idGeneratorAutomatic = idGeneratorAutomatic;
3110  }
3111
3112  /**
3113   * Return true if query plan capture is enabled.
3114   */
3115  public boolean isCollectQueryPlans() {
3116    return collectQueryPlans;
3117  }
3118
3119  /**
3120   * Set to true to enable query plan capture.
3121   */
3122  public void setCollectQueryPlans(boolean collectQueryPlans) {
3123    this.collectQueryPlans = collectQueryPlans;
3124  }
3125
3126  /**
3127   * Return the query plan collection threshold in microseconds.
3128   */
3129  public long getCollectQueryPlanThresholdMicros() {
3130    return collectQueryPlanThresholdMicros;
3131  }
3132
3133  /**
3134   * Set the query plan collection threshold in microseconds.
3135   */
3136  public void setCollectQueryPlanThresholdMicros(long collectQueryPlanThresholdMicros) {
3137    this.collectQueryPlanThresholdMicros = collectQueryPlanThresholdMicros;
3138  }
3139
3140  /**
3141   * Return true if metrics should be dumped when the server is shutdown.
3142   */
3143  public boolean isDumpMetricsOnShutdown() {
3144    return dumpMetricsOnShutdown;
3145  }
3146
3147  /**
3148   * Set to true if metrics should be dumped when the server is shutdown.
3149   */
3150  public void setDumpMetricsOnShutdown(boolean dumpMetricsOnShutdown) {
3151    this.dumpMetricsOnShutdown = dumpMetricsOnShutdown;
3152  }
3153
3154  /**
3155   * Return the options for dumping metrics.
3156   */
3157  public String getDumpMetricsOptions() {
3158    return dumpMetricsOptions;
3159  }
3160
3161  /**
3162   * Include 'sql' or 'hash' in options such that they are included in the output.
3163   *
3164   * @param dumpMetricsOptions Example "sql,hash", "sql"
3165   */
3166  public void setDumpMetricsOptions(String dumpMetricsOptions) {
3167    this.dumpMetricsOptions = dumpMetricsOptions;
3168  }
3169
3170  /**
3171   * Return true if entity classes should be loaded and registered via ModuleInfoLoader.
3172   * <p>
3173   * When false we either register entity classes via application code or use classpath
3174   * scanning to find and register entity classes.
3175   */
3176  public boolean isAutoLoadModuleInfo() {
3177    return loadModuleInfo && classes.isEmpty();
3178  }
3179
3180  /**
3181   * Set false to turn off automatic registration of entity beans.
3182   * <p>
3183   * When using query beans that also generates a module info class that
3184   * can register the entity bean classes (to avoid classpath scanning).
3185   * This is on by default and setting this to false turns it off.
3186   */
3187  public void setLoadModuleInfo(boolean loadModuleInfo) {
3188    this.loadModuleInfo = loadModuleInfo;
3189  }
3190
3191  public enum UuidVersion {
3192    VERSION4,
3193    VERSION1,
3194    VERSION1RND
3195  }
3196}