diff --git a/src/main/java/com/avaje/ebean/config/CompoundType.java b/src/main/java/com/avaje/ebean/config/CompoundType.java index 90b2cb716..59e704a40 100644 --- a/src/main/java/com/avaje/ebean/config/CompoundType.java +++ b/src/main/java/com/avaje/ebean/config/CompoundType.java @@ -1,46 +1,46 @@ -package com.avaje.ebean.config; - -/** - * API from creating and getting property values from an Immutable Compound - * Value Object. - * - *

- * A Compound Value object should contain multiple properties that are stored - * separately. If you only have a single scalar value you should instead look to - * use {@link ScalarTypeConverter}. - *

- *

- * For each property in the compound type you need to implement the - * {@link CompoundTypeProperty} interface. These must be returned from - * {@link #getProperties()} in the same order that the properties appear in the - * constructor. - *

- *

- * If your compound type is mutable then you should look to use the JPA Embedded - * annotation instead of implementing this interface. - *

- *

- * When using classpath search Ebean will detect and automatically register any - * implementations of this interface (along with detecting the entity classes - * etc). - *

- * - * @author rbygrave - * - * @param - * The type of the Value Object - * - * @see ScalarTypeConverter - */ -public interface CompoundType { - - /** - * Create an instance of the compound type given its property values. - */ - V create(Object[] propertyValues); - - /** - * Return the properties in the order they appear in the constructor. - */ - CompoundTypeProperty[] getProperties(); -} +package com.avaje.ebean.config; + +/** + * API from creating and getting property values from an Immutable Compound + * Value Object. + * + *

+ * A Compound Value object should contain multiple properties that are stored + * separately. If you only have a single scalar value you should instead look to + * use {@link ScalarTypeConverter}. + *

+ *

+ * For each property in the compound type you need to implement the + * {@link CompoundTypeProperty} interface. These must be returned from + * {@link #getProperties()} in the same order that the properties appear in the + * constructor. + *

+ *

+ * If your compound type is mutable then you should look to use the JPA Embedded + * annotation instead of implementing this interface. + *

+ *

+ * When using classpath search Ebean will detect and automatically register any + * implementations of this interface (along with detecting the entity classes + * etc). + *

+ * + * @author rbygrave + * + * @param + * The type of the Value Object + * + * @see ScalarTypeConverter + */ +public interface CompoundType { + + /** + * Create an instance of the compound type given its property values. + */ + V create(Object[] propertyValues); + + /** + * Return the properties in the order they appear in the constructor. + */ + CompoundTypeProperty[] getProperties(); +} diff --git a/src/main/java/com/avaje/ebean/config/CompoundTypeProperty.java b/src/main/java/com/avaje/ebean/config/CompoundTypeProperty.java index 83823d664..30075b328 100644 --- a/src/main/java/com/avaje/ebean/config/CompoundTypeProperty.java +++ b/src/main/java/com/avaje/ebean/config/CompoundTypeProperty.java @@ -1,51 +1,51 @@ -package com.avaje.ebean.config; - -/** - * Represents a Property of a Compound Value Object. - *

- * For each property in a {@link CompoundType} you need an implementation of - * this CompoundTypeProperty interface. - * - *

- * - * @author rbygrave - * - * @param - * The type of the Compound value object - * @param

- * The type of the property - * - * @see CompoundType - * @see ScalarTypeConverter - */ -public interface CompoundTypeProperty { - - /** - * The name of this property. - */ - String getName(); - - /** - * Return the property value from the containing compound value object. - * - * @param valueObject - * the compound value object - * @return the property value. - */ - P getValue(V valueObject); - - /** - * This should ONLY be used when the persistence type is different from - * the logical type returned. It most cases just return 0 and Ebean will - * persist the logical type. - *

- * Typically this should be used when the logical type is long but the - * persistence type is java.sql.Timestamp. In this case return - * java.sql.Types.TIMESTAMP (rather than 0). - *

- * - * @return Return the java.sql.Type that you want to use to persist this - * property or 0 and Ebean will use the logical type. - */ - int getDbType(); -} +package com.avaje.ebean.config; + +/** + * Represents a Property of a Compound Value Object. + *

+ * For each property in a {@link CompoundType} you need an implementation of + * this CompoundTypeProperty interface. + * + *

+ * + * @author rbygrave + * + * @param + * The type of the Compound value object + * @param

+ * The type of the property + * + * @see CompoundType + * @see ScalarTypeConverter + */ +public interface CompoundTypeProperty { + + /** + * The name of this property. + */ + String getName(); + + /** + * Return the property value from the containing compound value object. + * + * @param valueObject + * the compound value object + * @return the property value. + */ + P getValue(V valueObject); + + /** + * This should ONLY be used when the persistence type is different from + * the logical type returned. It most cases just return 0 and Ebean will + * persist the logical type. + *

+ * Typically this should be used when the logical type is long but the + * persistence type is java.sql.Timestamp. In this case return + * java.sql.Types.TIMESTAMP (rather than 0). + *

+ * + * @return Return the java.sql.Type that you want to use to persist this + * property or 0 and Ebean will use the logical type. + */ + int getDbType(); +} diff --git a/src/main/java/com/avaje/ebean/config/EncryptDeploy.java b/src/main/java/com/avaje/ebean/config/EncryptDeploy.java index d87d0c5fe..f19dc4d14 100644 --- a/src/main/java/com/avaje/ebean/config/EncryptDeploy.java +++ b/src/main/java/com/avaje/ebean/config/EncryptDeploy.java @@ -1,111 +1,111 @@ -package com.avaje.ebean.config; - -/** - * Define the encryption options for a bean property. - *

- * You can define the encryption options for a Bean property via the Encrypt - * annotation and programmatically via {@link EncryptDeployManager}. - *

- * - * @author rbygrave - * - * @see EncryptDeployManager#getEncryptDeploy(TableName, String) - */ -public class EncryptDeploy { - - /** - * Use to define that no encryption should be used. - */ - public static final EncryptDeploy NO_ENCRYPT = new EncryptDeploy(Mode.MODE_NO_ENCRYPT, true, 0); - - /** - * Use to define that the Encrypt annotation should be used to control - * encryption. - */ - public static final EncryptDeploy ANNOTATION = new EncryptDeploy(Mode.MODE_ANNOTATION, true, 0); - - /** - * Use to define that Encryption should be used and String types should use DB - * encryption. - */ - public static final EncryptDeploy ENCRYPT_DB = new EncryptDeploy(Mode.MODE_ENCRYPT, true, 0); - - /** - * Use to define that Java client Encryption should be used (rather than DB - * encryption). - */ - public static final EncryptDeploy ENCRYPT_CLIENT = new EncryptDeploy(Mode.MODE_ENCRYPT, false, 0); - - /** - * The Encryption mode. - */ - public enum Mode { - /** - * Encrypt the property using DB encryption or Java client encryption - * depending on the type and dbEncryption flag. - */ - MODE_ENCRYPT, - - /** - * No encryption is used, even if there is an Encryption annotation on the - * property. - */ - MODE_NO_ENCRYPT, - - /** - * Use encryption options defined by the Encryption annotation on the - * property. If no annotation is on the property it is not encrypted. - */ - MODE_ANNOTATION - } - - private final Mode mode; - - private final boolean dbEncrypt; - - private final int dbLength; - - /** - * Construct with all options for Encryption including the dbLength. - * - * @param mode - * the Encryption mode - * @param dbEncrypt - * set to false if you want to use Java client side encryption rather - * than DB encryption. - * @param dbLength - * set the DB length to use. - */ - public EncryptDeploy(Mode mode, boolean dbEncrypt, int dbLength) { - this.mode = mode; - this.dbEncrypt = dbEncrypt; - this.dbLength = dbLength; - } - - /** - * Return the encryption mode. - */ - public Mode getMode() { - return mode; - } - - /** - * Return true if String type should use DB encryption. - *

- * Return false if String type should use java client encryption instead. - *

- */ - public boolean isDbEncrypt() { - return dbEncrypt; - } - - /** - * Return a hint to specify the DB length. - *

- * Returning 0 means just use the normal DB length determination. - *

- */ - public int getDbLength() { - return dbLength; - } -} +package com.avaje.ebean.config; + +/** + * Define the encryption options for a bean property. + *

+ * You can define the encryption options for a Bean property via the Encrypt + * annotation and programmatically via {@link EncryptDeployManager}. + *

+ * + * @author rbygrave + * + * @see EncryptDeployManager#getEncryptDeploy(TableName, String) + */ +public class EncryptDeploy { + + /** + * Use to define that no encryption should be used. + */ + public static final EncryptDeploy NO_ENCRYPT = new EncryptDeploy(Mode.MODE_NO_ENCRYPT, true, 0); + + /** + * Use to define that the Encrypt annotation should be used to control + * encryption. + */ + public static final EncryptDeploy ANNOTATION = new EncryptDeploy(Mode.MODE_ANNOTATION, true, 0); + + /** + * Use to define that Encryption should be used and String types should use DB + * encryption. + */ + public static final EncryptDeploy ENCRYPT_DB = new EncryptDeploy(Mode.MODE_ENCRYPT, true, 0); + + /** + * Use to define that Java client Encryption should be used (rather than DB + * encryption). + */ + public static final EncryptDeploy ENCRYPT_CLIENT = new EncryptDeploy(Mode.MODE_ENCRYPT, false, 0); + + /** + * The Encryption mode. + */ + public enum Mode { + /** + * Encrypt the property using DB encryption or Java client encryption + * depending on the type and dbEncryption flag. + */ + MODE_ENCRYPT, + + /** + * No encryption is used, even if there is an Encryption annotation on the + * property. + */ + MODE_NO_ENCRYPT, + + /** + * Use encryption options defined by the Encryption annotation on the + * property. If no annotation is on the property it is not encrypted. + */ + MODE_ANNOTATION + } + + private final Mode mode; + + private final boolean dbEncrypt; + + private final int dbLength; + + /** + * Construct with all options for Encryption including the dbLength. + * + * @param mode + * the Encryption mode + * @param dbEncrypt + * set to false if you want to use Java client side encryption rather + * than DB encryption. + * @param dbLength + * set the DB length to use. + */ + public EncryptDeploy(Mode mode, boolean dbEncrypt, int dbLength) { + this.mode = mode; + this.dbEncrypt = dbEncrypt; + this.dbLength = dbLength; + } + + /** + * Return the encryption mode. + */ + public Mode getMode() { + return mode; + } + + /** + * Return true if String type should use DB encryption. + *

+ * Return false if String type should use java client encryption instead. + *

+ */ + public boolean isDbEncrypt() { + return dbEncrypt; + } + + /** + * Return a hint to specify the DB length. + *

+ * Returning 0 means just use the normal DB length determination. + *

+ */ + public int getDbLength() { + return dbLength; + } +} diff --git a/src/main/java/com/avaje/ebean/config/EncryptDeployManager.java b/src/main/java/com/avaje/ebean/config/EncryptDeployManager.java index 99d6277f5..dfe800928 100644 --- a/src/main/java/com/avaje/ebean/config/EncryptDeployManager.java +++ b/src/main/java/com/avaje/ebean/config/EncryptDeployManager.java @@ -1,15 +1,15 @@ -package com.avaje.ebean.config; - -/** - * Programmatically define which database columns are encrypted. - * - * @author rbygrave - * - */ -public interface EncryptDeployManager { - - /** - * Return true if the table column is encrypted. - */ - EncryptDeploy getEncryptDeploy(TableName table, String column); -} +package com.avaje.ebean.config; + +/** + * Programmatically define which database columns are encrypted. + * + * @author rbygrave + * + */ +public interface EncryptDeployManager { + + /** + * Return true if the table column is encrypted. + */ + EncryptDeploy getEncryptDeploy(TableName table, String column); +} diff --git a/src/main/java/com/avaje/ebean/config/EncryptKey.java b/src/main/java/com/avaje/ebean/config/EncryptKey.java index 999a95ed6..3318b8387 100644 --- a/src/main/java/com/avaje/ebean/config/EncryptKey.java +++ b/src/main/java/com/avaje/ebean/config/EncryptKey.java @@ -1,18 +1,18 @@ -package com.avaje.ebean.config; - -/** - * Represents the key used for encryption. - *

- * For simple cases this often represent a simple String key but depending on - * the encryption method this could contain other details. - *

- * - * @author rbygrave - */ -public interface EncryptKey { - - /** - * Return the string key value. - */ - String getStringValue(); -} +package com.avaje.ebean.config; + +/** + * Represents the key used for encryption. + *

+ * For simple cases this often represent a simple String key but depending on + * the encryption method this could contain other details. + *

+ * + * @author rbygrave + */ +public interface EncryptKey { + + /** + * Return the string key value. + */ + String getStringValue(); +} diff --git a/src/main/java/com/avaje/ebean/config/EncryptKeyManager.java b/src/main/java/com/avaje/ebean/config/EncryptKeyManager.java index 827b21167..8c785db59 100644 --- a/src/main/java/com/avaje/ebean/config/EncryptKeyManager.java +++ b/src/main/java/com/avaje/ebean/config/EncryptKeyManager.java @@ -1,23 +1,23 @@ -package com.avaje.ebean.config; - -/** - * Determine keys used for encryption and decryption. - * - * @author rbygrave - */ -public interface EncryptKeyManager { - - /** - * Initialise the EncryptKeyManager. - *

- * This gives the EncryptKeyManager the opportunity to get keys etc. - *

- */ - void initialise(); - - /** - * Return the key used to encrypt and decrypt a property mapping to the given - * table and column. - */ - EncryptKey getEncryptKey(String tableName, String columnName); -} +package com.avaje.ebean.config; + +/** + * Determine keys used for encryption and decryption. + * + * @author rbygrave + */ +public interface EncryptKeyManager { + + /** + * Initialise the EncryptKeyManager. + *

+ * This gives the EncryptKeyManager the opportunity to get keys etc. + *

+ */ + void initialise(); + + /** + * Return the key used to encrypt and decrypt a property mapping to the given + * table and column. + */ + EncryptKey getEncryptKey(String tableName, String columnName); +} diff --git a/src/main/java/com/avaje/ebean/config/Encryptor.java b/src/main/java/com/avaje/ebean/config/Encryptor.java index c482e71f9..d2aa540c8 100644 --- a/src/main/java/com/avaje/ebean/config/Encryptor.java +++ b/src/main/java/com/avaje/ebean/config/Encryptor.java @@ -1,34 +1,34 @@ -package com.avaje.ebean.config; - -/** - * Used for Java side encryption of properties when DB encryption is not used. - *

- * By default this is used on non-varchar types such as Blobs. - *

- * - * @author rbygrave - * - */ -public interface Encryptor { - - /** - * Encrypt the data using the key. - */ - byte[] encrypt(byte[] data, EncryptKey key); - - /** - * Decrypt the data using the key. - */ - byte[] decrypt(byte[] data, EncryptKey key); - - /** - * Encrypt the formatted string value using a key. - */ - byte[] encryptString(String formattedValue, EncryptKey key); - - /** - * Decrypt the data returning a formatted string value using a key. - */ - String decryptString(byte[] data, EncryptKey key); - -} +package com.avaje.ebean.config; + +/** + * Used for Java side encryption of properties when DB encryption is not used. + *

+ * By default this is used on non-varchar types such as Blobs. + *

+ * + * @author rbygrave + * + */ +public interface Encryptor { + + /** + * Encrypt the data using the key. + */ + byte[] encrypt(byte[] data, EncryptKey key); + + /** + * Decrypt the data using the key. + */ + byte[] decrypt(byte[] data, EncryptKey key); + + /** + * Encrypt the formatted string value using a key. + */ + byte[] encryptString(String formattedValue, EncryptKey key); + + /** + * Decrypt the data returning a formatted string value using a key. + */ + String decryptString(byte[] data, EncryptKey key); + +} diff --git a/src/main/java/com/avaje/ebean/config/NamingConvention.java b/src/main/java/com/avaje/ebean/config/NamingConvention.java index 34702c5e6..51bef545c 100644 --- a/src/main/java/com/avaje/ebean/config/NamingConvention.java +++ b/src/main/java/com/avaje/ebean/config/NamingConvention.java @@ -1,120 +1,120 @@ -package com.avaje.ebean.config; - -import com.avaje.ebean.config.dbplatform.DatabasePlatform; - -/** - * Defines the naming convention for converting between logical property - * names/entity names and physical DB column names/table names. - *

- * The main goal of the naming convention is to reduce the amount of - * configuration required in the mapping (especially when mapping between column - * and property names). - *

- *

- * Note that if you do not define a NamingConvention the default one will be - * used and you can configure it's behaviour via properties. - *

- */ -public interface NamingConvention { - - /** - * Set the associated DatabasePlaform. - *

- * This is set after the DatabasePlatform has been associated. - *

- *

- * The purpose of this is to enable NamingConvention to be able to support - * database platform specific configuration. - *

- * - * @param databasePlatform - * the database platform - */ - void setDatabasePlatform(DatabasePlatform databasePlatform); - - /** - * Returns the table name for a given Class. - *

- * This method is always called and should take into account @Table - * annotations etc. This means you can choose to override the settings defined - * by @Table if you wish. - *

- * - * @param beanClass - * the bean class - * - * @return the table name for the entity class - */ - TableName getTableName(Class beanClass); - - /** - * Returns the ManyToMany join table name (aka the intersection table). - * - * @param lhsTable - * the left hand side bean table - * @param rhsTable - * the right hand side bean table - * - * @return the many to many join table name - */ - TableName getM2MJoinTableName(TableName lhsTable, TableName rhsTable); - - /** - * Return the column name given the property name. - * - * @return the column name for a given property - */ - String getColumnFromProperty(Class beanClass, String propertyName); - - /** - * Return the property name from the column name. - *

- * This is used to help mapping of raw SQL queries onto bean properties. - *

- * - * @param beanClass - * the bean class - * @param dbColumnName - * the db column name - * - * @return the property name from the column name - */ - String getPropertyFromColumn(Class beanClass, String dbColumnName); - - /** - * Return the sequence name given the table name (for DB's that use - * sequences). - *

- * Typically you might append "_seq" to the table name as an example. - *

- * - * @param tableName - * the table name - * - * @return the sequence name - */ - String getSequenceName(String tableName, String pkColumn); - - /** - * Return true if a prefix should be used building a foreign key name. - *

- * This by default is true and this works well when the primary key column - * names are simply "ID". In this case a prefix (such as "ORDER" and - * "CUSTOMER" etc) is added to the foreign key column producing "ORDER_ID" and - * "CUSTOMER_ID". - *

- *

- * This should return false when your primary key columns are the same as the - * foreign key columns. For example, when the primary key columns are - * "ORDER_ID", "CUST_ID" etc ... and they are the same as the foreign key - * column names. - *

- */ - boolean isUseForeignKeyPrefix(); - - /** - * Load setting from properties. - */ - void loadFromProperties(PropertiesWrapper properties); - +package com.avaje.ebean.config; + +import com.avaje.ebean.config.dbplatform.DatabasePlatform; + +/** + * Defines the naming convention for converting between logical property + * names/entity names and physical DB column names/table names. + *

+ * The main goal of the naming convention is to reduce the amount of + * configuration required in the mapping (especially when mapping between column + * and property names). + *

+ *

+ * Note that if you do not define a NamingConvention the default one will be + * used and you can configure it's behaviour via properties. + *

+ */ +public interface NamingConvention { + + /** + * Set the associated DatabasePlaform. + *

+ * This is set after the DatabasePlatform has been associated. + *

+ *

+ * The purpose of this is to enable NamingConvention to be able to support + * database platform specific configuration. + *

+ * + * @param databasePlatform + * the database platform + */ + void setDatabasePlatform(DatabasePlatform databasePlatform); + + /** + * Returns the table name for a given Class. + *

+ * This method is always called and should take into account @Table + * annotations etc. This means you can choose to override the settings defined + * by @Table if you wish. + *

+ * + * @param beanClass + * the bean class + * + * @return the table name for the entity class + */ + TableName getTableName(Class beanClass); + + /** + * Returns the ManyToMany join table name (aka the intersection table). + * + * @param lhsTable + * the left hand side bean table + * @param rhsTable + * the right hand side bean table + * + * @return the many to many join table name + */ + TableName getM2MJoinTableName(TableName lhsTable, TableName rhsTable); + + /** + * Return the column name given the property name. + * + * @return the column name for a given property + */ + String getColumnFromProperty(Class beanClass, String propertyName); + + /** + * Return the property name from the column name. + *

+ * This is used to help mapping of raw SQL queries onto bean properties. + *

+ * + * @param beanClass + * the bean class + * @param dbColumnName + * the db column name + * + * @return the property name from the column name + */ + String getPropertyFromColumn(Class beanClass, String dbColumnName); + + /** + * Return the sequence name given the table name (for DB's that use + * sequences). + *

+ * Typically you might append "_seq" to the table name as an example. + *

+ * + * @param tableName + * the table name + * + * @return the sequence name + */ + String getSequenceName(String tableName, String pkColumn); + + /** + * Return true if a prefix should be used building a foreign key name. + *

+ * This by default is true and this works well when the primary key column + * names are simply "ID". In this case a prefix (such as "ORDER" and + * "CUSTOMER" etc) is added to the foreign key column producing "ORDER_ID" and + * "CUSTOMER_ID". + *

+ *

+ * This should return false when your primary key columns are the same as the + * foreign key columns. For example, when the primary key columns are + * "ORDER_ID", "CUST_ID" etc ... and they are the same as the foreign key + * column names. + *

+ */ + boolean isUseForeignKeyPrefix(); + + /** + * Load setting from properties. + */ + void loadFromProperties(PropertiesWrapper properties); + } \ No newline at end of file diff --git a/src/main/java/com/avaje/ebean/config/PstmtDelegate.java b/src/main/java/com/avaje/ebean/config/PstmtDelegate.java index c2407baca..4bd165883 100644 --- a/src/main/java/com/avaje/ebean/config/PstmtDelegate.java +++ b/src/main/java/com/avaje/ebean/config/PstmtDelegate.java @@ -1,24 +1,24 @@ -package com.avaje.ebean.config; - -import java.sql.PreparedStatement; - -/** - * Unwrap the PreparedStatement to get the specific underlying implementation. - *

- * This is used to handle specific JDBC driver issues. Typically this means - * getting the OraclePreparedStatement to handle Oracle specific issues etc. - *

- * - * @author rbygrave - */ -public interface PstmtDelegate { - - /** - * Unwrap the PreparedStatement to get the specific underlying implementation. - * - * @param pstmt - * the PreparedStatement coming out of the connection pool - * @return the underlying PreparedStatement - */ - PreparedStatement unwrap(PreparedStatement pstmt); -} +package com.avaje.ebean.config; + +import java.sql.PreparedStatement; + +/** + * Unwrap the PreparedStatement to get the specific underlying implementation. + *

+ * This is used to handle specific JDBC driver issues. Typically this means + * getting the OraclePreparedStatement to handle Oracle specific issues etc. + *

+ * + * @author rbygrave + */ +public interface PstmtDelegate { + + /** + * Unwrap the PreparedStatement to get the specific underlying implementation. + * + * @param pstmt + * the PreparedStatement coming out of the connection pool + * @return the underlying PreparedStatement + */ + PreparedStatement unwrap(PreparedStatement pstmt); +} diff --git a/src/main/java/com/avaje/ebean/config/ScalarTypeConverter.java b/src/main/java/com/avaje/ebean/config/ScalarTypeConverter.java index 14a7f97aa..1e61f5a71 100644 --- a/src/main/java/com/avaje/ebean/config/ScalarTypeConverter.java +++ b/src/main/java/com/avaje/ebean/config/ScalarTypeConverter.java @@ -1,74 +1,74 @@ -package com.avaje.ebean.config; - -/** - * Used to convert between a value object and a known scalar type. The value - * object is the logical type used in your application and the scalar type is - * the value used to persist than to the DB. - *

- * The Value object should be immutable and scalar (aka not compound) and - * converts to and from a known scalar type which Ebean will use to persist the - * value. - *

- *

- * This is an easier alternative to implementing the - * com.avaje.ebean.server.type.ScalarType interface. - *

- *

- * Note that Ebean will automatically try to detect Immutable Scalar Value - * Objects and automatically support them via reflection. This however would not - * be appropriate when the logical type is different from the type you wish to - * use for persistence - for example, if the logical type was long and you - * wanted to use java.sql.Timestamp for persistence. In this case you would want - * to implement this interface rather than let Ebean automatically support that - * type via reflection. - *

- *

- * If you want to support a Compound Type rather than a Scalar Type refer to - * {@link CompoundType}. - *

- * - * @author rbygrave - * - * @param - * The value object type. - * @param - * The scalar object type that is used to persist the value object. - * - * @see CompoundType - * @see CompoundTypeProperty - */ -public interface ScalarTypeConverter { - - /** - * Return the value to represent null. Typically this is actually null but for - * scala.Option and similar type converters this actually returns an instance - * representing "None". - */ - B getNullValue(); - - /** - * Convert the scalar type value into the value object. - *

- * This typically occurs when Ebean reads the value from a resultSet or other - * data source. - *

- * - * @param scalarType - * the value from the data source - */ - B wrapValue(S scalarType); - - /** - * Convert the value object into a scalar value that Ebean knows how to - * persist. - *

- * This typically occurs when Ebean is persisting the value object to the data - * store. - *

- * - * @param beanType - * the value object - */ - S unwrapValue(B beanType); - -} +package com.avaje.ebean.config; + +/** + * Used to convert between a value object and a known scalar type. The value + * object is the logical type used in your application and the scalar type is + * the value used to persist than to the DB. + *

+ * The Value object should be immutable and scalar (aka not compound) and + * converts to and from a known scalar type which Ebean will use to persist the + * value. + *

+ *

+ * This is an easier alternative to implementing the + * com.avaje.ebean.server.type.ScalarType interface. + *

+ *

+ * Note that Ebean will automatically try to detect Immutable Scalar Value + * Objects and automatically support them via reflection. This however would not + * be appropriate when the logical type is different from the type you wish to + * use for persistence - for example, if the logical type was long and you + * wanted to use java.sql.Timestamp for persistence. In this case you would want + * to implement this interface rather than let Ebean automatically support that + * type via reflection. + *

+ *

+ * If you want to support a Compound Type rather than a Scalar Type refer to + * {@link CompoundType}. + *

+ * + * @author rbygrave + * + * @param + * The value object type. + * @param + * The scalar object type that is used to persist the value object. + * + * @see CompoundType + * @see CompoundTypeProperty + */ +public interface ScalarTypeConverter { + + /** + * Return the value to represent null. Typically this is actually null but for + * scala.Option and similar type converters this actually returns an instance + * representing "None". + */ + B getNullValue(); + + /** + * Convert the scalar type value into the value object. + *

+ * This typically occurs when Ebean reads the value from a resultSet or other + * data source. + *

+ * + * @param scalarType + * the value from the data source + */ + B wrapValue(S scalarType); + + /** + * Convert the value object into a scalar value that Ebean knows how to + * persist. + *

+ * This typically occurs when Ebean is persisting the value object to the data + * store. + *

+ * + * @param beanType + * the value object + */ + S unwrapValue(B beanType); + +} diff --git a/src/main/java/com/avaje/ebean/config/ServerConfig.java b/src/main/java/com/avaje/ebean/config/ServerConfig.java index b55e4fb8c..a338f1369 100644 --- a/src/main/java/com/avaje/ebean/config/ServerConfig.java +++ b/src/main/java/com/avaje/ebean/config/ServerConfig.java @@ -1,1845 +1,1845 @@ -package com.avaje.ebean.config; - -import com.avaje.ebean.EbeanServerFactory; -import com.avaje.ebean.PersistenceContextScope; -import com.avaje.ebean.annotation.Encrypted; -import com.avaje.ebean.cache.ServerCacheFactory; -import com.avaje.ebean.cache.ServerCacheManager; -import com.avaje.ebean.config.dbplatform.DatabasePlatform; -import com.avaje.ebean.config.dbplatform.DbEncrypt; -import com.avaje.ebean.event.*; -import com.avaje.ebean.meta.MetaInfoManager; -import com.avaje.ebean.util.ClassUtil; -import com.fasterxml.jackson.core.JsonFactory; - -import javax.sql.DataSource; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -/** - * The configuration used for creating a EbeanServer. - *

- * Used to programmatically construct an EbeanServer and optionally register it - * with the Ebean singleton. - *

- *

- * If you just use Ebean without this programmatic configuration Ebean will read - * the ebean.properties file and take the configuration from there. This usually - * includes searching the class path and automatically registering any entity - * classes and listeners etc. - *

- * - *
{@code
- * ServerConfig c = new ServerConfig();
- * c.setName("ordh2");
- * 
- * // read the ebean.properties and load
- * // those settings into this serverConfig object
- * c.loadFromProperties();
- * 
- * // generate DDL and run it
- * c.setDdlGenerate(true);
- * c.setDdlRun(true);
- * 
- * // add any classes found in the app.data package
- * c.addPackage("app.data");
- * 
- * // add the names of Jars that contain entities
- * c.addJar("myJarContainingEntities.jar");
- * c.addJar("someOtherJarContainingEntities.jar");
- * 
- * // register as the 'Default' server
- * c.setDefaultServer(true);
- * 
- * EbeanServer server = EbeanServerFactory.create(c);
- * 
- * }
- * - * @see EbeanServerFactory - * - * @author emcgreal - * @author rbygrave - */ -public class ServerConfig { - - /** - * The EbeanServer name. - */ - private String name; - - private ContainerConfig containerConfig; - - /** - * The resource directory. - */ - private String resourceDirectory; - - /** - * Set to true to register this EbeanServer with the Ebean singleton. - */ - private boolean register = true; - - /** - * Set to true if this is the default/primary server. - */ - private boolean defaultServer; - - /** - * List of interesting classes such as entities, embedded, ScalarTypes, - * Listeners, Finders, Controllers etc. - */ - private List> classes = new ArrayList>(); - - /** - * The packages that are searched for interesting classes. Only used when - * classes is empty/not explicitly specified. - */ - private List packages = new ArrayList(); - - /** - * The names of Jar files that are searched for entities and other interesting - * classes. Only used when classes is empty/not explicitly specified. - */ - private List searchJars = new ArrayList(); - - /** - * Class name of a classPathReader implementation. - */ - private String classPathReaderClassName; - - /** - * Config controlling the autofetch behaviour. - */ - private AutofetchConfig autofetchConfig = new AutofetchConfig(); - - /** - * The JSON format used for DateTime types. Default to millis. - */ - private JsonConfig.DateTime jsonDateTime = JsonConfig.DateTime.MILLIS; - - /** - * The database platform name. Used to imply a DatabasePlatform to use. - */ - private String databasePlatformName; - - /** - * The database platform. - */ - private DatabasePlatform databasePlatform; - - /** - * For DB's using sequences this is the number of sequence values prefetched. - */ - private int databaseSequenceBatchSize = 20; - - /** - * Use for transaction scoped batch mode. - */ - private PersistBatch persistBatch = PersistBatch.NONE; - - /** - * Use for per request batch mode. - */ - private PersistBatch persistBatchOnCascade = PersistBatch.NONE; - - private int persistBatchSize = 20; - - /** - * The default batch size for lazy loading - */ - private int lazyLoadBatchSize = 10; - - /** - * The default batch size for 'query joins'. - */ - private int queryBatchSize = 100; - - private boolean eagerFetchLobs; - - private boolean ddlGenerate; - - private boolean ddlRun; - - private boolean useJtaTransactionManager; - - /** - * The external transaction manager (like Spring). - */ - private ExternalTransactionManager externalTransactionManager; - - /** - * Used to unwrap PreparedStatements to perform JDBC Driver specific functions - */ - private PstmtDelegate pstmtDelegate; - - /** - * The data source (if programmatically provided). - */ - private DataSource dataSource; - - /** - * The data source config. - */ - private DataSourceConfig dataSourceConfig = new DataSourceConfig(); - - /** - * Set to true if the DataSource uses autoCommit. - *

- * Indicates that Ebean should use autoCommit friendly Transactions and TransactionManager. - */ - private boolean autoCommitMode; - - /** - * The data source JNDI name if using a JNDI DataSource. - */ - private String dataSourceJndiName; - - /** - * The database boolean true value (typically either 1, T, or Y). - */ - private String databaseBooleanTrue; - - /** - * The database boolean false value (typically either 0, F or N). - */ - private String databaseBooleanFalse; - - /** - * The naming convention. - */ - private NamingConvention namingConvention = new UnderscoreNamingConvention(); - - /** - * Behaviour of update to include on the change properties. - */ - private boolean updateChangesOnly = true; - - /** - * Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children. - */ - private boolean updatesDeleteMissingChildren = true; - - /** - * Setting to indicate if UUID should be stored as binary(16) or varchar(40). - */ - private boolean uuidStoreAsBinary; - - - private List persistControllers = new ArrayList(); - private List persistListeners = new ArrayList(); - private List queryAdapters = new ArrayList(); - private List bulkTableEventListeners = new ArrayList(); - private List configStartupListeners = new ArrayList(); - private List transactionEventListeners = new ArrayList(); - - private EncryptKeyManager encryptKeyManager; - - private EncryptDeployManager encryptDeployManager; - - private Encryptor encryptor; - - private DbEncrypt dbEncrypt; - - private ServerCacheFactory serverCacheFactory; - - private ServerCacheManager serverCacheManager; - - private boolean collectQueryStatsByNode = true; - - private boolean collectQueryOrigins = true; - - /** - * The default PersistenceContextScope used if one is not explicitly set on a query. - */ - private PersistenceContextScope persistenceContextScope = PersistenceContextScope.TRANSACTION; - - private JsonFactory jsonFactory; - - private boolean localTimeWithNanos; - - private boolean durationWithNanos; - - private int maxCallStack = 5; - - private boolean transactionRollbackOnChecked = true; - - private boolean registerJmxMBeans = true; - - // configuration for the background executor service (thread pool) - - private int backgroundExecutorSchedulePoolSize = 1; - private int backgroundExecutorCorePoolSize = 1; - private int backgroundExecutorMaxPoolSize = 8; - private int backgroundExecutorIdleSecs = 60; - private int backgroundExecutorShutdownSecs = 30; - - // defaults for the L2 bean caching - - private int cacheWarmingDelay = 30; - private int cacheMaxSize = 10000; - private int cacheMaxIdleTime = 600; - private int cacheMaxTimeToLive = 60*60*6; - - // defaults for the L2 query caching - - private int queryCacheMaxSize = 1000; - private int queryCacheMaxIdleTime = 600; - private int queryCacheMaxTimeToLive = 60*60*6; - - /** - * Construct a Server Configuration for programmatically creating an EbeanServer. - */ - public ServerConfig() { - - } - - /** - * Return the Jackson JsonFactory to use. - *

- * If not set a default implmentation will be used. - */ - public JsonFactory getJsonFactory() { - return jsonFactory; - } - - /** - * Set the Jackson JsonFactory to use. - *

- * If not set a default implmentation will be used. - */ - public void setJsonFactory(JsonFactory jsonFactory) { - this.jsonFactory = jsonFactory; - } - - /** - * Return the JSON format used for DateTime types. - */ - public JsonConfig.DateTime getJsonDateTime() { - return jsonDateTime; - } - - /** - * Set the JSON format to use for DateTime types. - */ - public void setJsonDateTime(JsonConfig.DateTime jsonDateTime) { - this.jsonDateTime = jsonDateTime; - } - - /** - * Return the name of the EbeanServer. - */ - public String getName() { - return name; - } - - /** - * Set the name of the EbeanServer. - */ - public void setName(String name) { - this.name = name; - } - - /** - * Return the container / clustering configuration. - *

- * The container holds all the EbeanServer instances and provides clustering communication - * services to all the EbeanServer instances. - */ - public ContainerConfig getContainerConfig() { - return containerConfig; - } - - /** - * Set the container / clustering configuration. - *

- * The container holds all the EbeanServer instances and provides clustering communication - * services to all the EbeanServer instances. - */ - public void setContainerConfig(ContainerConfig containerConfig) { - this.containerConfig = containerConfig; - } - - /** - * Return true if this server should be registered with the Ebean singleton - * when it is created. - *

- * By default this is set to true. - *

- */ - public boolean isRegister() { - return register; - } - - /** - * Set to false if you do not want this server to be registered with the Ebean - * singleton when it is created. - *

- * By default this is set to true. - *

- */ - public void setRegister(boolean register) { - this.register = register; - } - - /** - * Return true if this server should be registered as the "default" server - * with the Ebean singleton. - *

- * This is only used when {@link #setRegister(boolean)} is also true. - *

- */ - public boolean isDefaultServer() { - return defaultServer; - } - - /** - * Set true if this EbeanServer should be registered as the "default" server - * with the Ebean singleton. - *

- * This is only used when {@link #setRegister(boolean)} is also true. - *

- */ - public void setDefaultServer(boolean defaultServer) { - this.defaultServer = defaultServer; - } - - /** - * Return the PersistBatch mode to use by default at the transaction level. - *

- * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into - * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends - * or the batch size is meet. - *

- */ - public PersistBatch getPersistBatch() { - return persistBatch; - } - - /** - * Set the JDBC batch mode to use at the transaction level. - *

- * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into - * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends - * or the batch size is meet. - *

- */ - public void setPersistBatch(PersistBatch persistBatch) { - this.persistBatch = persistBatch; - } - - /** - * Return the JDBC batch mode to use per save(), delete(), insert() or update() request. - *

- * This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase - * for this is when saving a master/parent bean this cascade inserts many detail/child beans. - *

- *

- * This only takes effect when the persistBatch mode at the transaction level does not take effect. - *

- */ - public PersistBatch getPersistBatchOnCascade() { - return persistBatchOnCascade; - } - - /** - * Set the JDBC batch mode to use per save(), delete(), insert() or update() request. - *

- * This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase - * for this is when saving a master/parent bean this cascade inserts many detail/child beans. - *

- *

- * This only takes effect when the persistBatch mode at the transaction level does not take effect. - *

- */ - public void setPersistBatchOnCascade(PersistBatch persistBatchOnCascade) { - this.persistBatchOnCascade = persistBatchOnCascade; - } - - /** - * Deprecated, please migrate to using setPersistBatch(). - *

- * Set to true if you what to use JDBC batching for persisting and deleting - * beans. - *

- *

- * With this Ebean will batch up persist requests and use the JDBC batch api. - * This is a performance optimisation designed to reduce the network chatter. - *

- *

- * When true this is equivalent to {@code setPersistBatch(PersistBatch.ALL)} or - * when false to {@code setPersistBatch(PersistBatch.NONE)} - *

- */ - public void setPersistBatching(boolean persistBatching) { - this.persistBatch = (persistBatching) ? PersistBatch.ALL : PersistBatch.NONE; - } - - /** - * Return the batch size used for JDBC batching. This defaults to 20. - */ - public int getPersistBatchSize() { - return persistBatchSize; - } - - /** - * Set the batch size used for JDBC batching. If unset this defaults to 20. - *

- * You can also set the batch size on the transaction. - *

- * @see com.avaje.ebean.Transaction#setBatchSize(int) - */ - public void setPersistBatchSize(int persistBatchSize) { - this.persistBatchSize = persistBatchSize; - } - - /** - * Gets the query batch size. This defaults to 100. - * - * @return the query batch size - */ - public int getQueryBatchSize() { - return queryBatchSize; - } - - /** - * Sets the query batch size. This defaults to 100. - * - * @param queryBatchSize - * the new query batch size - */ - public void setQueryBatchSize(int queryBatchSize) { - this.queryBatchSize = queryBatchSize; - } - - /** - * Return the default batch size for lazy loading of beans and collections. - */ - public int getLazyLoadBatchSize() { - return lazyLoadBatchSize; - } - - /** - * Set the default batch size for lazy loading. - *

- * This is the number of beans or collections loaded when lazy loading is - * invoked by default. - *

- *

- * The default value is for this is 10 (load 10 beans or collections). - *

- *

- * You can explicitly control the lazy loading batch size for a given join on - * a query using +lazy(batchSize) or JoinConfig. - *

- */ - public void setLazyLoadBatchSize(int lazyLoadBatchSize) { - this.lazyLoadBatchSize = lazyLoadBatchSize; - } - - /** - * Set the number of sequences to fetch/preallocate when using DB sequences. - *

- * This is a performance optimisation to reduce the number times Ebean - * requests a sequence to be used as an Id for a bean (aka reduce network - * chatter). - *

- */ - public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) { - this.databaseSequenceBatchSize = databaseSequenceBatchSize; - } - - /** - * Return true if we are running in a JTA Transaction manager. - */ - public boolean isUseJtaTransactionManager() { - return useJtaTransactionManager; - } - - /** - * Set to true if we are running in a JTA Transaction manager. - */ - public void setUseJtaTransactionManager(boolean useJtaTransactionManager) { - this.useJtaTransactionManager = useJtaTransactionManager; - } - - /** - * Return the external transaction manager. - */ - public ExternalTransactionManager getExternalTransactionManager() { - return externalTransactionManager; - } - - /** - * Set the external transaction manager. - */ - public void setExternalTransactionManager(ExternalTransactionManager externalTransactionManager) { - this.externalTransactionManager = externalTransactionManager; - } - - /** - * Return the ServerCacheFactory. - */ - public ServerCacheFactory getServerCacheFactory() { - return serverCacheFactory; - } - - /** - * Set the ServerCacheFactory to use. - */ - public void setServerCacheFactory(ServerCacheFactory serverCacheFactory) { - this.serverCacheFactory = serverCacheFactory; - } - - /** - * Return the ServerCacheManager. - */ - public ServerCacheManager getServerCacheManager() { - return serverCacheManager; - } - - /** - * Set the ServerCacheManager to use. - */ - public void setServerCacheManager(ServerCacheManager serverCacheManager) { - this.serverCacheManager = serverCacheManager; - } - - /** - * Return true if LOB's should default to fetch eager. - * By default this is set to false and LOB's must be explicitly fetched. - */ - public boolean isEagerFetchLobs() { - return eagerFetchLobs; - } - - /** - * Set to true if you want LOB's to be fetch eager by default. - * By default this is set to false and LOB's must be explicitly fetched. - */ - public void setEagerFetchLobs(boolean eagerFetchLobs) { - this.eagerFetchLobs = eagerFetchLobs; - } - - /** - * Return the max call stack to use for origin location. - */ - public int getMaxCallStack() { - return maxCallStack; - } - - /** - * Set the max call stack to use for origin location. - */ - public void setMaxCallStack(int maxCallStack) { - this.maxCallStack = maxCallStack; - } - - /** - * Return true if transactions should rollback on checked exceptions. - */ - public boolean isTransactionRollbackOnChecked() { - return transactionRollbackOnChecked; - } - - /** - * Set to true if transactions should by default rollback on checked exceptions. - */ - public void setTransactionRollbackOnChecked(boolean transactionRollbackOnChecked) { - this.transactionRollbackOnChecked = transactionRollbackOnChecked; - } - - /** - * Return true if the server should register JMX MBeans. - */ - public boolean isRegisterJmxMBeans() { - return registerJmxMBeans; - } - - /** - * Set if the server should register JMX MBeans. - */ - public void setRegisterJmxMBeans(boolean registerJmxMBeans) { - this.registerJmxMBeans = registerJmxMBeans; - } - - /** - * Return the Background executor schedule pool size. Defaults to 1. - */ - public int getBackgroundExecutorSchedulePoolSize() { - return backgroundExecutorSchedulePoolSize; - } - - /** - * Set the Background executor schedule pool size. - */ - public void setBackgroundExecutorSchedulePoolSize(int backgroundExecutorSchedulePoolSize) { - this.backgroundExecutorSchedulePoolSize = backgroundExecutorSchedulePoolSize; - } - - /** - * Return the Background executor core pool size. - */ - public int getBackgroundExecutorCorePoolSize() { - return backgroundExecutorCorePoolSize; - } - - /** - * Set the Background executor core pool size. - */ - public void setBackgroundExecutorCorePoolSize(int backgroundExecutorCorePoolSize) { - this.backgroundExecutorCorePoolSize = backgroundExecutorCorePoolSize; - } - - /** - * Return the Background executor max pool size. - */ - public int getBackgroundExecutorMaxPoolSize() { - return backgroundExecutorMaxPoolSize; - } - - /** - * Set the Background executor max pool size. - */ - public void setBackgroundExecutorMaxPoolSize(int backgroundExecutorMaxPoolSize) { - this.backgroundExecutorMaxPoolSize = backgroundExecutorMaxPoolSize; - } - - /** - * Return the Background executor idle seconds. - */ - public int getBackgroundExecutorIdleSecs() { - return backgroundExecutorIdleSecs; - } - - /** - * Set the Background executor idle seconds. - */ - public void setBackgroundExecutorIdleSecs(int backgroundExecutorIdleSecs) { - this.backgroundExecutorIdleSecs = backgroundExecutorIdleSecs; - } - - /** - * Return the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely - * before it is forced shutdown. - */ - public int getBackgroundExecutorShutdownSecs() { - return backgroundExecutorShutdownSecs; - } - - /** - * Set the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely - * before it is forced shutdown. - */ - public void setBackgroundExecutorShutdownSecs(int backgroundExecutorShutdownSecs) { - this.backgroundExecutorShutdownSecs = backgroundExecutorShutdownSecs; - } - - /** - * Return the cache warming delay in seconds. - */ - public int getCacheWarmingDelay() { - return cacheWarmingDelay; - } - - /** - * Set the cache warming delay in seconds. - */ - public void setCacheWarmingDelay(int cacheWarmingDelay) { - this.cacheWarmingDelay = cacheWarmingDelay; - } - - /** - * Return the L2 cache default max size. - */ - public int getCacheMaxSize() { - return cacheMaxSize; - } - - /** - * Set the L2 cache default max size. - */ - public void setCacheMaxSize(int cacheMaxSize) { - this.cacheMaxSize = cacheMaxSize; - } - - /** - * Return the L2 cache default max idle time in seconds. - */ - public int getCacheMaxIdleTime() { - return cacheMaxIdleTime; - } - - /** - * Set the L2 cache default max idle time in seconds. - */ - public void setCacheMaxIdleTime(int cacheMaxIdleTime) { - this.cacheMaxIdleTime = cacheMaxIdleTime; - } - - /** - * Return the L2 cache default max time to live in seconds. - */ - public int getCacheMaxTimeToLive() { - return cacheMaxTimeToLive; - } - - /** - * Set the L2 cache default max time to live in seconds. - */ - public void setCacheMaxTimeToLive(int cacheMaxTimeToLive) { - this.cacheMaxTimeToLive = cacheMaxTimeToLive; - } - - /** - * Return the L2 query cache default max size. - */ - public int getQueryCacheMaxSize() { - return queryCacheMaxSize; - } - - /** - * Set the L2 query cache default max size. - */ - public void setQueryCacheMaxSize(int queryCacheMaxSize) { - this.queryCacheMaxSize = queryCacheMaxSize; - } - - /** - * Return the L2 query cache default max idle time in seconds. - */ - public int getQueryCacheMaxIdleTime() { - return queryCacheMaxIdleTime; - } - - /** - * Set the L2 query cache default max idle time in seconds. - */ - public void setQueryCacheMaxIdleTime(int queryCacheMaxIdleTime) { - this.queryCacheMaxIdleTime = queryCacheMaxIdleTime; - } - - /** - * Return the L2 query cache default max time to live in seconds. - */ - public int getQueryCacheMaxTimeToLive() { - return queryCacheMaxTimeToLive; - } - - /** - * Set the L2 query cache default max time to live in seconds. - */ - public void setQueryCacheMaxTimeToLive(int queryCacheMaxTimeToLive) { - this.queryCacheMaxTimeToLive = queryCacheMaxTimeToLive; - } - - /** - * Return the NamingConvention. - *

- * If none has been set the default UnderscoreNamingConvention is used. - *

- */ - public NamingConvention getNamingConvention() { - return namingConvention; - } - - /** - * Set the NamingConvention. - *

- * If none is set the default UnderscoreNamingConvention is used. - *

- */ - public void setNamingConvention(NamingConvention namingConvention) { - this.namingConvention = namingConvention; - } - - /** - * Return the configuration for the Autofetch feature. - */ - public AutofetchConfig getAutofetchConfig() { - return autofetchConfig; - } - - /** - * Set the configuration for the Autofetch feature. - */ - public void setAutofetchConfig(AutofetchConfig autofetchConfig) { - this.autofetchConfig = autofetchConfig; - } - - /** - * Return the PreparedStatementDelegate. - */ - public PstmtDelegate getPstmtDelegate() { - return pstmtDelegate; - } - - /** - * Set the PstmtDelegate which can be used to support JDBC driver specific - * features. - *

- * Typically this means Oracle JDBC driver specific workarounds. - *

- */ - public void setPstmtDelegate(PstmtDelegate pstmtDelegate) { - this.pstmtDelegate = pstmtDelegate; - } - - /** - * Return the DataSource. - */ - public DataSource getDataSource() { - return dataSource; - } - - /** - * Set a DataSource. - */ - public void setDataSource(DataSource dataSource) { - this.dataSource = dataSource; - } - - /** - * Return the configuration to build a DataSource using Ebean's own DataSource - * implementation. - */ - public DataSourceConfig getDataSourceConfig() { - return dataSourceConfig; - } - - /** - * Set the configuration required to build a DataSource using Ebean's own - * DataSource implementation. - */ - public void setDataSourceConfig(DataSourceConfig dataSourceConfig) { - this.dataSourceConfig = dataSourceConfig; - } - - /** - * Return the JNDI name of the DataSource to use. - */ - public String getDataSourceJndiName() { - return dataSourceJndiName; - } - - /** - * Set the JNDI name of the DataSource to use. - *

- * By default a prefix of "java:comp/env/jdbc/" is used to lookup the - * DataSource. This prefix is not used if dataSourceJndiName starts with - * "java:". - *

- */ - public void setDataSourceJndiName(String dataSourceJndiName) { - this.dataSourceJndiName = dataSourceJndiName; - } - - /** - * Return true if autoCommit mode is on. This indicates to Ebean to use autoCommit friendly Transactions and TransactionManager. - */ - public boolean isAutoCommitMode() { - return autoCommitMode; - } - - /** - * Set to true if autoCommit mode is on and Ebean should use autoCommit friendly Transactions and TransactionManager. - */ - public void setAutoCommitMode(boolean autoCommitMode) { - this.autoCommitMode = autoCommitMode; - } - - /** - * Return a value used to represent TRUE in the database. - *

- * This is used for databases that do not support boolean natively. - *

- *

- * The value returned is either a Integer or a String (e.g. "1", or "T"). - *

- */ - public String getDatabaseBooleanTrue() { - return databaseBooleanTrue; - } - - /** - * Set the value to represent TRUE in the database. - *

- * This is used for databases that do not support boolean natively. - *

- *

- * The value set is either a Integer or a String (e.g. "1", or "T"). - *

- */ - public void setDatabaseBooleanTrue(String databaseTrue) { - this.databaseBooleanTrue = databaseTrue; - } - - /** - * Return a value used to represent FALSE in the database. - *

- * This is used for databases that do not support boolean natively. - *

- *

- * The value returned is either a Integer or a String (e.g. "0", or "F"). - *

- */ - public String getDatabaseBooleanFalse() { - return databaseBooleanFalse; - } - - /** - * Set the value to represent FALSE in the database. - *

- * This is used for databases that do not support boolean natively. - *

- *

- * The value set is either a Integer or a String (e.g. "0", or "F"). - *

- */ - public void setDatabaseBooleanFalse(String databaseFalse) { - this.databaseBooleanFalse = databaseFalse; - } - - /** - * Return the number of DB sequence values that should be preallocated. - */ - public int getDatabaseSequenceBatchSize() { - return databaseSequenceBatchSize; - } - - /** - * Set the number of DB sequence values that should be preallocated and cached - * by Ebean. - *

- * This is only used for DB's that use sequences and is a performance - * optimisation. This reduces the number of times Ebean needs to get a - * sequence value from the Database reducing network chatter. - *

- *

- * By default this value is 10 so when we need another Id (and don't have one - * in our cache) Ebean will fetch 10 id's from the database. Note that when - * the cache drops to have full (which is 5 by default) Ebean will fetch - * another batch of Id's in a background thread. - *

- */ - public void setDatabaseSequenceBatch(int databaseSequenceBatchSize) { - this.databaseSequenceBatchSize = databaseSequenceBatchSize; - } - - /** - * Return the database platform name (can be null). - *

- * If null then the platform is determined automatically via the JDBC driver - * information. - *

- */ - public String getDatabasePlatformName() { - return databasePlatformName; - } - - /** - * Explicitly set the database platform name - *

- * If none is set then the platform is determined automatically via the JDBC - * driver information. - *

- *

- * This can be used when the Database Platform can not be automatically - * detected from the JDBC driver (possibly 3rd party JDBC driver). It is also - * useful when you want to do offline DDL generation for a database platform - * that you don't have access to. - *

- *

- * Values are oracle, h2, postgres, mysql, mssqlserver2005. - *

- * - * @see DataSourceConfig#setOffline(boolean) - */ - public void setDatabasePlatformName(String databasePlatformName) { - this.databasePlatformName = databasePlatformName; - } - - /** - * Return the database platform to use for this server. - */ - public DatabasePlatform getDatabasePlatform() { - return databasePlatform; - } - - /** - * Explicitly set the database platform to use. - *

- * If none is set then the platform is determined via the databasePlatformName - * or automatically via the JDBC driver information. - *

- */ - public void setDatabasePlatform(DatabasePlatform databasePlatform) { - this.databasePlatform = databasePlatform; - } - - /** - * Return the EncryptKeyManager. - */ - public EncryptKeyManager getEncryptKeyManager() { - return encryptKeyManager; - } - - /** - * Set the EncryptKeyManager. - *

- * This is required when you want to use encrypted properties. - *

- *

- * You can also set this in ebean.proprerties: - *

- * - *
-   * # set via ebean.properties
-   * 
-   * ebean.encryptKeyManager=com.avaje.tests.basic.encrypt.BasicEncyptKeyManager
-   * 
- */ - public void setEncryptKeyManager(EncryptKeyManager encryptKeyManager) { - this.encryptKeyManager = encryptKeyManager; - } - - /** - * Return the EncryptDeployManager. - *

- * This is optionally used to programmatically define which columns are - * encrypted instead of using the {@link Encrypted} Annotation. - *

- */ - public EncryptDeployManager getEncryptDeployManager() { - return encryptDeployManager; - } - - /** - * Set the EncryptDeployManager. - *

- * This is optionally used to programmatically define which columns are - * encrypted instead of using the {@link Encrypted} Annotation. - *

- */ - public void setEncryptDeployManager(EncryptDeployManager encryptDeployManager) { - this.encryptDeployManager = encryptDeployManager; - } - - /** - * Return the Encryptor used to encrypt data on the java client side (as - * opposed to DB encryption functions). - */ - public Encryptor getEncryptor() { - return encryptor; - } - - /** - * Set the Encryptor used to encrypt data on the java client side (as opposed - * to DB encryption functions). - *

- * Ebean has a default implementation that it will use if you do not set your - * own Encryptor implementation. - *

- */ - public void setEncryptor(Encryptor encryptor) { - this.encryptor = encryptor; - } - - /** - * Return the DbEncrypt used to encrypt and decrypt properties. - *

- * Note that if this is not set then the DbPlatform may already have a - * DbEncrypt set and that will be used. - *

- */ - public DbEncrypt getDbEncrypt() { - return dbEncrypt; - } - - /** - * Set the DbEncrypt used to encrypt and decrypt properties. - *

- * Note that if this is not set then the DbPlatform may already have a - * DbEncrypt set (H2, MySql, Postgres and Oracle platforms have a DbEncrypt) - *

- */ - public void setDbEncrypt(DbEncrypt dbEncrypt) { - this.dbEncrypt = dbEncrypt; - } - - - /** - * Return true if UUID should be stored as binary(16) (as opposed to varchar(40)). - */ - public boolean isUuidStoreAsBinary() { - return uuidStoreAsBinary; - } - - /** - * Set to true if UUID should be stored as binary(16) (as opposed to varchar(40)). - */ - public void setUuidStoreAsBinary(boolean uuidStoreAsBinary) { - this.uuidStoreAsBinary = uuidStoreAsBinary; - } - - /** - * Return true if LocalTime should be persisted with nanos precision. - */ - public boolean isLocalTimeWithNanos() { - return localTimeWithNanos; - } - - /** - * Set to true if LocalTime should be persisted with nanos precision. - *

- * Otherwise it is persisted using java.sql.Time which is seconds precision. - *

- */ - public void setLocalTimeWithNanos(boolean localTimeWithNanos) { - this.localTimeWithNanos = localTimeWithNanos; - } - - /** - * Return true if Duration should be persisted with nanos precision (SQL DECIMAL). - *

- * Otherwise it is persisted with second precision (SQL INTEGER). - *

- */ - public boolean isDurationWithNanos() { - return durationWithNanos; - } - - /** - * Set to true if Duration should be persisted with nanos precision (SQL DECIMAL). - *

- * Otherwise it is persisted with second precision (SQL INTEGER). - *

- */ - public void setDurationWithNanos(boolean durationWithNanos) { - this.durationWithNanos = durationWithNanos; - } - - /** - * Set to true to run the DDL generation on startup. - */ - public void setDdlGenerate(boolean ddlGenerate) { - this.ddlGenerate = ddlGenerate; - } - - /** - * Set to true to run the generated DDL on startup. - */ - public void setDdlRun(boolean ddlRun) { - this.ddlRun = ddlRun; - } - - /** - * Return true if the DDL should be generated. - */ - public boolean isDdlGenerate() { - return ddlGenerate; - } - - /** - * Return true if the DDL should be run. - */ - public boolean isDdlRun() { - return ddlRun; - } - - /** - * Programmatically add classes (typically entities) that this server should - * use. - *

- * The class can be an Entity, Embedded type, ScalarType, BeanPersistListener, - * BeanFinder or BeanPersistController. - *

- *

- * If no classes are specified then the classes are found automatically via - * searching the class path. - *

- *

- * Alternatively the classes can be added via {@link #setClasses(List)}. - *

- * - * @param cls - * the entity type (or other type) that should be registered by this - * server. - */ - public void addClass(Class cls) { - if (classes == null) { - classes = new ArrayList>(); - } - classes.add(cls); - } - - /** - * Add a package to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- */ - public void addPackage(String packageName) { - if (packages == null) { - packages = new ArrayList(); - } - packages.add(packageName); - } - - /** - * Return packages to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- */ - public List getPackages() { - return packages; - } - - /** - * Set packages to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- */ - public void setPackages(List packages) { - this.packages = packages; - } - - /** - * Add the name of a Jar to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- *

- * If you are using ebean.properties you can specify jars to search by setting - * a ebean.search.jars property. - *

- * - *
-   * # EBean will search through classes for entities, but will not search jar files 
-   * # unless you tell it to do so, for performance reasons.  Set this value to a 
-   * # comma-delimited list of jar files you want ebean to search.
-   * ebean.search.jars=example.jar
-   * 
- */ - public void addJar(String jarName) { - if (searchJars == null) { - searchJars = new ArrayList(); - } - searchJars.add(jarName); - } - - /** - * Return packages to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- */ - public List getJars() { - return searchJars; - } - - /** - * Set the names of Jars to search for entities via class path search. - *

- * This is only used if classes have not been explicitly specified. - *

- */ - public void setJars(List searchJars) { - this.searchJars = searchJars; - } - - /** - * Return the class name of a classPathReader implementation. - */ - public String getClassPathReaderClassName() { - return classPathReaderClassName; - } - - /** - * Set the class name of a classPathReader implementation. - * - * Refer to server.util.ClassPathReader, this should really by a plugin but doing this for now - * to be relatively compatible with current implementation. - */ - public void setClassPathReaderClassName(String classPathReaderClassName) { - this.classPathReaderClassName = classPathReaderClassName; - } - - /** - * Set the list of classes (entities, listeners, scalarTypes etc) that should - * be used for this server. - *

- * If no classes are specified then the classes are found automatically via - * searching the class path. - *

- *

- * Alternatively the classes can contain added via {@link #addClass(Class)}. - *

- */ - public void setClasses(List> classes) { - this.classes = classes; - } - - /** - * Return the classes registered for this server. Typically this includes - * entities and perhaps listeners. - */ - public List> getClasses() { - return classes; - } - - /** - * Return true to only update changed properties. - */ - public boolean isUpdateChangesOnly() { - return updateChangesOnly; - } - - /** - * Set to true to only update changed properties. - */ - public void setUpdateChangesOnly(boolean updateChangesOnly) { - this.updateChangesOnly = updateChangesOnly; - } - - /** - * Return true if updates by default delete missing children when cascading save to a OneToMany or - * ManyToMany. When not set this defaults to true. - */ - public boolean isUpdatesDeleteMissingChildren() { - return updatesDeleteMissingChildren; - } - - /** - * Set if updates by default delete missing children when cascading save to a OneToMany or - * ManyToMany. When not set this defaults to true. - */ - public void setUpdatesDeleteMissingChildren(boolean updatesDeleteMissingChildren) { - this.updatesDeleteMissingChildren = updatesDeleteMissingChildren; - } - - /** - * Return true if the ebeanServer should collection query statistics by ObjectGraphNode. - */ - public boolean isCollectQueryStatsByNode() { - return collectQueryStatsByNode; - } - - /** - * Set to true to collection query execution statistics by ObjectGraphNode. - *

- * These statistics can be used to highlight code/query 'origin points' that result in lots of lazy loading. - *

- *

- * It is considered safe/fine to have this set to true for production. - *

- *

- * This information can be later retrieved via {@link MetaInfoManager}. - *

- * @see MetaInfoManager - */ - public void setCollectQueryStatsByNode(boolean collectQueryStatsByNode) { - this.collectQueryStatsByNode = collectQueryStatsByNode; - } - - /** - * Return true if query plans should also collect their 'origins'. This means for a given query plan you - * can identify the code/origin points where this query resulted from including lazy loading origins. - */ - public boolean isCollectQueryOrigins() { - return collectQueryOrigins; - } - - /** - * Set to true if query plans should collect their 'origin' points. This means for a given query plan you - * can identify the code/origin points where this query resulted from including lazy loading origins. - *

- * This information can be later retrieved via {@link MetaInfoManager}. - *

- * @see MetaInfoManager - */ - public void setCollectQueryOrigins(boolean collectQueryOrigins) { - this.collectQueryOrigins = collectQueryOrigins; - } - - /** - * Returns the resource directory. - */ - public String getResourceDirectory() { - return resourceDirectory; - } - - /** - * Sets the resource directory. - */ - public void setResourceDirectory(String resourceDirectory) { - this.resourceDirectory = resourceDirectory; - } - - /** - * Register a BeanQueryAdapter instance. - *

- * Note alternatively you can use {@link #setQueryAdapters(List)} to set all - * the BeanQueryAdapter instances. - *

- */ - public void add(BeanQueryAdapter beanQueryAdapter) { - queryAdapters.add(beanQueryAdapter); - } - - /** - * Return the BeanQueryAdapter instances. - */ - public List getQueryAdapters() { - return queryAdapters; - } - - /** - * Register all the BeanQueryAdapter instances. - *

- * Note alternatively you can use {@link #add(BeanQueryAdapter)} to add - * BeanQueryAdapter instances one at a time. - *

- */ - public void setQueryAdapters(List queryAdapters) { - this.queryAdapters = queryAdapters; - } - - /** - * Register a BeanPersistController instance. - *

- * Note alternatively you can use {@link #setPersistControllers(List)} to set - * all the BeanPersistController instances. - *

- */ - public void add(BeanPersistController beanPersistController) { - persistControllers.add(beanPersistController); - } - - /** - * Return the BeanPersistController instances. - */ - public List getPersistControllers() { - return persistControllers; - } - - /** - * Register all the BeanPersistController instances. - *

- * Note alternatively you can use {@link #add(BeanPersistController)} to add - * BeanPersistController instances one at a time. - *

- */ - public void setPersistControllers(List persistControllers) { - this.persistControllers = persistControllers; - } - - /** - * Register a TransactionEventListener instance - *

- * Note alternatively you can use {@link #setTransactionEventListeners(List)} - * to set all the TransactionEventListener instances. - *

- */ - public void add(TransactionEventListener listener) { - transactionEventListeners.add(listener); - } - - /** - * Return the TransactionEventListener instances. - */ - public List getTransactionEventListeners() { - return transactionEventListeners; - } - - /** - * Register all the TransactionEventListener instances. - *

- * Note alternatively you can use {@link #add(TransactionEventListener)} to - * add TransactionEventListener instances one at a time. - *

- */ - public void setTransactionEventListeners(List transactionEventListeners) { - this.transactionEventListeners = transactionEventListeners; - } - - /** - * Register a BeanPersistListener instance. - *

- * Note alternatively you can use {@link #setPersistListeners(List)} to set - * all the BeanPersistListener instances. - *

- */ - public void add(BeanPersistListener beanPersistListener) { - persistListeners.add(beanPersistListener); - } - - /** - * Return the BeanPersistListener instances. - */ - public List getPersistListeners() { - return persistListeners; - } - - /** - * Add a BulkTableEventListener - */ - public void add(BulkTableEventListener bulkTableEventListener) { - bulkTableEventListeners.add(bulkTableEventListener); - } - - /** - * Return the list of BulkTableEventListener instances. - */ - public List getBulkTableEventListeners() { - return bulkTableEventListeners; - } - - /** - * Add a ServerConfigStartup. - */ - public void addServerConfigStartup(ServerConfigStartup configStartupListener) { - configStartupListeners.add(configStartupListener); - } - - /** - * Return the list of ServerConfigStartup instances. - */ - public List getServerConfigStartupListeners() { - return configStartupListeners; - } - - /** - * Register all the BeanPersistListener instances. - *

- * Note alternatively you can use {@link #add(BeanPersistListener)} to add - * BeanPersistListener instances one at a time. - *

- */ - public void setPersistListeners(List persistListeners) { - this.persistListeners = persistListeners; - } - - /** - * Return the default PersistenceContextScope to be used if one is not explicitly set on a query. - *

- * The PersistenceContextScope can specified on each query via {@link com.avaje.ebean - * .Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope)}. If it - * is not set on the query this default scope is used. - * - * @see com.avaje.ebean.Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope) - */ - public PersistenceContextScope getPersistenceContextScope() { - // if somehow null return TRANSACTION scope - return persistenceContextScope == null ? PersistenceContextScope.TRANSACTION : persistenceContextScope; - } - - /** - * Set the PersistenceContext scope to be used if one is not explicitly set on a query. - *

- * This defaults to {@link PersistenceContextScope#TRANSACTION}. - *

- * The PersistenceContextScope can specified on each query via {@link com.avaje.ebean - * .Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope)}. If it - * is not set on the query this scope is used. - * - * @see com.avaje.ebean.Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope) - */ - public void setPersistenceContextScope(PersistenceContextScope persistenceContextScope) { - this.persistenceContextScope = persistenceContextScope; - } - - /** - * Load settings from ebean.properties. - */ - public void loadFromProperties() { - loadFromProperties(PropertyMap.defaultProperties()); - } - - /** - * Load the settings from the given properties - */ - public void loadFromProperties(Properties properties) { - PropertiesWrapper p = new PropertiesWrapper("ebean", name, properties); - loadSettings(p); - } - - - @SuppressWarnings("unchecked") - private T createInstance(PropertiesWrapper p, Class pluginType, String key) { - - String classname = p.get(key, null); - return classname == null ? null : (T) ClassUtil.newInstance(classname); - } - - /** - * loads the data source settings to preserve existing behaviour. IMHO, if someone has set the datasource config already, - * they don't want the settings to be reloaded and reset. This allows a descending class to override this behaviour and prevent it - * from happening. - * - * @param p - The defined property source passed to load settings - */ - protected void loadDataSourceSettings(PropertiesWrapper p) { - dataSourceConfig.loadSettings(p.withPrefix("datasource")); - } - - /** - * This is broken out for the same reason as above - preserve existing behaviour but let it be overridden. - */ - protected void loadAutofetchSettings(PropertiesWrapper p) { - autofetchConfig.loadSettings(p); - } - - /** - * Load the configuration settings from the properties file. - */ - protected void loadSettings(PropertiesWrapper p) { - - namingConvention = createNamingConvention(p, namingConvention); - if (namingConvention != null) { - namingConvention.loadFromProperties(p); - } - if (autofetchConfig == null) { - autofetchConfig = new AutofetchConfig(); - } - loadAutofetchSettings(p); - - if (dataSourceConfig == null) { - dataSourceConfig = new DataSourceConfig(); - } - loadDataSourceSettings(p); - - autoCommitMode = p.getBoolean("autoCommitMode", autoCommitMode); - useJtaTransactionManager = p.getBoolean("useJtaTransactionManager", useJtaTransactionManager); - - databasePlatform = createInstance(p, DatabasePlatform.class, "databasePlatform"); - encryptKeyManager = createInstance(p, EncryptKeyManager.class, "encryptKeyManager"); - encryptDeployManager = createInstance(p, EncryptDeployManager.class, "encryptDeployManager"); - encryptor = createInstance(p, Encryptor.class, "encryptor"); - dbEncrypt = createInstance(p, DbEncrypt.class, "dbEncrypt"); - serverCacheFactory = createInstance(p, ServerCacheFactory.class, "serverCacheFactory"); - serverCacheManager = createInstance(p, ServerCacheManager.class, "serverCacheManager"); - cacheWarmingDelay = p.getInt("cacheWarmingDelay", cacheWarmingDelay); - classPathReaderClassName = p.get("classpathreader"); - - String jarsProp = p.get("search.jars", p.get("jars", null)); - if (jarsProp != null) { - searchJars = getSearchJarsPackages(jarsProp); - } - - if (packages != null) { - String packagesProp = p.get("search.packages", p.get("packages", null)); - packages = getSearchJarsPackages(packagesProp); - } - - collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode); - collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins); - - updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly); - - boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren); - updatesDeleteMissingChildren = p.getBoolean("updatesDeleteMissingChildren", defaultDeleteMissingChildren); - - if (p.get("batch.mode") != null || p.get("persistBatching") != null) { - throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'"); - } - - persistBatch = p.getEnum(PersistBatch.class, "persistBatch", persistBatch); - persistBatchOnCascade = p.getEnum(PersistBatch.class, "persistBatchOnCascade", persistBatchOnCascade); - - int batchSize = p.getInt("batch.size", persistBatchSize); - persistBatchSize = p.getInt("persistBatchSize", batchSize); - - persistenceContextScope = PersistenceContextScope.valueOf(p.get("persistenceContextScope","TRANSACTION")); - - dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName); - databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize); - databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue); - databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse); - databasePlatformName = p.get("databasePlatformName", databasePlatformName); - uuidStoreAsBinary = p.getBoolean("uuidStoreAsBinary", uuidStoreAsBinary); - localTimeWithNanos = p.getBoolean("localTimeWithNanos", localTimeWithNanos); - - lazyLoadBatchSize = p.getInt("lazyLoadBatchSize", lazyLoadBatchSize); - queryBatchSize = p.getInt("queryBatchSize", queryBatchSize); - - String jsonDateTimeFormat = p.get("jsonDateTime", null); - if (jsonDateTimeFormat != null) { - jsonDateTime = JsonConfig.DateTime.valueOf(jsonDateTimeFormat); - } else { - jsonDateTime = JsonConfig.DateTime.MILLIS; - } - - ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate); - ddlRun = p.getBoolean("ddl.run", ddlRun); - - classes = getClasses(p); - } - - private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) { - - NamingConvention nc = createInstance(properties, NamingConvention.class, "namingconvention"); - return (nc != null) ? nc : namingConvention; - } - - /** - * Build the list of classes from the comma delimited string. - * - * @param properties - * the properties - * - * @return the classes - */ - private List> getClasses(PropertiesWrapper properties) { - - String classNames = properties.get("classes", null); - if (classNames == null) { - - return null; - } - - List> classes = new ArrayList>(); - - String[] split = classNames.split("[ ,;]"); - for (int i = 0; i < split.length; i++) { - String cn = split[i].trim(); - if (cn.length() > 0 && !"class".equalsIgnoreCase(cn)) { - try { - classes.add(Class.forName(cn)); - } catch (ClassNotFoundException e) { - String msg = "Error registering class [" + cn + "] from [" + classNames + "]"; - throw new RuntimeException(msg, e); - } - } - } - return classes; - } - - private List getSearchJarsPackages(String searchPackages) { - - List hitList = new ArrayList(); - - if (searchPackages != null) { - - String[] entries = searchPackages.split("[ ,;]"); - for (int i = 0; i < entries.length; i++) { - hitList.add(entries[i].trim()); - } - } - return hitList; - } - - /** - * Return the PersistBatch mode to use for 'batchOnCascade' taking into account if the database - * platform supports getGeneratedKeys in batch mode. - *

- * Used to effectively turn off batchOnCascade for SQL Server - still allows explicit batch mode. - *

- */ - public PersistBatch appliedPersistBatchOnCascade() { - - return databasePlatform.isDisallowBatchOnCascade() ? PersistBatch.NONE : persistBatchOnCascade; - } -} +package com.avaje.ebean.config; + +import com.avaje.ebean.EbeanServerFactory; +import com.avaje.ebean.PersistenceContextScope; +import com.avaje.ebean.annotation.Encrypted; +import com.avaje.ebean.cache.ServerCacheFactory; +import com.avaje.ebean.cache.ServerCacheManager; +import com.avaje.ebean.config.dbplatform.DatabasePlatform; +import com.avaje.ebean.config.dbplatform.DbEncrypt; +import com.avaje.ebean.event.*; +import com.avaje.ebean.meta.MetaInfoManager; +import com.avaje.ebean.util.ClassUtil; +import com.fasterxml.jackson.core.JsonFactory; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * The configuration used for creating a EbeanServer. + *

+ * Used to programmatically construct an EbeanServer and optionally register it + * with the Ebean singleton. + *

+ *

+ * If you just use Ebean without this programmatic configuration Ebean will read + * the ebean.properties file and take the configuration from there. This usually + * includes searching the class path and automatically registering any entity + * classes and listeners etc. + *

+ * + *
{@code
+ * ServerConfig c = new ServerConfig();
+ * c.setName("ordh2");
+ * 
+ * // read the ebean.properties and load
+ * // those settings into this serverConfig object
+ * c.loadFromProperties();
+ * 
+ * // generate DDL and run it
+ * c.setDdlGenerate(true);
+ * c.setDdlRun(true);
+ * 
+ * // add any classes found in the app.data package
+ * c.addPackage("app.data");
+ * 
+ * // add the names of Jars that contain entities
+ * c.addJar("myJarContainingEntities.jar");
+ * c.addJar("someOtherJarContainingEntities.jar");
+ * 
+ * // register as the 'Default' server
+ * c.setDefaultServer(true);
+ * 
+ * EbeanServer server = EbeanServerFactory.create(c);
+ * 
+ * }
+ * + * @see EbeanServerFactory + * + * @author emcgreal + * @author rbygrave + */ +public class ServerConfig { + + /** + * The EbeanServer name. + */ + private String name; + + private ContainerConfig containerConfig; + + /** + * The resource directory. + */ + private String resourceDirectory; + + /** + * Set to true to register this EbeanServer with the Ebean singleton. + */ + private boolean register = true; + + /** + * Set to true if this is the default/primary server. + */ + private boolean defaultServer; + + /** + * List of interesting classes such as entities, embedded, ScalarTypes, + * Listeners, Finders, Controllers etc. + */ + private List> classes = new ArrayList>(); + + /** + * The packages that are searched for interesting classes. Only used when + * classes is empty/not explicitly specified. + */ + private List packages = new ArrayList(); + + /** + * The names of Jar files that are searched for entities and other interesting + * classes. Only used when classes is empty/not explicitly specified. + */ + private List searchJars = new ArrayList(); + + /** + * Class name of a classPathReader implementation. + */ + private String classPathReaderClassName; + + /** + * Config controlling the autofetch behaviour. + */ + private AutofetchConfig autofetchConfig = new AutofetchConfig(); + + /** + * The JSON format used for DateTime types. Default to millis. + */ + private JsonConfig.DateTime jsonDateTime = JsonConfig.DateTime.MILLIS; + + /** + * The database platform name. Used to imply a DatabasePlatform to use. + */ + private String databasePlatformName; + + /** + * The database platform. + */ + private DatabasePlatform databasePlatform; + + /** + * For DB's using sequences this is the number of sequence values prefetched. + */ + private int databaseSequenceBatchSize = 20; + + /** + * Use for transaction scoped batch mode. + */ + private PersistBatch persistBatch = PersistBatch.NONE; + + /** + * Use for per request batch mode. + */ + private PersistBatch persistBatchOnCascade = PersistBatch.NONE; + + private int persistBatchSize = 20; + + /** + * The default batch size for lazy loading + */ + private int lazyLoadBatchSize = 10; + + /** + * The default batch size for 'query joins'. + */ + private int queryBatchSize = 100; + + private boolean eagerFetchLobs; + + private boolean ddlGenerate; + + private boolean ddlRun; + + private boolean useJtaTransactionManager; + + /** + * The external transaction manager (like Spring). + */ + private ExternalTransactionManager externalTransactionManager; + + /** + * Used to unwrap PreparedStatements to perform JDBC Driver specific functions + */ + private PstmtDelegate pstmtDelegate; + + /** + * The data source (if programmatically provided). + */ + private DataSource dataSource; + + /** + * The data source config. + */ + private DataSourceConfig dataSourceConfig = new DataSourceConfig(); + + /** + * Set to true if the DataSource uses autoCommit. + *

+ * Indicates that Ebean should use autoCommit friendly Transactions and TransactionManager. + */ + private boolean autoCommitMode; + + /** + * The data source JNDI name if using a JNDI DataSource. + */ + private String dataSourceJndiName; + + /** + * The database boolean true value (typically either 1, T, or Y). + */ + private String databaseBooleanTrue; + + /** + * The database boolean false value (typically either 0, F or N). + */ + private String databaseBooleanFalse; + + /** + * The naming convention. + */ + private NamingConvention namingConvention = new UnderscoreNamingConvention(); + + /** + * Behaviour of update to include on the change properties. + */ + private boolean updateChangesOnly = true; + + /** + * Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children. + */ + private boolean updatesDeleteMissingChildren = true; + + /** + * Setting to indicate if UUID should be stored as binary(16) or varchar(40). + */ + private boolean uuidStoreAsBinary; + + + private List persistControllers = new ArrayList(); + private List persistListeners = new ArrayList(); + private List queryAdapters = new ArrayList(); + private List bulkTableEventListeners = new ArrayList(); + private List configStartupListeners = new ArrayList(); + private List transactionEventListeners = new ArrayList(); + + private EncryptKeyManager encryptKeyManager; + + private EncryptDeployManager encryptDeployManager; + + private Encryptor encryptor; + + private DbEncrypt dbEncrypt; + + private ServerCacheFactory serverCacheFactory; + + private ServerCacheManager serverCacheManager; + + private boolean collectQueryStatsByNode = true; + + private boolean collectQueryOrigins = true; + + /** + * The default PersistenceContextScope used if one is not explicitly set on a query. + */ + private PersistenceContextScope persistenceContextScope = PersistenceContextScope.TRANSACTION; + + private JsonFactory jsonFactory; + + private boolean localTimeWithNanos; + + private boolean durationWithNanos; + + private int maxCallStack = 5; + + private boolean transactionRollbackOnChecked = true; + + private boolean registerJmxMBeans = true; + + // configuration for the background executor service (thread pool) + + private int backgroundExecutorSchedulePoolSize = 1; + private int backgroundExecutorCorePoolSize = 1; + private int backgroundExecutorMaxPoolSize = 8; + private int backgroundExecutorIdleSecs = 60; + private int backgroundExecutorShutdownSecs = 30; + + // defaults for the L2 bean caching + + private int cacheWarmingDelay = 30; + private int cacheMaxSize = 10000; + private int cacheMaxIdleTime = 600; + private int cacheMaxTimeToLive = 60*60*6; + + // defaults for the L2 query caching + + private int queryCacheMaxSize = 1000; + private int queryCacheMaxIdleTime = 600; + private int queryCacheMaxTimeToLive = 60*60*6; + + /** + * Construct a Server Configuration for programmatically creating an EbeanServer. + */ + public ServerConfig() { + + } + + /** + * Return the Jackson JsonFactory to use. + *

+ * If not set a default implmentation will be used. + */ + public JsonFactory getJsonFactory() { + return jsonFactory; + } + + /** + * Set the Jackson JsonFactory to use. + *

+ * If not set a default implmentation will be used. + */ + public void setJsonFactory(JsonFactory jsonFactory) { + this.jsonFactory = jsonFactory; + } + + /** + * Return the JSON format used for DateTime types. + */ + public JsonConfig.DateTime getJsonDateTime() { + return jsonDateTime; + } + + /** + * Set the JSON format to use for DateTime types. + */ + public void setJsonDateTime(JsonConfig.DateTime jsonDateTime) { + this.jsonDateTime = jsonDateTime; + } + + /** + * Return the name of the EbeanServer. + */ + public String getName() { + return name; + } + + /** + * Set the name of the EbeanServer. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Return the container / clustering configuration. + *

+ * The container holds all the EbeanServer instances and provides clustering communication + * services to all the EbeanServer instances. + */ + public ContainerConfig getContainerConfig() { + return containerConfig; + } + + /** + * Set the container / clustering configuration. + *

+ * The container holds all the EbeanServer instances and provides clustering communication + * services to all the EbeanServer instances. + */ + public void setContainerConfig(ContainerConfig containerConfig) { + this.containerConfig = containerConfig; + } + + /** + * Return true if this server should be registered with the Ebean singleton + * when it is created. + *

+ * By default this is set to true. + *

+ */ + public boolean isRegister() { + return register; + } + + /** + * Set to false if you do not want this server to be registered with the Ebean + * singleton when it is created. + *

+ * By default this is set to true. + *

+ */ + public void setRegister(boolean register) { + this.register = register; + } + + /** + * Return true if this server should be registered as the "default" server + * with the Ebean singleton. + *

+ * This is only used when {@link #setRegister(boolean)} is also true. + *

+ */ + public boolean isDefaultServer() { + return defaultServer; + } + + /** + * Set true if this EbeanServer should be registered as the "default" server + * with the Ebean singleton. + *

+ * This is only used when {@link #setRegister(boolean)} is also true. + *

+ */ + public void setDefaultServer(boolean defaultServer) { + this.defaultServer = defaultServer; + } + + /** + * Return the PersistBatch mode to use by default at the transaction level. + *

+ * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into + * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends + * or the batch size is meet. + *

+ */ + public PersistBatch getPersistBatch() { + return persistBatch; + } + + /** + * Set the JDBC batch mode to use at the transaction level. + *

+ * When INSERT or ALL is used then save(), delete() etc do not execute immediately but instead go into + * a JDBC batch execute buffer that is flushed. The buffer is flushed if a query is executed, transaction ends + * or the batch size is meet. + *

+ */ + public void setPersistBatch(PersistBatch persistBatch) { + this.persistBatch = persistBatch; + } + + /** + * Return the JDBC batch mode to use per save(), delete(), insert() or update() request. + *

+ * This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase + * for this is when saving a master/parent bean this cascade inserts many detail/child beans. + *

+ *

+ * This only takes effect when the persistBatch mode at the transaction level does not take effect. + *

+ */ + public PersistBatch getPersistBatchOnCascade() { + return persistBatchOnCascade; + } + + /** + * Set the JDBC batch mode to use per save(), delete(), insert() or update() request. + *

+ * This makes sense when a save() or delete() etc cascades and executes multiple child statements. The best caase + * for this is when saving a master/parent bean this cascade inserts many detail/child beans. + *

+ *

+ * This only takes effect when the persistBatch mode at the transaction level does not take effect. + *

+ */ + public void setPersistBatchOnCascade(PersistBatch persistBatchOnCascade) { + this.persistBatchOnCascade = persistBatchOnCascade; + } + + /** + * Deprecated, please migrate to using setPersistBatch(). + *

+ * Set to true if you what to use JDBC batching for persisting and deleting + * beans. + *

+ *

+ * With this Ebean will batch up persist requests and use the JDBC batch api. + * This is a performance optimisation designed to reduce the network chatter. + *

+ *

+ * When true this is equivalent to {@code setPersistBatch(PersistBatch.ALL)} or + * when false to {@code setPersistBatch(PersistBatch.NONE)} + *

+ */ + public void setPersistBatching(boolean persistBatching) { + this.persistBatch = (persistBatching) ? PersistBatch.ALL : PersistBatch.NONE; + } + + /** + * Return the batch size used for JDBC batching. This defaults to 20. + */ + public int getPersistBatchSize() { + return persistBatchSize; + } + + /** + * Set the batch size used for JDBC batching. If unset this defaults to 20. + *

+ * You can also set the batch size on the transaction. + *

+ * @see com.avaje.ebean.Transaction#setBatchSize(int) + */ + public void setPersistBatchSize(int persistBatchSize) { + this.persistBatchSize = persistBatchSize; + } + + /** + * Gets the query batch size. This defaults to 100. + * + * @return the query batch size + */ + public int getQueryBatchSize() { + return queryBatchSize; + } + + /** + * Sets the query batch size. This defaults to 100. + * + * @param queryBatchSize + * the new query batch size + */ + public void setQueryBatchSize(int queryBatchSize) { + this.queryBatchSize = queryBatchSize; + } + + /** + * Return the default batch size for lazy loading of beans and collections. + */ + public int getLazyLoadBatchSize() { + return lazyLoadBatchSize; + } + + /** + * Set the default batch size for lazy loading. + *

+ * This is the number of beans or collections loaded when lazy loading is + * invoked by default. + *

+ *

+ * The default value is for this is 10 (load 10 beans or collections). + *

+ *

+ * You can explicitly control the lazy loading batch size for a given join on + * a query using +lazy(batchSize) or JoinConfig. + *

+ */ + public void setLazyLoadBatchSize(int lazyLoadBatchSize) { + this.lazyLoadBatchSize = lazyLoadBatchSize; + } + + /** + * Set the number of sequences to fetch/preallocate when using DB sequences. + *

+ * This is a performance optimisation to reduce the number times Ebean + * requests a sequence to be used as an Id for a bean (aka reduce network + * chatter). + *

+ */ + public void setDatabaseSequenceBatchSize(int databaseSequenceBatchSize) { + this.databaseSequenceBatchSize = databaseSequenceBatchSize; + } + + /** + * Return true if we are running in a JTA Transaction manager. + */ + public boolean isUseJtaTransactionManager() { + return useJtaTransactionManager; + } + + /** + * Set to true if we are running in a JTA Transaction manager. + */ + public void setUseJtaTransactionManager(boolean useJtaTransactionManager) { + this.useJtaTransactionManager = useJtaTransactionManager; + } + + /** + * Return the external transaction manager. + */ + public ExternalTransactionManager getExternalTransactionManager() { + return externalTransactionManager; + } + + /** + * Set the external transaction manager. + */ + public void setExternalTransactionManager(ExternalTransactionManager externalTransactionManager) { + this.externalTransactionManager = externalTransactionManager; + } + + /** + * Return the ServerCacheFactory. + */ + public ServerCacheFactory getServerCacheFactory() { + return serverCacheFactory; + } + + /** + * Set the ServerCacheFactory to use. + */ + public void setServerCacheFactory(ServerCacheFactory serverCacheFactory) { + this.serverCacheFactory = serverCacheFactory; + } + + /** + * Return the ServerCacheManager. + */ + public ServerCacheManager getServerCacheManager() { + return serverCacheManager; + } + + /** + * Set the ServerCacheManager to use. + */ + public void setServerCacheManager(ServerCacheManager serverCacheManager) { + this.serverCacheManager = serverCacheManager; + } + + /** + * Return true if LOB's should default to fetch eager. + * By default this is set to false and LOB's must be explicitly fetched. + */ + public boolean isEagerFetchLobs() { + return eagerFetchLobs; + } + + /** + * Set to true if you want LOB's to be fetch eager by default. + * By default this is set to false and LOB's must be explicitly fetched. + */ + public void setEagerFetchLobs(boolean eagerFetchLobs) { + this.eagerFetchLobs = eagerFetchLobs; + } + + /** + * Return the max call stack to use for origin location. + */ + public int getMaxCallStack() { + return maxCallStack; + } + + /** + * Set the max call stack to use for origin location. + */ + public void setMaxCallStack(int maxCallStack) { + this.maxCallStack = maxCallStack; + } + + /** + * Return true if transactions should rollback on checked exceptions. + */ + public boolean isTransactionRollbackOnChecked() { + return transactionRollbackOnChecked; + } + + /** + * Set to true if transactions should by default rollback on checked exceptions. + */ + public void setTransactionRollbackOnChecked(boolean transactionRollbackOnChecked) { + this.transactionRollbackOnChecked = transactionRollbackOnChecked; + } + + /** + * Return true if the server should register JMX MBeans. + */ + public boolean isRegisterJmxMBeans() { + return registerJmxMBeans; + } + + /** + * Set if the server should register JMX MBeans. + */ + public void setRegisterJmxMBeans(boolean registerJmxMBeans) { + this.registerJmxMBeans = registerJmxMBeans; + } + + /** + * Return the Background executor schedule pool size. Defaults to 1. + */ + public int getBackgroundExecutorSchedulePoolSize() { + return backgroundExecutorSchedulePoolSize; + } + + /** + * Set the Background executor schedule pool size. + */ + public void setBackgroundExecutorSchedulePoolSize(int backgroundExecutorSchedulePoolSize) { + this.backgroundExecutorSchedulePoolSize = backgroundExecutorSchedulePoolSize; + } + + /** + * Return the Background executor core pool size. + */ + public int getBackgroundExecutorCorePoolSize() { + return backgroundExecutorCorePoolSize; + } + + /** + * Set the Background executor core pool size. + */ + public void setBackgroundExecutorCorePoolSize(int backgroundExecutorCorePoolSize) { + this.backgroundExecutorCorePoolSize = backgroundExecutorCorePoolSize; + } + + /** + * Return the Background executor max pool size. + */ + public int getBackgroundExecutorMaxPoolSize() { + return backgroundExecutorMaxPoolSize; + } + + /** + * Set the Background executor max pool size. + */ + public void setBackgroundExecutorMaxPoolSize(int backgroundExecutorMaxPoolSize) { + this.backgroundExecutorMaxPoolSize = backgroundExecutorMaxPoolSize; + } + + /** + * Return the Background executor idle seconds. + */ + public int getBackgroundExecutorIdleSecs() { + return backgroundExecutorIdleSecs; + } + + /** + * Set the Background executor idle seconds. + */ + public void setBackgroundExecutorIdleSecs(int backgroundExecutorIdleSecs) { + this.backgroundExecutorIdleSecs = backgroundExecutorIdleSecs; + } + + /** + * Return the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely + * before it is forced shutdown. + */ + public int getBackgroundExecutorShutdownSecs() { + return backgroundExecutorShutdownSecs; + } + + /** + * Set the Background executor shutdown seconds. This is the time allowed for the pool to shutdown nicely + * before it is forced shutdown. + */ + public void setBackgroundExecutorShutdownSecs(int backgroundExecutorShutdownSecs) { + this.backgroundExecutorShutdownSecs = backgroundExecutorShutdownSecs; + } + + /** + * Return the cache warming delay in seconds. + */ + public int getCacheWarmingDelay() { + return cacheWarmingDelay; + } + + /** + * Set the cache warming delay in seconds. + */ + public void setCacheWarmingDelay(int cacheWarmingDelay) { + this.cacheWarmingDelay = cacheWarmingDelay; + } + + /** + * Return the L2 cache default max size. + */ + public int getCacheMaxSize() { + return cacheMaxSize; + } + + /** + * Set the L2 cache default max size. + */ + public void setCacheMaxSize(int cacheMaxSize) { + this.cacheMaxSize = cacheMaxSize; + } + + /** + * Return the L2 cache default max idle time in seconds. + */ + public int getCacheMaxIdleTime() { + return cacheMaxIdleTime; + } + + /** + * Set the L2 cache default max idle time in seconds. + */ + public void setCacheMaxIdleTime(int cacheMaxIdleTime) { + this.cacheMaxIdleTime = cacheMaxIdleTime; + } + + /** + * Return the L2 cache default max time to live in seconds. + */ + public int getCacheMaxTimeToLive() { + return cacheMaxTimeToLive; + } + + /** + * Set the L2 cache default max time to live in seconds. + */ + public void setCacheMaxTimeToLive(int cacheMaxTimeToLive) { + this.cacheMaxTimeToLive = cacheMaxTimeToLive; + } + + /** + * Return the L2 query cache default max size. + */ + public int getQueryCacheMaxSize() { + return queryCacheMaxSize; + } + + /** + * Set the L2 query cache default max size. + */ + public void setQueryCacheMaxSize(int queryCacheMaxSize) { + this.queryCacheMaxSize = queryCacheMaxSize; + } + + /** + * Return the L2 query cache default max idle time in seconds. + */ + public int getQueryCacheMaxIdleTime() { + return queryCacheMaxIdleTime; + } + + /** + * Set the L2 query cache default max idle time in seconds. + */ + public void setQueryCacheMaxIdleTime(int queryCacheMaxIdleTime) { + this.queryCacheMaxIdleTime = queryCacheMaxIdleTime; + } + + /** + * Return the L2 query cache default max time to live in seconds. + */ + public int getQueryCacheMaxTimeToLive() { + return queryCacheMaxTimeToLive; + } + + /** + * Set the L2 query cache default max time to live in seconds. + */ + public void setQueryCacheMaxTimeToLive(int queryCacheMaxTimeToLive) { + this.queryCacheMaxTimeToLive = queryCacheMaxTimeToLive; + } + + /** + * Return the NamingConvention. + *

+ * If none has been set the default UnderscoreNamingConvention is used. + *

+ */ + public NamingConvention getNamingConvention() { + return namingConvention; + } + + /** + * Set the NamingConvention. + *

+ * If none is set the default UnderscoreNamingConvention is used. + *

+ */ + public void setNamingConvention(NamingConvention namingConvention) { + this.namingConvention = namingConvention; + } + + /** + * Return the configuration for the Autofetch feature. + */ + public AutofetchConfig getAutofetchConfig() { + return autofetchConfig; + } + + /** + * Set the configuration for the Autofetch feature. + */ + public void setAutofetchConfig(AutofetchConfig autofetchConfig) { + this.autofetchConfig = autofetchConfig; + } + + /** + * Return the PreparedStatementDelegate. + */ + public PstmtDelegate getPstmtDelegate() { + return pstmtDelegate; + } + + /** + * Set the PstmtDelegate which can be used to support JDBC driver specific + * features. + *

+ * Typically this means Oracle JDBC driver specific workarounds. + *

+ */ + public void setPstmtDelegate(PstmtDelegate pstmtDelegate) { + this.pstmtDelegate = pstmtDelegate; + } + + /** + * Return the DataSource. + */ + public DataSource getDataSource() { + return dataSource; + } + + /** + * Set a DataSource. + */ + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * Return the configuration to build a DataSource using Ebean's own DataSource + * implementation. + */ + public DataSourceConfig getDataSourceConfig() { + return dataSourceConfig; + } + + /** + * Set the configuration required to build a DataSource using Ebean's own + * DataSource implementation. + */ + public void setDataSourceConfig(DataSourceConfig dataSourceConfig) { + this.dataSourceConfig = dataSourceConfig; + } + + /** + * Return the JNDI name of the DataSource to use. + */ + public String getDataSourceJndiName() { + return dataSourceJndiName; + } + + /** + * Set the JNDI name of the DataSource to use. + *

+ * By default a prefix of "java:comp/env/jdbc/" is used to lookup the + * DataSource. This prefix is not used if dataSourceJndiName starts with + * "java:". + *

+ */ + public void setDataSourceJndiName(String dataSourceJndiName) { + this.dataSourceJndiName = dataSourceJndiName; + } + + /** + * Return true if autoCommit mode is on. This indicates to Ebean to use autoCommit friendly Transactions and TransactionManager. + */ + public boolean isAutoCommitMode() { + return autoCommitMode; + } + + /** + * Set to true if autoCommit mode is on and Ebean should use autoCommit friendly Transactions and TransactionManager. + */ + public void setAutoCommitMode(boolean autoCommitMode) { + this.autoCommitMode = autoCommitMode; + } + + /** + * Return a value used to represent TRUE in the database. + *

+ * This is used for databases that do not support boolean natively. + *

+ *

+ * The value returned is either a Integer or a String (e.g. "1", or "T"). + *

+ */ + public String getDatabaseBooleanTrue() { + return databaseBooleanTrue; + } + + /** + * Set the value to represent TRUE in the database. + *

+ * This is used for databases that do not support boolean natively. + *

+ *

+ * The value set is either a Integer or a String (e.g. "1", or "T"). + *

+ */ + public void setDatabaseBooleanTrue(String databaseTrue) { + this.databaseBooleanTrue = databaseTrue; + } + + /** + * Return a value used to represent FALSE in the database. + *

+ * This is used for databases that do not support boolean natively. + *

+ *

+ * The value returned is either a Integer or a String (e.g. "0", or "F"). + *

+ */ + public String getDatabaseBooleanFalse() { + return databaseBooleanFalse; + } + + /** + * Set the value to represent FALSE in the database. + *

+ * This is used for databases that do not support boolean natively. + *

+ *

+ * The value set is either a Integer or a String (e.g. "0", or "F"). + *

+ */ + public void setDatabaseBooleanFalse(String databaseFalse) { + this.databaseBooleanFalse = databaseFalse; + } + + /** + * Return the number of DB sequence values that should be preallocated. + */ + public int getDatabaseSequenceBatchSize() { + return databaseSequenceBatchSize; + } + + /** + * Set the number of DB sequence values that should be preallocated and cached + * by Ebean. + *

+ * This is only used for DB's that use sequences and is a performance + * optimisation. This reduces the number of times Ebean needs to get a + * sequence value from the Database reducing network chatter. + *

+ *

+ * By default this value is 10 so when we need another Id (and don't have one + * in our cache) Ebean will fetch 10 id's from the database. Note that when + * the cache drops to have full (which is 5 by default) Ebean will fetch + * another batch of Id's in a background thread. + *

+ */ + public void setDatabaseSequenceBatch(int databaseSequenceBatchSize) { + this.databaseSequenceBatchSize = databaseSequenceBatchSize; + } + + /** + * Return the database platform name (can be null). + *

+ * If null then the platform is determined automatically via the JDBC driver + * information. + *

+ */ + public String getDatabasePlatformName() { + return databasePlatformName; + } + + /** + * Explicitly set the database platform name + *

+ * If none is set then the platform is determined automatically via the JDBC + * driver information. + *

+ *

+ * This can be used when the Database Platform can not be automatically + * detected from the JDBC driver (possibly 3rd party JDBC driver). It is also + * useful when you want to do offline DDL generation for a database platform + * that you don't have access to. + *

+ *

+ * Values are oracle, h2, postgres, mysql, mssqlserver2005. + *

+ * + * @see DataSourceConfig#setOffline(boolean) + */ + public void setDatabasePlatformName(String databasePlatformName) { + this.databasePlatformName = databasePlatformName; + } + + /** + * Return the database platform to use for this server. + */ + public DatabasePlatform getDatabasePlatform() { + return databasePlatform; + } + + /** + * Explicitly set the database platform to use. + *

+ * If none is set then the platform is determined via the databasePlatformName + * or automatically via the JDBC driver information. + *

+ */ + public void setDatabasePlatform(DatabasePlatform databasePlatform) { + this.databasePlatform = databasePlatform; + } + + /** + * Return the EncryptKeyManager. + */ + public EncryptKeyManager getEncryptKeyManager() { + return encryptKeyManager; + } + + /** + * Set the EncryptKeyManager. + *

+ * This is required when you want to use encrypted properties. + *

+ *

+ * You can also set this in ebean.proprerties: + *

+ * + *
+   * # set via ebean.properties
+   * 
+   * ebean.encryptKeyManager=com.avaje.tests.basic.encrypt.BasicEncyptKeyManager
+   * 
+ */ + public void setEncryptKeyManager(EncryptKeyManager encryptKeyManager) { + this.encryptKeyManager = encryptKeyManager; + } + + /** + * Return the EncryptDeployManager. + *

+ * This is optionally used to programmatically define which columns are + * encrypted instead of using the {@link Encrypted} Annotation. + *

+ */ + public EncryptDeployManager getEncryptDeployManager() { + return encryptDeployManager; + } + + /** + * Set the EncryptDeployManager. + *

+ * This is optionally used to programmatically define which columns are + * encrypted instead of using the {@link Encrypted} Annotation. + *

+ */ + public void setEncryptDeployManager(EncryptDeployManager encryptDeployManager) { + this.encryptDeployManager = encryptDeployManager; + } + + /** + * Return the Encryptor used to encrypt data on the java client side (as + * opposed to DB encryption functions). + */ + public Encryptor getEncryptor() { + return encryptor; + } + + /** + * Set the Encryptor used to encrypt data on the java client side (as opposed + * to DB encryption functions). + *

+ * Ebean has a default implementation that it will use if you do not set your + * own Encryptor implementation. + *

+ */ + public void setEncryptor(Encryptor encryptor) { + this.encryptor = encryptor; + } + + /** + * Return the DbEncrypt used to encrypt and decrypt properties. + *

+ * Note that if this is not set then the DbPlatform may already have a + * DbEncrypt set and that will be used. + *

+ */ + public DbEncrypt getDbEncrypt() { + return dbEncrypt; + } + + /** + * Set the DbEncrypt used to encrypt and decrypt properties. + *

+ * Note that if this is not set then the DbPlatform may already have a + * DbEncrypt set (H2, MySql, Postgres and Oracle platforms have a DbEncrypt) + *

+ */ + public void setDbEncrypt(DbEncrypt dbEncrypt) { + this.dbEncrypt = dbEncrypt; + } + + + /** + * Return true if UUID should be stored as binary(16) (as opposed to varchar(40)). + */ + public boolean isUuidStoreAsBinary() { + return uuidStoreAsBinary; + } + + /** + * Set to true if UUID should be stored as binary(16) (as opposed to varchar(40)). + */ + public void setUuidStoreAsBinary(boolean uuidStoreAsBinary) { + this.uuidStoreAsBinary = uuidStoreAsBinary; + } + + /** + * Return true if LocalTime should be persisted with nanos precision. + */ + public boolean isLocalTimeWithNanos() { + return localTimeWithNanos; + } + + /** + * Set to true if LocalTime should be persisted with nanos precision. + *

+ * Otherwise it is persisted using java.sql.Time which is seconds precision. + *

+ */ + public void setLocalTimeWithNanos(boolean localTimeWithNanos) { + this.localTimeWithNanos = localTimeWithNanos; + } + + /** + * Return true if Duration should be persisted with nanos precision (SQL DECIMAL). + *

+ * Otherwise it is persisted with second precision (SQL INTEGER). + *

+ */ + public boolean isDurationWithNanos() { + return durationWithNanos; + } + + /** + * Set to true if Duration should be persisted with nanos precision (SQL DECIMAL). + *

+ * Otherwise it is persisted with second precision (SQL INTEGER). + *

+ */ + public void setDurationWithNanos(boolean durationWithNanos) { + this.durationWithNanos = durationWithNanos; + } + + /** + * Set to true to run the DDL generation on startup. + */ + public void setDdlGenerate(boolean ddlGenerate) { + this.ddlGenerate = ddlGenerate; + } + + /** + * Set to true to run the generated DDL on startup. + */ + public void setDdlRun(boolean ddlRun) { + this.ddlRun = ddlRun; + } + + /** + * Return true if the DDL should be generated. + */ + public boolean isDdlGenerate() { + return ddlGenerate; + } + + /** + * Return true if the DDL should be run. + */ + public boolean isDdlRun() { + return ddlRun; + } + + /** + * Programmatically add classes (typically entities) that this server should + * use. + *

+ * The class can be an Entity, Embedded type, ScalarType, BeanPersistListener, + * BeanFinder or BeanPersistController. + *

+ *

+ * If no classes are specified then the classes are found automatically via + * searching the class path. + *

+ *

+ * Alternatively the classes can be added via {@link #setClasses(List)}. + *

+ * + * @param cls + * the entity type (or other type) that should be registered by this + * server. + */ + public void addClass(Class cls) { + if (classes == null) { + classes = new ArrayList>(); + } + classes.add(cls); + } + + /** + * Add a package to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ */ + public void addPackage(String packageName) { + if (packages == null) { + packages = new ArrayList(); + } + packages.add(packageName); + } + + /** + * Return packages to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ */ + public List getPackages() { + return packages; + } + + /** + * Set packages to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ */ + public void setPackages(List packages) { + this.packages = packages; + } + + /** + * Add the name of a Jar to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ *

+ * If you are using ebean.properties you can specify jars to search by setting + * a ebean.search.jars property. + *

+ * + *
+   * # EBean will search through classes for entities, but will not search jar files 
+   * # unless you tell it to do so, for performance reasons.  Set this value to a 
+   * # comma-delimited list of jar files you want ebean to search.
+   * ebean.search.jars=example.jar
+   * 
+ */ + public void addJar(String jarName) { + if (searchJars == null) { + searchJars = new ArrayList(); + } + searchJars.add(jarName); + } + + /** + * Return packages to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ */ + public List getJars() { + return searchJars; + } + + /** + * Set the names of Jars to search for entities via class path search. + *

+ * This is only used if classes have not been explicitly specified. + *

+ */ + public void setJars(List searchJars) { + this.searchJars = searchJars; + } + + /** + * Return the class name of a classPathReader implementation. + */ + public String getClassPathReaderClassName() { + return classPathReaderClassName; + } + + /** + * Set the class name of a classPathReader implementation. + * + * Refer to server.util.ClassPathReader, this should really by a plugin but doing this for now + * to be relatively compatible with current implementation. + */ + public void setClassPathReaderClassName(String classPathReaderClassName) { + this.classPathReaderClassName = classPathReaderClassName; + } + + /** + * Set the list of classes (entities, listeners, scalarTypes etc) that should + * be used for this server. + *

+ * If no classes are specified then the classes are found automatically via + * searching the class path. + *

+ *

+ * Alternatively the classes can contain added via {@link #addClass(Class)}. + *

+ */ + public void setClasses(List> classes) { + this.classes = classes; + } + + /** + * Return the classes registered for this server. Typically this includes + * entities and perhaps listeners. + */ + public List> getClasses() { + return classes; + } + + /** + * Return true to only update changed properties. + */ + public boolean isUpdateChangesOnly() { + return updateChangesOnly; + } + + /** + * Set to true to only update changed properties. + */ + public void setUpdateChangesOnly(boolean updateChangesOnly) { + this.updateChangesOnly = updateChangesOnly; + } + + /** + * Return true if updates by default delete missing children when cascading save to a OneToMany or + * ManyToMany. When not set this defaults to true. + */ + public boolean isUpdatesDeleteMissingChildren() { + return updatesDeleteMissingChildren; + } + + /** + * Set if updates by default delete missing children when cascading save to a OneToMany or + * ManyToMany. When not set this defaults to true. + */ + public void setUpdatesDeleteMissingChildren(boolean updatesDeleteMissingChildren) { + this.updatesDeleteMissingChildren = updatesDeleteMissingChildren; + } + + /** + * Return true if the ebeanServer should collection query statistics by ObjectGraphNode. + */ + public boolean isCollectQueryStatsByNode() { + return collectQueryStatsByNode; + } + + /** + * Set to true to collection query execution statistics by ObjectGraphNode. + *

+ * These statistics can be used to highlight code/query 'origin points' that result in lots of lazy loading. + *

+ *

+ * It is considered safe/fine to have this set to true for production. + *

+ *

+ * This information can be later retrieved via {@link MetaInfoManager}. + *

+ * @see MetaInfoManager + */ + public void setCollectQueryStatsByNode(boolean collectQueryStatsByNode) { + this.collectQueryStatsByNode = collectQueryStatsByNode; + } + + /** + * Return true if query plans should also collect their 'origins'. This means for a given query plan you + * can identify the code/origin points where this query resulted from including lazy loading origins. + */ + public boolean isCollectQueryOrigins() { + return collectQueryOrigins; + } + + /** + * Set to true if query plans should collect their 'origin' points. This means for a given query plan you + * can identify the code/origin points where this query resulted from including lazy loading origins. + *

+ * This information can be later retrieved via {@link MetaInfoManager}. + *

+ * @see MetaInfoManager + */ + public void setCollectQueryOrigins(boolean collectQueryOrigins) { + this.collectQueryOrigins = collectQueryOrigins; + } + + /** + * Returns the resource directory. + */ + public String getResourceDirectory() { + return resourceDirectory; + } + + /** + * Sets the resource directory. + */ + public void setResourceDirectory(String resourceDirectory) { + this.resourceDirectory = resourceDirectory; + } + + /** + * Register a BeanQueryAdapter instance. + *

+ * Note alternatively you can use {@link #setQueryAdapters(List)} to set all + * the BeanQueryAdapter instances. + *

+ */ + public void add(BeanQueryAdapter beanQueryAdapter) { + queryAdapters.add(beanQueryAdapter); + } + + /** + * Return the BeanQueryAdapter instances. + */ + public List getQueryAdapters() { + return queryAdapters; + } + + /** + * Register all the BeanQueryAdapter instances. + *

+ * Note alternatively you can use {@link #add(BeanQueryAdapter)} to add + * BeanQueryAdapter instances one at a time. + *

+ */ + public void setQueryAdapters(List queryAdapters) { + this.queryAdapters = queryAdapters; + } + + /** + * Register a BeanPersistController instance. + *

+ * Note alternatively you can use {@link #setPersistControllers(List)} to set + * all the BeanPersistController instances. + *

+ */ + public void add(BeanPersistController beanPersistController) { + persistControllers.add(beanPersistController); + } + + /** + * Return the BeanPersistController instances. + */ + public List getPersistControllers() { + return persistControllers; + } + + /** + * Register all the BeanPersistController instances. + *

+ * Note alternatively you can use {@link #add(BeanPersistController)} to add + * BeanPersistController instances one at a time. + *

+ */ + public void setPersistControllers(List persistControllers) { + this.persistControllers = persistControllers; + } + + /** + * Register a TransactionEventListener instance + *

+ * Note alternatively you can use {@link #setTransactionEventListeners(List)} + * to set all the TransactionEventListener instances. + *

+ */ + public void add(TransactionEventListener listener) { + transactionEventListeners.add(listener); + } + + /** + * Return the TransactionEventListener instances. + */ + public List getTransactionEventListeners() { + return transactionEventListeners; + } + + /** + * Register all the TransactionEventListener instances. + *

+ * Note alternatively you can use {@link #add(TransactionEventListener)} to + * add TransactionEventListener instances one at a time. + *

+ */ + public void setTransactionEventListeners(List transactionEventListeners) { + this.transactionEventListeners = transactionEventListeners; + } + + /** + * Register a BeanPersistListener instance. + *

+ * Note alternatively you can use {@link #setPersistListeners(List)} to set + * all the BeanPersistListener instances. + *

+ */ + public void add(BeanPersistListener beanPersistListener) { + persistListeners.add(beanPersistListener); + } + + /** + * Return the BeanPersistListener instances. + */ + public List getPersistListeners() { + return persistListeners; + } + + /** + * Add a BulkTableEventListener + */ + public void add(BulkTableEventListener bulkTableEventListener) { + bulkTableEventListeners.add(bulkTableEventListener); + } + + /** + * Return the list of BulkTableEventListener instances. + */ + public List getBulkTableEventListeners() { + return bulkTableEventListeners; + } + + /** + * Add a ServerConfigStartup. + */ + public void addServerConfigStartup(ServerConfigStartup configStartupListener) { + configStartupListeners.add(configStartupListener); + } + + /** + * Return the list of ServerConfigStartup instances. + */ + public List getServerConfigStartupListeners() { + return configStartupListeners; + } + + /** + * Register all the BeanPersistListener instances. + *

+ * Note alternatively you can use {@link #add(BeanPersistListener)} to add + * BeanPersistListener instances one at a time. + *

+ */ + public void setPersistListeners(List persistListeners) { + this.persistListeners = persistListeners; + } + + /** + * Return the default PersistenceContextScope to be used if one is not explicitly set on a query. + *

+ * The PersistenceContextScope can specified on each query via {@link com.avaje.ebean + * .Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope)}. If it + * is not set on the query this default scope is used. + * + * @see com.avaje.ebean.Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope) + */ + public PersistenceContextScope getPersistenceContextScope() { + // if somehow null return TRANSACTION scope + return persistenceContextScope == null ? PersistenceContextScope.TRANSACTION : persistenceContextScope; + } + + /** + * Set the PersistenceContext scope to be used if one is not explicitly set on a query. + *

+ * This defaults to {@link PersistenceContextScope#TRANSACTION}. + *

+ * The PersistenceContextScope can specified on each query via {@link com.avaje.ebean + * .Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope)}. If it + * is not set on the query this scope is used. + * + * @see com.avaje.ebean.Query#setPersistenceContextScope(com.avaje.ebean.PersistenceContextScope) + */ + public void setPersistenceContextScope(PersistenceContextScope persistenceContextScope) { + this.persistenceContextScope = persistenceContextScope; + } + + /** + * Load settings from ebean.properties. + */ + public void loadFromProperties() { + loadFromProperties(PropertyMap.defaultProperties()); + } + + /** + * Load the settings from the given properties + */ + public void loadFromProperties(Properties properties) { + PropertiesWrapper p = new PropertiesWrapper("ebean", name, properties); + loadSettings(p); + } + + + @SuppressWarnings("unchecked") + private T createInstance(PropertiesWrapper p, Class pluginType, String key) { + + String classname = p.get(key, null); + return classname == null ? null : (T) ClassUtil.newInstance(classname); + } + + /** + * loads the data source settings to preserve existing behaviour. IMHO, if someone has set the datasource config already, + * they don't want the settings to be reloaded and reset. This allows a descending class to override this behaviour and prevent it + * from happening. + * + * @param p - The defined property source passed to load settings + */ + protected void loadDataSourceSettings(PropertiesWrapper p) { + dataSourceConfig.loadSettings(p.withPrefix("datasource")); + } + + /** + * This is broken out for the same reason as above - preserve existing behaviour but let it be overridden. + */ + protected void loadAutofetchSettings(PropertiesWrapper p) { + autofetchConfig.loadSettings(p); + } + + /** + * Load the configuration settings from the properties file. + */ + protected void loadSettings(PropertiesWrapper p) { + + namingConvention = createNamingConvention(p, namingConvention); + if (namingConvention != null) { + namingConvention.loadFromProperties(p); + } + if (autofetchConfig == null) { + autofetchConfig = new AutofetchConfig(); + } + loadAutofetchSettings(p); + + if (dataSourceConfig == null) { + dataSourceConfig = new DataSourceConfig(); + } + loadDataSourceSettings(p); + + autoCommitMode = p.getBoolean("autoCommitMode", autoCommitMode); + useJtaTransactionManager = p.getBoolean("useJtaTransactionManager", useJtaTransactionManager); + + databasePlatform = createInstance(p, DatabasePlatform.class, "databasePlatform"); + encryptKeyManager = createInstance(p, EncryptKeyManager.class, "encryptKeyManager"); + encryptDeployManager = createInstance(p, EncryptDeployManager.class, "encryptDeployManager"); + encryptor = createInstance(p, Encryptor.class, "encryptor"); + dbEncrypt = createInstance(p, DbEncrypt.class, "dbEncrypt"); + serverCacheFactory = createInstance(p, ServerCacheFactory.class, "serverCacheFactory"); + serverCacheManager = createInstance(p, ServerCacheManager.class, "serverCacheManager"); + cacheWarmingDelay = p.getInt("cacheWarmingDelay", cacheWarmingDelay); + classPathReaderClassName = p.get("classpathreader"); + + String jarsProp = p.get("search.jars", p.get("jars", null)); + if (jarsProp != null) { + searchJars = getSearchJarsPackages(jarsProp); + } + + if (packages != null) { + String packagesProp = p.get("search.packages", p.get("packages", null)); + packages = getSearchJarsPackages(packagesProp); + } + + collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode); + collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins); + + updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly); + + boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren); + updatesDeleteMissingChildren = p.getBoolean("updatesDeleteMissingChildren", defaultDeleteMissingChildren); + + if (p.get("batch.mode") != null || p.get("persistBatching") != null) { + throw new IllegalArgumentException("Property 'batch.mode' or 'persistBatching' is being set but no longer used. Please change to use 'persistBatchMode'"); + } + + persistBatch = p.getEnum(PersistBatch.class, "persistBatch", persistBatch); + persistBatchOnCascade = p.getEnum(PersistBatch.class, "persistBatchOnCascade", persistBatchOnCascade); + + int batchSize = p.getInt("batch.size", persistBatchSize); + persistBatchSize = p.getInt("persistBatchSize", batchSize); + + persistenceContextScope = PersistenceContextScope.valueOf(p.get("persistenceContextScope","TRANSACTION")); + + dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName); + databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize); + databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue); + databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse); + databasePlatformName = p.get("databasePlatformName", databasePlatformName); + uuidStoreAsBinary = p.getBoolean("uuidStoreAsBinary", uuidStoreAsBinary); + localTimeWithNanos = p.getBoolean("localTimeWithNanos", localTimeWithNanos); + + lazyLoadBatchSize = p.getInt("lazyLoadBatchSize", lazyLoadBatchSize); + queryBatchSize = p.getInt("queryBatchSize", queryBatchSize); + + String jsonDateTimeFormat = p.get("jsonDateTime", null); + if (jsonDateTimeFormat != null) { + jsonDateTime = JsonConfig.DateTime.valueOf(jsonDateTimeFormat); + } else { + jsonDateTime = JsonConfig.DateTime.MILLIS; + } + + ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate); + ddlRun = p.getBoolean("ddl.run", ddlRun); + + classes = getClasses(p); + } + + private NamingConvention createNamingConvention(PropertiesWrapper properties, NamingConvention namingConvention) { + + NamingConvention nc = createInstance(properties, NamingConvention.class, "namingconvention"); + return (nc != null) ? nc : namingConvention; + } + + /** + * Build the list of classes from the comma delimited string. + * + * @param properties + * the properties + * + * @return the classes + */ + private List> getClasses(PropertiesWrapper properties) { + + String classNames = properties.get("classes", null); + if (classNames == null) { + + return null; + } + + List> classes = new ArrayList>(); + + String[] split = classNames.split("[ ,;]"); + for (int i = 0; i < split.length; i++) { + String cn = split[i].trim(); + if (cn.length() > 0 && !"class".equalsIgnoreCase(cn)) { + try { + classes.add(Class.forName(cn)); + } catch (ClassNotFoundException e) { + String msg = "Error registering class [" + cn + "] from [" + classNames + "]"; + throw new RuntimeException(msg, e); + } + } + } + return classes; + } + + private List getSearchJarsPackages(String searchPackages) { + + List hitList = new ArrayList(); + + if (searchPackages != null) { + + String[] entries = searchPackages.split("[ ,;]"); + for (int i = 0; i < entries.length; i++) { + hitList.add(entries[i].trim()); + } + } + return hitList; + } + + /** + * Return the PersistBatch mode to use for 'batchOnCascade' taking into account if the database + * platform supports getGeneratedKeys in batch mode. + *

+ * Used to effectively turn off batchOnCascade for SQL Server - still allows explicit batch mode. + *

+ */ + public PersistBatch appliedPersistBatchOnCascade() { + + return databasePlatform.isDisallowBatchOnCascade() ? PersistBatch.NONE : persistBatchOnCascade; + } +}