Compare commits

..
Author SHA1 Message Date
Robin Bygrave 9ea58572de [maven-release-plugin] prepare release avaje-ebeanorm-7.14.1 2016-06-17 22:27:04 +12:00
Robin Bygrave 35d82c9104 Bump pom to 7.14.1-SNAPSHOT 2016-06-17 22:26:06 +12:00
Robin Bygrave 31aae38616 #742 - ENH: DocStoreConfig ... read System properties for isGenerateMapping(), isDropCreate() and isCreate() 2016-06-17 22:25:11 +12:00
Robin Bygrave f144b53651 #741 - ENH: Add DocumentStore indexSettings() method ... for setting ElasticSearch refresh_interval 2016-06-17 22:21:22 +12:00
Robin Bygrave f47cd7e7c2 Add extra-dll.xml example for .... ENH: For @Index add support for index types (like Postgres GIN) #707 ... 2016-06-17 15:04:12 +12:00
Robin Bygrave 8765cb8356 No effective change - reformat code 2016-06-17 13:24:49 +12:00
Robin Bygrave 30abe75a96 Travis - enable caching .m2 2016-06-17 13:19:01 +12:00
Robin Bygrave 164e6c71c1 Travis - stop caching .m2 2016-06-17 13:15:42 +12:00
Robin Bygrave dfa6353850 #740 - ClassCastException: java.util.ArrayList cannot be cast to com.avaje.ebean.bean.BeanCollection at com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany.resetMany(BeanPropertyAssocMany.java:273) 2016-06-17 12:30:57 +12:00
Robin Bygrave d88ff2a3b2 #739 - UpdateQuery with idEq() expression gives wrong update statement (still has table alias) 2016-06-17 11:34:47 +12:00
Robin Bygrave 713ae75464 No effective change - reformat 2016-06-17 11:03:47 +12:00
Rob BygraveandGitHub 710fb0e947 Merge pull request #738 from DevFactory/staging/using-isempty-fix-1
Refactor: Use Collection.isEmpty() instead of size() comparison to 0 etc
2016-06-15 20:55:02 +12:00
Rob BygraveandGitHub cb0cf97f3f Merge pull request #736 from DevFactory/staging/make-public-static-fields-constant-fix-1
Updating "public static" fields to add final modifier
2016-06-15 20:46:37 +12:00
Artyom Melnikov 07edb2c81f Using Collection.isEmpty() to test for emptiness 2016-06-14 15:21:23 +03:00
Artyom Melnikov 066effa5bf "public static" fields should be constant 2016-06-14 14:18:18 +03:00
Robin Bygrave bb5ca6c56e Bump agent in pom to 4.11.1 2016-06-14 22:24:50 +12:00
Robin Bygrave a64a020e36 #734 - Add ServerConfig.skipCacheAfterWrite & transaction.setSkipCache(boolean) ... to control L2 Bean cache use during transaction 2016-06-10 17:59:37 +12:00
Robin Bygrave c24ee53462 [maven-release-plugin] prepare for next development iteration 2016-06-08 14:40:18 +12:00
Robin Bygrave 06e4bdca0e [maven-release-plugin] prepare release avaje-ebeanorm-7.13.1 2016-06-08 14:39:56 +12:00
Robin Bygrave 3dbf35aca4 Bump pom version to 7.13.1-SNAPSHOT 2016-06-08 14:38:47 +12:00
Robin Bygrave cd56b3ca3c #726 - L2 cache returns stale data -> change such that when using "local L2 caching" the changes to L2 cache propagate in foreground 2016-06-08 14:38:08 +12:00
Robin Bygrave 353175626d #733 - RawSqlBuilder.columnMapping() not working using DB column alias ... java.lang.IllegalArgumentException: DB Column [detail_count] not found in mapping. 2016-06-07 17:10:37 +12:00
Robin Bygrave 1a3acb86df #732 - NPE in ScalarTypeArrayList.read(ScalarTypeArrayList.java:89) ... 2016-06-03 08:09:04 +12:00
Robin Bygrave 1304646cce #731 - ENH: Add support for using ebean.mf manifest file for finding/defining packages to search for entities 2016-06-02 17:35:06 +12:00
Robin Bygrave b3828572fd No effective change - javadoc for ServerConfig 2016-06-02 14:08:00 +12:00
Robin Bygrave eddd48f8ad #730 - Remove unused ServerConfig.classPathReaderClassName ... as replaced by org.avaje.classpath.scanner.ClassPathScanner plugin (in 7.8.1) 2016-06-02 14:03:30 +12:00
Robin Bygrave 9797502ef2 #729 - Remove unused ServerConfig.addJar(...); serverConfig.setJars(...); ... as "search jars" is no longer used in classpath scanning (since 7.8.1) 2016-06-02 13:55:14 +12:00
Robin Bygrave daba7a11b4 No effective change - remove unused code (old ClassPathReader etc) 2016-06-01 20:53:07 +12:00
Robin Bygrave 92caf69cb3 #728 - Remove Query.where(String) ... migrate to where().raw(...) 2016-06-01 19:54:02 +12:00
Robin Bygrave 71f70c01ae #727 - ENH: Add endOr(), endAnd(), endNot() ... to ExpressionList as synonym for endJunction() 2016-06-01 16:03:30 +12:00
Robin Bygrave 74d7652044 [maven-release-plugin] prepare for next development iteration 2016-05-30 17:28:05 +12:00
Robin Bygrave d7ee748f31 [maven-release-plugin] prepare release avaje-ebeanorm-7.12.2 2016-05-30 17:27:43 +12:00
Robin Bygrave 2442eb017a #725 - L2 cache not updating CacheManyId's entry when Lazy loading on a ToMany relationship, after a prior update, when other ToMany is a vanilla type (like ArrayList) 2016-05-30 17:01:20 +12:00
Robin Bygrave 37ea56ad11 #724 - NPE when using L2 caching configured with @Cache with queryCaching=true and beanCaching=false 2016-05-30 16:56:04 +12:00
Robin Bygrave 067a8b784c No effective change - add test with where().raw() containing disjunction etc 2016-05-24 09:28:29 +12:00
Robin Bygrave b18922df79 [maven-release-plugin] prepare for next development iteration 2016-05-23 22:34:46 +12:00
98 changed files with 1956 additions and 1752 deletions
+5 -5
View File
@@ -9,7 +9,7 @@
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm</artifactId>
<version>7.12.1</version>
<version>7.14.1</version>
<packaging>jar</packaging>
<name>avaje-ebeanorm</name>
@@ -37,7 +37,7 @@
<scm>
<developerConnection>scm:git:https://github.com/ebean-orm/avaje-ebeanorm.git</developerConnection>
<tag>avaje-ebeanorm-7.12.1</tag>
<tag>avaje-ebeanorm-7.14.1</tag>
</scm>
<dependencies>
@@ -168,7 +168,7 @@
<dependency>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-agent</artifactId>
<version>4.10.1</version>
<version>4.11.1</version>
<scope>test</scope>
</dependency>
@@ -243,14 +243,14 @@
<plugin>
<groupId>org.avaje.ebeanorm</groupId>
<artifactId>avaje-ebeanorm-mavenenhancer</artifactId>
<version>4.10.1</version>
<version>4.11.1</version>
<executions>
<execution>
<id>test</id>
<phase>process-test-classes</phase>
<configuration>
<classSource>target/test-classes</classSource>
<packages>com.avaje.tests.**</packages>
<!--<packages>com.avaje.tests.**</packages>-->
<transformArgs>debug=1</transformArgs>
</configuration>
<goals>
@@ -5,6 +5,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* Document storage operations.
@@ -205,6 +206,39 @@ public interface DocumentStore {
*/
void createIndex(String indexName, String alias);
/**
* Modify the settings on an index.
* <p>
* For example, this can be used be used to set elasticSearch refresh_interval
* on an index before a bulk update.
* </p>
* <pre>{@code
*
* // refresh_interval -1 ... disable refresh while bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "-1");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* <pre>{@code
*
* // refresh_interval 1s ... restore after bulk loading
*
* Map<String,Object> settings = new LinkedHashMap<>();
* settings.put("refresh_interval", "1s");
*
* documentStore.indexSettings("product", settings);
*
* }</pre>
*
* @param indexName the name of the index to update settings on
* @param settings the settings to set on the index
*/
void indexSettings(String indexName, Map<String, Object> settings);
/**
* Copy the index to a new index.
* <p>
@@ -925,7 +925,7 @@ public interface ExpressionList<T> {
* This is exactly the same as conjunction();
* </p>
* <p>
* Use endJunction() to end the AND junction.
* Use endAnd() or endJunction() to end the AND junction.
* </p>
* <p>
* Note that a where() clause defaults to an AND junction so
@@ -943,11 +943,11 @@ public interface ExpressionList<T> {
* .and() // nested and
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .endAnd()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .endAnd()
* .orderBy().asc("name")
* .findList();
* }</pre>
@@ -959,7 +959,7 @@ public interface ExpressionList<T> {
* This is exactly the same as disjunction();
*
* <p>
* Use endJunction() to end the OR junction.
* Use endOr() or endJunction() to end the OR junction.
* </p>
*
* <pre>{@code
@@ -973,11 +973,11 @@ public interface ExpressionList<T> {
* .and()
* .startsWith("name", "r")
* .eq("anniversary", onAfter)
* .endJunction() // end AND junction
* .endAnd()
* .and()
* .eq("status", Customer.Status.ACTIVE)
* .gt("id", 0)
* .endJunction() // end AND junction
* .endAnd()
* .orderBy().asc("name")
* .findList();
*
@@ -988,7 +988,7 @@ public interface ExpressionList<T> {
/**
* Return a list of expressions that will be wrapped by NOT.
* <p>
* Use endJunction() to end expressions being added to the
* Use endNot() or endJunction() to end expressions being added to the
* NOT expression list.
* </p>
*
@@ -998,7 +998,7 @@ public interface ExpressionList<T> {
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
* .endNot()
*
* }</pre>
*
@@ -1012,7 +1012,7 @@ public interface ExpressionList<T> {
* .not()
* .gt("id", 1)
* .eq("anniversary", onAfter)
* .endJunction() // end the not expressions
* .endNot()
* .orderBy()
* .asc("name")
* .findList();
@@ -1085,4 +1085,19 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> endJunction();
/**
* End a AND junction - synonym for endJunction().
*/
ExpressionList<T> endAnd();
/**
* End a AND junction - synonym for endJunction().
*/
ExpressionList<T> endOr();
/**
* End a NOT junction - synonym for endJunction().
*/
ExpressionList<T> endNot();
}
-57
View File
@@ -917,40 +917,6 @@ public interface Query<T> {
*/
Object getId();
/**
* Add additional clause(s) to the where clause.
* <p>
* This typically contains named parameters which will need to be set via
* {@link #setParameter(String, Object)}.
* </p>
*
* <pre>{@code
*
* Query<Order> query = ebeanServer.createQuery(Order.class, "top");
* ...
* if (...) {
* query.where("status = :status and lower(customer.name) like :custName");
* query.setParameter("status", Order.NEW);
* query.setParameter("custName", "rob%");
* }
*
* }</pre>
*
* <p>
* Internally the addToWhereClause string is processed by removing named
* parameters (replacing them with ?) and by converting logical property names
* to database column names (with table alias). The rest of the string is left
* as is and it is completely acceptable and expected for the addToWhereClause
* string to include sql functions and columns.
* </p>
*
* @param addToWhereClause
* the clause to append to the where clause which typically contains
* named parameters.
* @return The query object
*/
Query<T> where(String addToWhereClause);
/**
* Add a single Expression to the where clause returning the query.
*
@@ -1061,29 +1027,6 @@ public interface Query<T> {
*/
ExpressionList<T> having();
/**
* Add additional clause(s) to the having clause.
* <p>
* This typically contains named parameters which will need to be set via
* {@link #setParameter(String, Object)}.
* </p>
*
* <pre>{@code
*
* List<ReportOrder> query =
* ebeanServer.find(ReportOrder.class)
* .having("score > :min").setParameter("min", 1)
* .findList();
*
* }</pre>
*
* @param addToHavingClause
* the clause to append to the having clause which typically contains
* named parameters.
* @return The query object
*/
Query<T> having(String addToHavingClause);
/**
* Add an expression to the having clause returning the query.
* <p>
+10 -10
View File
@@ -404,7 +404,7 @@ public final class RawSql implements Serializable {
this.dbColumnMap = new LinkedHashMap<String, Column>();
for (int i = 0; i < columns.size(); i++) {
Column c = columns.get(i);
dbColumnMap.put(c.getDbColumn(), c);
dbColumnMap.put(c.getDbColumnKey(), c);
}
}
@@ -500,8 +500,7 @@ public final class RawSql implements Serializable {
} else {
Column column = dbColumnMap.get(dbColumn);
if (column == null) {
String msg = "DB Column [" + dbColumn + "] not found in mapping. Expecting one of ["
+ dbColumnMap.keySet() + "]";
String msg = "DB Column [" + dbColumn + "] not found in mapping. Expecting one of [" + dbColumnMap.keySet() + "]";
throw new IllegalArgumentException(msg);
}
column.setPropertyName(propertyName);
@@ -657,6 +656,14 @@ public final class RawSql implements Serializable {
return indexPos;
}
/**
* Return the DB column alias if specified otherwise DB column.
* This is used as the key for mapping a column to a logical property.
*/
public String getDbColumnKey() {
return (dbAlias != null) ? dbAlias : dbColumn;
}
/**
* Return the DB column name including table alias (if it has one).
*/
@@ -664,13 +671,6 @@ public final class RawSql implements Serializable {
return dbColumn;
}
/**
* Return the DB column alias (if it has one).
*/
public String getDbAlias() {
return dbAlias;
}
/**
* Return the bean property this column is mapped to.
*/
+69 -3
View File
@@ -3,6 +3,7 @@ package com.avaje.ebean;
import com.avaje.ebean.annotation.DocStoreMode;
import com.avaje.ebean.config.DocStoreConfig;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.config.ServerConfig;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
@@ -125,13 +126,78 @@ public interface Transaction extends Closeable {
* Set to true when you want all loaded properties to be included in the update
* (rather than just the changed properties).
* <p>
* You might set this when using JDBC batch in order to get multiple updates
* with slightly different sets of changed properties into the same statement
* and hence better JDBC batch performance.
* You might set this when using JDBC batch in order to get multiple updates
* with slightly different sets of changed properties into the same statement
* and hence better JDBC batch performance.
* </p>
*/
void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties);
/**
* Set if the L2 cache should be skipped for "find by id" and "find by natural key" queries.
* <p>
* By default {@link ServerConfig#isSkipCacheAfterWrite()} is true and that means that for
* "find by id" and "find by natural key" queries which normally hit L2 bean cache automatically
* - will not do so after a persist/write on the transaction.
* </p>
* <p>
* This method provides explicit control over whether "find by id" and "find by natural key"
* will skip the L2 bean cache or not (regardless of whether the transaction is considered "read only").
* </p>
* <p>
* Refer to {@link ServerConfig#setSkipCacheAfterWrite(boolean)} for configuring the default behavior
* for using the L2 bean cache in transactions spanning multiple query/persist requests.
* </p>
*
* <pre>{@code
*
* // assume Customer has L2 bean caching enabled ...
*
* Transaction transaction = Ebean.beginTransaction();
* try {
*
* // this uses L2 bean cache as the transaction
* // ... is considered "query only" at this point
* Customer.find.byId(42);
*
* // transaction no longer "query only" once
* // ... a bean has been saved etc
* Ebean.save(someBean);
*
* // will NOT use L2 bean cache as the transaction
* // ... is no longer considered "query only"
* Customer.find.byId(55);
*
*
*
* // explicit control - please use L2 bean cache
*
* transaction.setSkipCache(false);
* Customer.find.byId(77); // hit the l2 bean cache
*
*
* // explicit control - please don't use L2 bean cache
*
* transaction.setSkipCache(true);
* Customer.find.byId(99); // skips l2 bean cache
*
*
* } finally {
* transaction.end();
* }
*
* }</pre>
*
* @see ServerConfig#isSkipCacheAfterWrite()
*/
void setSkipCache(boolean skipCache);
/**
* Return true if the L2 cache should be skipped. More accurately if true then find by id
* and find by natural key queries should NOT automatically use the L2 bean cache.
*/
boolean isSkipCache();
/**
* Turn on or off statement batching. Statement batching can be transparent
* for drivers and databases that support getGeneratedKeys. Otherwise you may
@@ -5,6 +5,15 @@ package com.avaje.ebean.cache;
*/
public interface ServerCacheManager {
/**
* Return true if the L2 caching is local.
* <p>
* Local L2 caching means that the cache updates should occur in foreground
* rather than background processing.
* </p>
*/
boolean isLocalL2Caching();
/**
* Return true if there is an active bean cache for this type of bean.
*/
@@ -83,7 +83,6 @@ public class DocStoreConfig {
if (systemValue != null) {
return systemValue;
}
return url;
}
@@ -100,6 +99,10 @@ public class DocStoreConfig {
* Return true if Ebean should generate mapping files on server startup.
*/
public boolean isGenerateMapping() {
String systemValue = System.getProperty("ebean.docstore.generateMapping");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return generateMapping;
}
@@ -114,6 +117,10 @@ public class DocStoreConfig {
* Return true if the document store should recreate mapped indexes.
*/
public boolean isDropCreate() {
String systemValue = System.getProperty("ebean.docstore.dropCreate");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return dropCreate;
}
@@ -129,6 +136,10 @@ public class DocStoreConfig {
* This is only used if dropCreate is false.
*/
public boolean isCreate() {
String systemValue = System.getProperty("ebean.docstore.create");
if (systemValue != null) {
return Boolean.parseBoolean(systemValue);
}
return create;
}
@@ -47,23 +47,16 @@ import java.util.ServiceLoader;
* </p>
*
* <pre>{@code
*
* ServerConfig c = new ServerConfig();
* c.setName("ordh2");
* c.setName("db");
*
* // 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");
* c.addPackage("com.myapp.domain");
*
* // register as the 'Default' server
* c.setDefaultServer(true);
@@ -128,17 +121,6 @@ public class ServerConfig {
*/
private List<String> packages = new ArrayList<String>();
/**
* 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<String> searchJars = new ArrayList<String>();
/**
* Class name of a classPathReader implementation.
*/
private String classPathReaderClassName;
/**
* Configuration for the ElasticSearch integration.
*/
@@ -238,6 +220,11 @@ public class ServerConfig {
private String ddlSeedSql;
/**
* When true L2 bean cache use is skipped after a write has occurred on a transaction.
*/
private boolean skipCacheAfterWrite = true;
private boolean useJtaTransactionManager;
/**
@@ -1790,67 +1777,6 @@ public class ServerConfig {
this.packages = packages;
}
/**
* Add the name of a Jar to search for entities via class path search.
* <p>
* This is only used if classes have not been explicitly specified.
* </p>
* <p>
* If you are using ebean.properties you can specify jars to search by setting
* a ebean.search.jars property.
* </p>
*
* <pre>{@code
* # 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
* }</pre>
*/
public void addJar(String jarName) {
if (searchJars == null) {
searchJars = new ArrayList<String>();
}
searchJars.add(jarName);
}
/**
* Return packages to search for entities via class path search.
* <p>
* This is only used if classes have not been explicitly specified.
* </p>
*/
public List<String> getJars() {
return searchJars;
}
/**
* Set the names of Jars to search for entities via class path search.
* <p>
* This is only used if classes have not been explicitly specified.
* </p>
*/
public void setJars(List<String> 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.
* <p>
* 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.
@@ -1874,6 +1800,66 @@ public class ServerConfig {
return classes;
}
/**
* Return true if L2 bean cache should be skipped once writes have occurred on a transaction.
* <p>
* This defaults to true and means that for "find by id" and "find by natural key"
* queries that normally hit L2 bean cache automatically will not do so after a write/persist
* on the transaction.
* </p>
*
* <pre>{@code
*
* // assume Customer has L2 bean caching enabled ...
*
* Transaction transaction = Ebean.beginTransaction();
* try {
*
* // this uses L2 bean cache as the transaction
* // ... is considered "query only" at this point
* Customer.find.byId(42);
*
* // transaction no longer "query only" once
* // ... a bean has been saved etc
* Ebean.save(someBean);
*
* // will NOT use L2 bean cache as the transaction
* // ... is no longer considered "query only"
* Customer.find.byId(55);
*
*
*
* // explicit control - please use L2 bean cache
*
* transaction.setSkipCache(false);
* Customer.find.byId(77); // hit the l2 bean cache
*
*
* // explicit control - please don't use L2 bean cache
*
* transaction.setSkipCache(true);
* Customer.find.byId(99); // skips l2 bean cache
*
*
* } finally {
* transaction.end();
* }
*
* }</pre>
*
* @see com.avaje.ebean.Transaction#setSkipCache(boolean)
*/
public boolean isSkipCacheAfterWrite() {
return skipCacheAfterWrite;
}
/**
* Set to false when we still want to hit the cache after a write has occurred on a transaction.
*/
public void setSkipCacheAfterWrite(boolean skipCacheAfterWrite) {
this.skipCacheAfterWrite = skipCacheAfterWrite;
}
/**
* Return true to only update changed properties.
*/
@@ -2382,12 +2368,6 @@ public class ServerConfig {
serverCachePlugin = createInstance(p, ServerCachePlugin.class, "serverCachePlugin", serverCachePlugin);
serverCacheManager = createInstance(p, ServerCacheManager.class, "serverCacheManager", 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));
@@ -2397,6 +2377,7 @@ public class ServerConfig {
collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode);
collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins);
skipCacheAfterWrite = p.getBoolean("skipCacheAfterWrite", skipCacheAfterWrite);
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
@@ -114,7 +114,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
public Object nextId(Transaction t) {
synchronized (monitor) {
if (idList.size() == 0) {
if (idList.isEmpty()) {
loadMoreIds(batchSize, t);
}
Long nextId = idList.remove(0);
@@ -193,7 +193,7 @@ public abstract class SequenceIdGenerator implements PlatformIdGenerator {
while (rset.next()) {
newIds.add(rset.getLong(1));
}
if (newIds.size() == 0) {
if (newIds.isEmpty()) {
throw new PersistenceException("Always expecting more than 1 row from " + sql);
}
@@ -105,6 +105,16 @@ public class ScopedTransaction implements SpiTransaction {
transaction.logSummary(msg);
}
@Override
public void setSkipCache(boolean skipCache) {
transaction.setSkipCache(skipCache);
}
@Override
public boolean isSkipCache() {
return transaction.isSkipCache();
}
@Override
public void addBeanChange(BeanChange beanChange) {
transaction.addBeanChange(beanChange);
@@ -475,12 +475,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
OrderBy<T> getOrderBy();
/**
* Return additional where clause. This should be added to any where clause
* that was part of the original query.
*/
String getAdditionalWhere();
/**
* Can return null if no expressions where added to the where clause.
*/
@@ -496,12 +490,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
SpiExpressionList<T> getTextExpression();
/**
* Return additional having clause. Where raw String expressions are added
* to having clause rather than Expression objects.
*/
String getAdditionalHaving();
/**
* Returns true if either firstRow or maxRows has been set.
*/
@@ -622,11 +610,6 @@ public interface SpiQuery<T> extends Query<T> {
*/
void setDefaultSelectClause();
/**
* Return the where clause from a parsed string query.
*/
String getRawWhereClause();
/**
* Set the generated sql for debug purposes.
*/
@@ -20,10 +20,13 @@ public class DefaultServerCacheManager implements ServerCacheManager {
private final DefaultCacheHolder collectionIdsCache;
private final boolean localL2Caching;
/**
* Create with a cache factory and default cache options.
*/
public DefaultServerCacheManager(ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
public DefaultServerCacheManager(boolean localL2Caching, ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
this.localL2Caching = localL2Caching;
this.beanCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
this.queryCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions);
this.naturalKeyCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
@@ -34,7 +37,11 @@ public class DefaultServerCacheManager implements ServerCacheManager {
* Construct when l2 cache is disabled.
*/
public DefaultServerCacheManager() {
this(new DefaultServerCacheFactory(), new ServerCacheOptions(), new ServerCacheOptions());
this(true, new DefaultServerCacheFactory(), new ServerCacheOptions(), new ServerCacheOptions());
}
public boolean isLocalL2Caching() {
return localL2Caching;
}
/**
@@ -49,7 +56,9 @@ public class DefaultServerCacheManager implements ServerCacheManager {
queryCache.clearCache(beanName);
}
/**
* Clear all caches.
*/
public void clearAll() {
beanCache.clearAll();
queryCache.clearAll();
@@ -57,7 +66,6 @@ public class DefaultServerCacheManager implements ServerCacheManager {
collectionIdsCache.clearAll();
}
public ServerCache getCollectionIdsCache(Class<?> beanType, String propertyName) {
return collectionIdsCache.getCache(beanType.getName() + "." + propertyName, ServerCacheType.COLLECTION_IDS);
}
@@ -87,5 +95,4 @@ public class DefaultServerCacheManager implements ServerCacheManager {
return beanCache.isCaching(beanType.getName());
}
}
@@ -10,7 +10,7 @@ public class CacheOptions {
/**
* Instance when no caching is used.
*/
public static CacheOptions NO_CACHING = new CacheOptions();
public static final CacheOptions NO_CACHING = new CacheOptions();
private final boolean enableBeanCache;
private final boolean enableQueryCache;
@@ -281,7 +281,7 @@ public class DefaultBeanLoader {
}
}
SpiQuery<?> query = (SpiQuery<?>) server.createQuery(desc.getBeanType());
SpiQuery<?> query = server.createQuery(desc.getBeanType());
query.setLazyLoadProperty(ebi.getLazyLoadProperty());
if (draft) {
query.asDraft();
@@ -17,6 +17,8 @@ import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.cache.DefaultServerCachePlugin;
import com.avaje.ebeaninternal.server.cache.DefaultServerCacheManager;
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.core.bootup.BootupClassPathSearch;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
import org.avaje.datasource.DataSourceAlertFactory;
import org.avaje.datasource.DataSourceConfig;
@@ -168,6 +170,7 @@ public class DefaultContainer implements SpiContainer {
queryOptions.setMaxIdleSecs(serverConfig.getQueryCacheMaxIdleTime());
queryOptions.setMaxSecsToLive(serverConfig.getQueryCacheMaxTimeToLive());
boolean localL2Caching = false;
ServerCachePlugin plugin = serverConfig.getServerCachePlugin();
if (plugin == null) {
ServiceLoader<ServerCachePlugin> cacheFactories = ServiceLoader.load(ServerCachePlugin.class);
@@ -177,13 +180,14 @@ public class DefaultContainer implements SpiContainer {
plugin = iterator.next();
logger.debug("using ServerCacheFactory {}", plugin.getClass());
} else {
// use the built in default
// use the built in default l2 caching which is local cache based
localL2Caching = true;
plugin = new DefaultServerCachePlugin();
}
}
ServerCacheFactory factory = plugin.create(serverConfig, executor);
return new DefaultServerCacheManager(factory, beanOptions, queryOptions);
return new DefaultServerCacheManager(localL2Caching, factory, beanOptions, queryOptions);
}
/**
@@ -192,20 +196,20 @@ public class DefaultContainer implements SpiContainer {
*/
private BootupClasses getBootupClasses(ServerConfig serverConfig) {
BootupClasses bootupClasses = getBootupClasses1(serverConfig);
bootupClasses.addIdGenerators(serverConfig.getIdGenerators());
bootupClasses.addPersistControllers(serverConfig.getPersistControllers());
bootupClasses.addPostLoaders(serverConfig.getPostLoaders());
bootupClasses.addFindControllers(serverConfig.getFindControllers());
bootupClasses.addTransactionEventListeners(serverConfig.getTransactionEventListeners());
bootupClasses.addPersistListeners(serverConfig.getPersistListeners());
bootupClasses.addQueryAdapters(serverConfig.getQueryAdapters());
bootupClasses.addServerConfigStartup(serverConfig.getServerConfigStartupListeners());
bootupClasses.addChangeLogInstances(serverConfig);
BootupClasses bootup = getBootupClasses1(serverConfig);
bootup.addIdGenerators(serverConfig.getIdGenerators());
bootup.addPersistControllers(serverConfig.getPersistControllers());
bootup.addPostLoaders(serverConfig.getPostLoaders());
bootup.addFindControllers(serverConfig.getFindControllers());
bootup.addTransactionEventListeners(serverConfig.getTransactionEventListeners());
bootup.addPersistListeners(serverConfig.getPersistListeners());
bootup.addQueryAdapters(serverConfig.getQueryAdapters());
bootup.addServerConfigStartup(serverConfig.getServerConfigStartupListeners());
bootup.addChangeLogInstances(serverConfig);
// run any ServerConfigStartup instances
bootupClasses.runServerConfigStartup(serverConfig);
return bootupClasses;
bootup.runServerConfigStartup(serverConfig);
return bootup;
}
/**
@@ -214,7 +218,7 @@ public class DefaultContainer implements SpiContainer {
private BootupClasses getBootupClasses1(ServerConfig serverConfig) {
List<Class<?>> entityClasses = serverConfig.getClasses();
if (serverConfig.isDisableClasspathSearch() || (entityClasses != null && entityClasses.size() > 0)) {
if (serverConfig.isDisableClasspathSearch() || (entityClasses != null && !entityClasses.isEmpty())) {
// use classes we explicitly added via configuration
return new BootupClasses(entityClasses);
}
@@ -836,7 +836,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (sortByClause == null) {
throw new NullPointerException("sortByClause is null");
}
if (list.size() == 0) {
if (list.isEmpty()) {
// don't need to sort an empty list
return;
}
@@ -991,7 +991,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
if (!query.isUseBeanCache()) {
if (!query.isUseBeanCache() || (t != null && t.isSkipCache())) {
return null;
}
@@ -1041,26 +1041,32 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
public <T> T findUnique(Query<T> query, Transaction t) {
public <T> T findUnique(Query<T> query, Transaction transaction) {
Object id = query.getId();
if (id != null) {
// actually a find by Id query
return findId(query, t);
return findId(query, transaction);
}
SpiQuery<T> spiQuery = (SpiQuery<T>) query;
BeanDescriptor<T> desc = spiQuery.getBeanDescriptor();
id = desc.cacheNaturalKeyIdLookup(spiQuery);
if (id != null) {
T bean = findIdCheckPersistenceContextAndCache(t, spiQuery, id);
if (bean != null) {
return bean;
SpiTransaction t = (SpiTransaction) transaction;
if (t == null) {
t = getCurrentServerTransaction();
}
if (t == null || !t.isSkipCache()) {
id = desc.cacheNaturalKeyIdLookup(spiQuery);
if (id != null) {
T bean = findIdCheckPersistenceContextAndCache(t, spiQuery, id);
if (bean != null) {
return bean;
}
}
}
// a query that is expected to return either 0 or 1 rows
// a query that is expected to return either 0 or 1 beans
List<T> list = findList(query, t);
return extractUnique(list);
}
@@ -22,6 +22,7 @@ import com.avaje.ebeaninternal.server.changelog.DefaultChangeLogListener;
import com.avaje.ebeaninternal.server.changelog.DefaultChangeLogPrepare;
import com.avaje.ebeaninternal.server.changelog.DefaultChangeLogRegister;
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.core.timezone.CloneDataTimeZone;
import com.avaje.ebeaninternal.server.core.timezone.DataTimeZone;
import com.avaje.ebeaninternal.server.core.timezone.NoDataTimeZone;
@@ -337,15 +338,16 @@ public class InternalConfiguration {
*/
public TransactionManager createTransactionManager(DocStoreUpdateProcessor indexUpdateProcessor) {
boolean localL2 = cacheManager.isLocalL2Caching();
if (serverConfig.isExplicitTransactionBeginMode()) {
return new ExplicitTransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
return new ExplicitTransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
}
if (isAutoCommitMode()) {
return new AutoCommitTransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
return new AutoCommitTransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
}
return new TransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
return new TransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
}
/**
@@ -1,6 +1,7 @@
package com.avaje.ebeaninternal.server.core;
package com.avaje.ebeaninternal.server.core.bootup;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.server.core.ClassPathScanners;
import org.avaje.classpath.scanner.ClassPathScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -10,10 +11,12 @@ import java.util.*;
/**
* Searches for interesting classes such as Entities, Embedded and ScalarTypes.
*/
class BootupClassPathSearch {
public class BootupClassPathSearch {
private static final Logger logger = LoggerFactory.getLogger(BootupClassPathSearch.class);
private static final String EBEAN_MF = "META-INF/ebean.mf";
private final List<String> packages;
private final List<ClassPathScanner> scanners;
@@ -28,7 +31,11 @@ class BootupClassPathSearch {
}
private BootupClassPathSearch(ServerConfig serverConfig) {
this.packages = serverConfig.getPackages();
// find packages defined in META-INF/ebean.mf resources
Set<String> mfPackages = ManifestReader.readManifests(serverConfig.getClassLoadConfig().getClassLoader(), EBEAN_MF);
this.packages = DistillPackages.distill(serverConfig.getPackages(), mfPackages);
this.scanners = ClassPathScanners.find(serverConfig);
}
@@ -42,7 +49,7 @@ class BootupClassPathSearch {
long st = System.currentTimeMillis();
for (ClassPathScanner finder : this.scanners) {
if (packages != null && packages.size() > 0) {
if (packages != null && !packages.isEmpty()) {
for (String packageName : packages) {
finder.scanForClasses(packageName, bc);
}
@@ -1,4 +1,4 @@
package com.avaje.ebeaninternal.server.core;
package com.avaje.ebeaninternal.server.core.bootup;
import com.avaje.ebean.config.CompoundType;
import com.avaje.ebean.config.IdGenerator;
@@ -17,7 +17,6 @@ import com.avaje.ebean.event.changelog.ChangeLogRegister;
import com.avaje.ebean.event.readaudit.ReadAuditLogger;
import com.avaje.ebean.event.readaudit.ReadAuditPrepare;
import com.avaje.ebeaninternal.server.type.ScalarType;
import com.avaje.ebeaninternal.server.util.ClassPathSearchMatcher;
import org.avaje.classpath.scanner.ClassFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,7 +34,7 @@ import java.util.List;
* Interesting classes for a EbeanServer such as Embeddable, Entity,
* ScalarTypes, Finders, Listeners and Controllers.
*/
public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
public class BootupClasses implements ClassFilter {
private static final Logger logger = LoggerFactory.getLogger(BootupClasses.class);
@@ -0,0 +1,48 @@
package com.avaje.ebeaninternal.server.core.bootup;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
/**
* Distill packages into distinct top level packages for searching.
*/
class DistillPackages {
/**
* Distill the list of packages into distinct top level packages.
*/
static List<String> distill(Collection<String> packages, Collection<String> mfPackages) {
// sort into natural order
TreeSet<String> treeSet = new TreeSet<String>();
treeSet.addAll(packages);
treeSet.addAll(mfPackages);
List<String> distilled = new ArrayList<String>();
// build the distilled list
for (String pack : treeSet) {
if (notAlreadyContained(distilled, pack)) {
distilled.add(pack);
}
}
return distilled;
}
/**
* Return true if the package is not already contained in the distilled list.
*/
private static boolean notAlreadyContained(List<String> distilled, String pack) {
for (int i = 0; i < distilled.size(); i++) {
if (pack.startsWith(distilled.get(i))) {
return false;
}
}
return true;
}
}
@@ -0,0 +1,84 @@
package com.avaje.ebeaninternal.server.core.bootup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
/**
* Reads all the META-INF/ebean.mf resources with the package locations of entity beans.
*/
class ManifestReader {
private static final Logger logger = LoggerFactory.getLogger(ManifestReader.class);
private final Set<String> packageSet = new HashSet<String>();
/**
* Read the packages from ebean.mf manifest files found as resources.
*/
static Set<String> readManifests(ClassLoader classLoader, String resourcePath) {
return new ManifestReader().read(classLoader, resourcePath);
}
/**
* Read all the specific manifest files and return the set of packages containing type query beans.
*/
private Set<String> read(ClassLoader classLoader, String resourcePath) {
try {
Enumeration<URL> resources = classLoader.getResources(resourcePath);
while (resources.hasMoreElements()) {
InputStream is = resources.nextElement().openStream();
try {
read(new Manifest(is));
} finally {
close(is);
}
}
} catch (IOException e) {
logger.warn("Error reading META-INF/ebean.mf manifest resources", e);
}
return packageSet;
}
private void close(InputStream is) {
try {
is.close();
} catch (IOException e) {
logger.warn("Error closing manifest InputStream", e);
}
}
/**
* Read the packages from the manifest.
*/
private void read(Manifest manifest) throws IOException {
Attributes attributes = manifest.getMainAttributes();
String packages = attributes.getValue("packages");
if (packages != null) {
add(packages);
}
}
/**
* Collect each individual package splitting by delimiters.
*/
private void add(String packages) {
String[] split = packages.split(",|;| ");
for (int i = 0; i <split.length; i++) {
String pkg = split[i].trim();
if (!pkg.isEmpty()) {
packageSet.add(pkg);
}
}
}
}
@@ -21,6 +21,7 @@ abstract class AssocOneHelp {
this.property = property;
this.target = property.targetDescriptor;
}
/**
* Effectively skip reading (the jdbc resultSet as already in the persistence context etc).
*/
@@ -10,56 +10,69 @@ import javax.persistence.CascadeType;
*/
public class BeanCascadeInfo {
/**
* should delete cascade.
*/
boolean delete;
/**
* Should save cascade.
*/
boolean save;
private boolean delete;
public void setTypes(CascadeType[] types) {
for (int i = 0; i < types.length; i++) {
setType(types[i]);
}
private boolean save;
private boolean refresh;
public void setTypes(CascadeType[] types) {
for (int i = 0; i < types.length; i++) {
setType(types[i]);
}
private void setType(CascadeType type) {
if (type.equals(CascadeType.ALL)){
save = true;
delete = true;
}
if (type.equals(CascadeType.REMOVE)){
delete = true;
}
if (type.equals(CascadeType.PERSIST)){
save = true;
}
if (type.equals(CascadeType.MERGE)){
save = true;
}
}
/**
* Return true if delete should cascade.
*/
public boolean isDelete() {
return delete;
}
/**
* Set to true if delete should cascade.
*/
public void setDelete(boolean delete) {
this.delete = delete;
}
/**
* Return true if save should cascade.
*/
public boolean isSave() {
return save;
}
private void setType(CascadeType type) {
switch (type) {
case ALL:
save = true;
delete = true;
refresh = true;
break;
case REMOVE:
delete = true;
break;
case REFRESH:
refresh = true;
break;
case PERSIST:
save = true;
break;
case MERGE:
save = true;
break;
default:
throw new IllegalStateException("Unexpected CascadeType " + type);
}
}
/**
* Return true if refresh should cascade.
*/
public boolean isRefresh() {
return refresh;
}
/**
* Return true if delete should cascade.
*/
public boolean isDelete() {
return delete;
}
/**
* Set to true if delete should cascade.
*/
public void setDelete(boolean delete) {
this.delete = delete;
}
/**
* Return true if save should cascade.
*/
public boolean isSave() {
return save;
}
/**
* Set cascade save and delete settings.
@@ -16,48 +16,48 @@ import java.io.IOException;
*/
public interface BeanCollectionHelp<T> {
/**
* Set the EbeanServer that owns the configuration.
*/
void setLoader(BeanCollectionLoader loader);
/**
* Return the mechanism to add beans to the underlying collection.
* <p>
* For Map's this needs to take the mapKey.
* </p>
*/
BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey);
/**
* Set the EbeanServer that owns the configuration.
*/
void setLoader(BeanCollectionLoader loader);
/**
* Return the mechanism to add beans to the underlying collection.
* <p>
* For Map's this needs to take the mapKey.
* </p>
*/
BeanCollectionAdd getBeanCollectionAdd(Object bc, String mapKey);
/**
* Create an empty collection of the correct type without a parent bean.
*/
BeanCollection<T> createEmptyNoParent();
/**
* Create an empty collection of the correct type.
*/
BeanCollection<T> createEmpty(EntityBean bean);
/**
* Create an empty collection of the correct type.
*/
BeanCollection<T> createEmpty(EntityBean bean);
/**
* Add a bean to the List Set or Map.
*/
void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck);
/**
* Add a bean to the List Set or Map.
*/
void add(BeanCollection<?> collection, EntityBean bean, boolean withCheck);
/**
* Create a lazy loading proxy for a List Set or Map.
*/
BeanCollection<T> createReference(EntityBean parentBean);
/**
* Create a lazy loading proxy for a List Set or Map.
*/
BeanCollection<T> createReference(EntityBean parentBean);
/**
* Refresh the List Set or Map.
*/
void refresh(EbeanServer server, Query<?> query, Transaction t, EntityBean parentBean);
/**
* Apply the new refreshed BeanCollection to the appropriate property of the parent bean.
*/
void refresh(BeanCollection<?> bc, EntityBean parentBean);
/**
* Refresh the List Set or Map.
*/
void refresh(EbeanServer server, Query<?> query, Transaction t, EntityBean parentBean);
/**
* Apply the new refreshed BeanCollection to the appropriate property of the parent bean.
*/
void refresh(BeanCollection<?> bc, EntityBean parentBean);
/**
* Write the collection out as json.
@@ -13,42 +13,42 @@ public class BeanCollectionHelpFactory {
static final BeanSetHelp SET_HELP = new BeanSetHelp();
/**
* Create the helper based on the many property.
*/
public static <T> BeanCollectionHelp<T> create(BeanPropertyAssocMany<T> manyProperty) {
/**
* Create the helper based on the many property.
*/
public static <T> BeanCollectionHelp<T> create(BeanPropertyAssocMany<T> manyProperty) {
ManyType manyType = manyProperty.getManyType();
switch (manyType) {
case LIST:
return new BeanListHelp<T>(manyProperty);
case SET:
return new BeanSetHelp<T>(manyProperty);
case MAP:
return new BeanMapHelp<T>(manyProperty);
default:
throw new RuntimeException("Invalid type "+manyType);
}
}
ManyType manyType = manyProperty.getManyType();
switch (manyType) {
case LIST:
return new BeanListHelp<T>(manyProperty);
case SET:
return new BeanSetHelp<T>(manyProperty);
case MAP:
return new BeanMapHelp<T>(manyProperty);
default:
throw new RuntimeException("Invalid type " + manyType);
}
}
@SuppressWarnings("unchecked")
public static <T> BeanCollectionHelp<T> create(OrmQueryRequest<T> request) {
public static <T> BeanCollectionHelp<T> create(OrmQueryRequest<T> request) {
SpiQuery.Type manyType = request.getQuery().getType();
if (manyType.equals(SpiQuery.Type.LIST)) {
return LIST_HELP;
} else if (manyType.equals(SpiQuery.Type.SET)) {
return SET_HELP;
} else {
BeanDescriptor<T> target = request.getBeanDescriptor();
String mapKey = request.getQuery().getMapKey();
return new BeanMapHelp<T>(target, mapKey);
}
}
SpiQuery.Type manyType = request.getQuery().getType();
if (manyType.equals(SpiQuery.Type.LIST)){
return LIST_HELP;
} else if (manyType.equals(SpiQuery.Type.SET)) {
return SET_HELP;
} else {
BeanDescriptor<T> target = request.getBeanDescriptor();
String mapKey = request.getQuery().getMapKey();
return new BeanMapHelp<T>(target, mapKey);
}
}
}
@@ -119,7 +119,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
for (int i = 0; i < propertyLength; i++) {
if (fromEbi.isLoadedProperty(i) ) {
if (fromEbi.isLoadedProperty(i)) {
BeanProperty property = getBeanProperty(names[i]);
if (!toEbi.isLoadedProperty(i)) {
Object val = property.getValue(bean);
@@ -228,9 +228,9 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
*/
private final BeanDescriptorMap owner;
private final String[] properties;
/**
* Intercept pre post on insert,update, and delete .
*/
@@ -276,7 +276,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
* Derived list of properties that are used for version concurrency checking.
*/
private final BeanProperty versionProperty;
private final int versionPropertyIndex;
private final BeanProperty whenModifiedProperty;
@@ -287,7 +287,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
* Properties that are initialised in the constructor need to be 'unloaded' to support partial object queries.
*/
private final int[] unloadProperties;
/**
* Properties local to this type (not from a super type).
*/
@@ -298,7 +298,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
*/
private final BeanProperty[] propertiesMutable;
private final BeanPropertyAssocOne<?> unidirectional;
/**
@@ -358,7 +358,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
private boolean deleteRecurseSkippable;
private final EntityBean prototypeEntityBean;
private final IdBinder idBinder;
private String idBinderInLHSSql;
@@ -499,7 +499,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
// Check if there are no cascade delete associated beans (also subject to
// change in initialiseOther()).
deleteRecurseSkippable = (0 == (propertiesOneExportedDelete.length + propertiesOneImportedDelete.length + propertiesManyDelete.length));
// object used to handle Id values
this.idBinder = owner.createIdBinder(idProperty);
this.whenModifiedProperty = findWhenModifiedProperty();
@@ -511,7 +511,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
this.versionPropertyIndex = -1;
this.unloadProperties = new int[0];
this.propertiesIndex = new BeanProperty[0];
} else {
EntityBeanIntercept ebi = prototypeEntityBean._ebean_getIntercept();
this.idPropertyIndex = (idProperty == null) ? -1 : ebi.findProperty(idProperty.getName());
@@ -529,40 +529,40 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
* These properties need to be unloaded when populating beans for queries.
*/
private int[] derivePropertiesToUnload(EntityBean prototypeEntityBean) {
boolean[] loaded = prototypeEntityBean._ebean_getIntercept().getLoaded();
int[] props = new int[loaded.length];
int pos = 0;
// collect the positions of the properties initialised in the default constructor.
for (int i = 0; i < loaded.length; i++) {
if (loaded[i]) {
props[pos++] = i;
}
}
if (pos == 0) {
// nothing set in the constructor
return new int[0];
}
// populate a smaller/minimal array
int[] unload = new int[pos];
System.arraycopy(props, 0, unload, 0, pos);
return unload;
}
/**
* Create an entity bean that is used as a prototype/factory to create new instances.
* Create an entity bean that is used as a prototype/factory to create new instances.
*/
private EntityBean createPrototypeEntityBean(Class<T> beanType) {
if (Modifier.isAbstract(beanType.getModifiers())) {
return null;
}
return null;
}
try {
return (EntityBean) beanType.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Error trying to create the prototypeEntityBean for "+beanType, e);
throw new IllegalStateException("Error trying to create the prototypeEntityBean for " + beanType, e);
}
}
@@ -608,9 +608,10 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
* These properties need to be initialised prior to the association properties
* as they are used to get the imported and exported properties.
* </p>
*
* @param withHistoryTables map populated if @History is supported on this entity bean
*/
public void initialiseId(Map<String, String> withHistoryTables, Map<String,String> draftTables) {
public void initialiseId(Map<String, String> withHistoryTables, Map<String, String> draftTables) {
if (logger.isTraceEnabled()) {
logger.trace("BeanDescriptor initialise " + fullName);
@@ -644,9 +645,9 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Initialise the exported and imported parts for associated properties.
*
* @param asOfTableMap the map of base tables to associated 'with history' tables
* @param asOfTableMap the map of base tables to associated 'with history' tables
* @param asOfViewSuffix the suffix added to the table name to derive the 'with history' view name
* @param draftTableMap the map of base tables to associated 'draft' tables.
* @param draftTableMap the map of base tables to associated 'draft' tables.
*/
public void initialiseOther(Map<String, String> asOfTableMap, String asOfViewSuffix, Map<String, String> draftTableMap) {
@@ -709,7 +710,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
propertiesMany[i].initialisePostTarget();
}
if (inheritInfo != null && !inheritInfo.isRoot()) {
docStoreAdapter = (DocStoreBeanAdapter<T>)inheritInfo.getRoot().desc().docStoreAdapter();
docStoreAdapter = (DocStoreBeanAdapter<T>) inheritInfo.getRoot().desc().docStoreAdapter();
}
docMapping = docStoreAdapter.createDocMapping();
docStoreAdapter.registerPaths();
@@ -753,12 +754,12 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
PersistRequest.Type type = request.getType();
switch (type) {
case INSERT:
return changeLogFilter.includeInsert(request) ? insertBeanChange(request): null;
return changeLogFilter.includeInsert(request) ? insertBeanChange(request) : null;
case UPDATE:
case SOFT_DELETE:
return changeLogFilter.includeUpdate(request) ? updateBeanChange(request): null;
return changeLogFilter.includeUpdate(request) ? updateBeanChange(request) : null;
case DELETE:
return changeLogFilter.includeDelete(request) ? deleteBeanChange(request) :null;
return changeLogFilter.includeDelete(request) ? deleteBeanChange(request) : null;
default:
throw new IllegalStateException("Unhandled request type " + type);
}
@@ -959,7 +960,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
mapping.add(new DocPropertyMapping(discCol, DocPropertyType.INTEGER));
}
}
for (BeanProperty prop: propertiesNonTransient) {
for (BeanProperty prop : propertiesNonTransient) {
prop.docStoreMapping(mapping, prefix);
}
if (inheritInfo != null) {
@@ -1121,7 +1122,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
public CachedBeanData cacheEmbeddedBeanExtract(EntityBean bean) {
return cacheHelp.beanExtractData(this, bean);
}
/**
* Load the embedded bean (taking into account inheritance).
*/
@@ -1177,7 +1178,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
public void cacheHandleDeleteById(Object id) {
cacheHelp.beanCacheRemove(id);
}
/**
* Returns true if it managed to populate/load the bean from the cache.
*/
@@ -1330,15 +1331,15 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
public List<MetaQueryPlanStatistic> collectQueryPlanStatistics(boolean reset) {
return collectQueryPlanStatisticsInternal(reset, false);
}
@Override
public List<MetaQueryPlanStatistic> collectAllQueryPlanStatistics(boolean reset) {
return collectQueryPlanStatisticsInternal(reset, false);
}
public List<MetaQueryPlanStatistic> collectQueryPlanStatisticsInternal(boolean reset, boolean collectAll) {
List<MetaQueryPlanStatistic> list = new ArrayList<MetaQueryPlanStatistic>(queryPlanCache.size());
for (CQueryPlan queryPlan : queryPlanCache.values()) {
for (CQueryPlan queryPlan : queryPlanCache.values()) {
Snapshot snapshot = queryPlan.getSnapshot(reset);
if (collectAll || snapshot.getExecutionCount() > 0) {
list.add(snapshot);
@@ -1413,7 +1414,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Return true if delete can use a single SQL statement.
*
* <p>
* This implies cascade delete does not continue depth wise and that this is no
* associated L2 bean caching.
*/
@@ -1529,7 +1530,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
@Override
@SuppressWarnings("unchecked")
public T createBean() {
return (T)createEntityBean();
return (T) createEntityBean();
}
/**
@@ -1538,8 +1539,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
@SuppressWarnings("unchecked")
public EntityBean createEntityBean() {
try {
EntityBean bean = (EntityBean)prototypeEntityBean._ebean_newInstance();
EntityBean bean = (EntityBean) prototypeEntityBean._ebean_newInstance();
if (unloadProperties.length > 0) {
// 'unload' any properties initialised in the default constructor
EntityBeanIntercept ebi = bean._ebean_getIntercept();
@@ -1548,7 +1549,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
}
}
return bean;
} catch (Exception ex) {
throw new PersistenceException(ex);
}
@@ -1806,7 +1807,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
public Object convertIdFromJson(Object idValue) {
return idBinder.convertIdFromJson(idValue);
}
/**
* Return the default order by that may need to be added if a many property is
* included in the query.
@@ -1871,7 +1872,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Register all the assoc many properties on this bean that are not populated with the load context.
* <p>
* This provides further lazy loading via the load context.
* This provides further lazy loading via the load context.
* </p>
*/
public void lazyLoadRegister(String prefix, EntityBeanIntercept ebi, EntityBean bean, LoadContext loadContext) {
@@ -1930,9 +1931,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Return a Comparator for local sorting of lists.
*
* @param sortByClause
* list of property names with optional ASC or DESC suffix.
*
* @param sortByClause list of property names with optional ASC or DESC suffix.
*/
@SuppressWarnings("unchecked")
private ElComparator<T> createComparator(String sortByClause) {
@@ -2025,7 +2025,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
ElPropertyDeploy fk = elDeployCache.get(propName);
if (fk != null && fk instanceof BeanFkeyProperty) {
// propertyDeploy chain for foreign key column
return ((BeanFkeyProperty)fk).create(chain.getExpression(), chain.isContainsMany());
return ((BeanFkeyProperty) fk).create(chain.getExpression(), chain.isContainsMany());
}
}
@@ -2087,9 +2087,11 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
*/
public void resetManyProperties(Object dbBean) {
EntityBean bean = (EntityBean)dbBean;
EntityBean bean = (EntityBean) dbBean;
for (int i = 0; i < propertiesMany.length; i++) {
propertiesMany[i].resetMany(bean);
if (propertiesMany[i].isCascadeRefresh()) {
propertiesMany[i].resetMany(bean);
}
}
}
@@ -2334,10 +2336,14 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
*/
public String getBaseTable(SpiQuery.TemporalMode mode) {
switch (mode) {
case DRAFT: return draftTable;
case VERSIONS: return baseTableVersionsBetween;
case AS_OF: return baseTableAsOf;
default: return baseTable;
case DRAFT:
return draftTable;
case VERSIONS:
return baseTableVersionsBetween;
case AS_OF:
return baseTableAsOf;
default:
return baseTable;
}
}
@@ -2552,19 +2558,17 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Return true if this bean should be inserted rather than updated.
*
* @param ebi
* The entity bean intercept
* @param insertMode
* true if the 'root request' was an insert rather than an update
*
* @param ebi The entity bean intercept
* @param insertMode true if the 'root request' was an insert rather than an update
*/
public boolean isInsertMode(EntityBeanIntercept ebi, boolean insertMode) {
if (ebi.isLoaded()) {
// must be an update as the bean is loaded
return false;
}
if (idProperty.isEmbedded()) {
// not using Id generator so just base on isLoaded()
return !ebi.isLoaded();
@@ -2576,11 +2580,11 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
// same as the 'root request'
return insertMode;
}
public boolean isReference(EntityBeanIntercept ebi) {
return ebi.isReference() || hasIdPropertyOnly(ebi);
}
public boolean hasIdPropertyOnly(EntityBeanIntercept ebi) {
return ebi.hasIdOnly(idPropertyIndex);
}
@@ -2629,13 +2633,13 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
}
}
}
public ConcurrencyMode getConcurrencyMode(EntityBeanIntercept ebi) {
if (!hasVersionProperty(ebi)) {
return ConcurrencyMode.NONE;
} else {
return concurrencyMode;
return concurrencyMode;
}
}
@@ -2721,7 +2725,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
query.order(rawSql.getSql().getOrderBy());
}
query.order().asc(idProperty.getName());
} else if (!orderBy.containsProperty(idProperty.getName())){
} else if (!orderBy.containsProperty(idProperty.getName())) {
query.order().asc(idProperty.getName());
}
}
@@ -2853,8 +2857,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
public void jsonWrite(WriteJson writeJson, EntityBean bean) throws IOException {
jsonHelp.jsonWrite(writeJson, bean, null);
}
}
public void jsonWrite(WriteJson writeJson, EntityBean bean, String key) throws IOException {
jsonHelp.jsonWrite(writeJson, bean, key);
}
@@ -2862,11 +2866,11 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
protected void jsonWriteProperties(WriteJson writeJson, EntityBean bean) throws IOException {
jsonHelp.jsonWriteProperties(writeJson, bean);
}
public T jsonRead(ReadJson jsonRead, String path) throws IOException {
return jsonHelp.jsonRead(jsonRead, path);
}
protected T jsonReadObject(ReadJson jsonRead, String path) throws IOException {
return jsonHelp.jsonReadObject(jsonRead, path);
}
@@ -29,7 +29,7 @@ import java.util.Map;
/**
* Helper for BeanDescriptor that manages the bean, query and collection caches.
*
*
* @param <T> The entity bean type
*/
final class BeanDescriptorCacheHelp<T> {
@@ -55,7 +55,7 @@ final class BeanDescriptorCacheHelp<T> {
private final Class<?> beanType;
private final String cacheName;
private final BeanPropertyAssocOne<?>[] propertiesOneImported;
private final String naturalKeyProperty;
@@ -74,7 +74,7 @@ final class BeanDescriptorCacheHelp<T> {
private boolean cacheNotifyOnDelete;
BeanDescriptorCacheHelp(BeanDescriptor<T> desc, ServerCacheManager cacheManager, CacheOptions cacheOptions,
boolean cacheSharableBeans, BeanPropertyAssocOne<?>[] propertiesOneImported) {
boolean cacheSharableBeans, BeanPropertyAssocOne<?>[] propertiesOneImported) {
this.desc = desc;
this.beanType = desc.rootBeanType;
@@ -88,7 +88,7 @@ final class BeanDescriptorCacheHelp<T> {
if (!cacheOptions.isEnableQueryCache()) {
this.queryCache = null;
} else {
this.queryCache = cacheManager.getQueryCache(beanType);
this.queryCache = cacheManager.getQueryCache(beanType);
}
if (cacheOptions.isEnableBeanCache()) {
@@ -240,7 +240,7 @@ final class BeanDescriptorCacheHelp<T> {
manyLog.trace(" GET {}({}).{} - cache miss", cacheName, parentId, propertyName);
}
} else if (manyLog.isDebugEnabled()) {
manyLog.debug(" GET {}({}).{} - hit", cacheName, parentId, propertyName);
manyLog.debug(" GET {}({}).{} - hit", cacheName, parentId, propertyName);
}
return entry;
}
@@ -255,7 +255,7 @@ final class BeanDescriptorCacheHelp<T> {
// not in cache so return unsuccessful
return false;
}
Object ownerBean = bc.getOwnerBean();
EntityBeanIntercept ebi = ((EntityBean) ownerBean)._ebean_getIntercept();
PersistenceContext persistenceContext = ebi.getPersistenceContext();
@@ -326,7 +326,7 @@ final class BeanDescriptorCacheHelp<T> {
// try to lookup the id using the natural key
Object id = naturalKeyCache.get(keyBindParam.getValue());
if (natLog.isTraceEnabled() && id != null) {
if (natLog.isTraceEnabled()) {
natLog.trace(" LOOKUP {}({}) - id:{}", cacheName, keyBindParam.getValue(), id);
}
return id;
@@ -350,13 +350,13 @@ final class BeanDescriptorCacheHelp<T> {
// Not using a loadContext for beans coming out of L2 cache
// so that means no batch lazy loading for these beans
EntityBean entityBean = (EntityBean)bean;
EntityBean entityBean = (EntityBean) bean;
EntityBeanIntercept ebi = entityBean._ebean_getIntercept();
ebi.setPersistenceContext(context);
Object id = desc.getId(entityBean);
desc.contextPut(context, id, bean);
}
/**
* Return the beanCache creating it if necessary.
*/
@@ -366,7 +366,7 @@ final class BeanDescriptorCacheHelp<T> {
}
return beanCache;
}
/**
* Clear the bean cache.
*/
@@ -422,7 +422,7 @@ final class BeanDescriptorCacheHelp<T> {
CachedBeanData beanCacheGetData(Object id) {
return (CachedBeanData) getBeanCache().get(id);
}
T beanCacheGet(Object id, Boolean readOnly, PersistenceContext context) {
T bean = beanCacheGetInternal(id, readOnly, context);
if (bean != null) {
@@ -430,7 +430,7 @@ final class BeanDescriptorCacheHelp<T> {
}
return bean;
}
/**
* Return a bean from the bean cache.
*/
@@ -457,7 +457,7 @@ final class BeanDescriptorCacheHelp<T> {
}
}
return (T)loadBean(id, readOnly, data, context);
return (T) loadBean(id, readOnly, data, context);
}
/**
@@ -620,6 +620,11 @@ final class BeanDescriptorCacheHelp<T> {
queryCacheClear(changeSet);
if (beanCache == null) {
// query caching only
return;
}
List<BeanPropertyAssocMany<?>> manyCollections = updateRequest.getUpdatedManyCollections();
if (manyCollections != null) {
for (int i = 0; i < manyCollections.size(); i++) {
@@ -631,7 +636,7 @@ final class BeanDescriptorCacheHelp<T> {
}
}
}
// check if the bean itself was updated
if (!updateRequest.isUpdatedManysOnly()) {
@@ -8,7 +8,7 @@ import java.util.List;
/**
* Helper for BeanDescriptor that manages draft entity beans.
*
*
* @param <T> The entity bean type
*/
public final class BeanDescriptorDraftHelp<T> {
@@ -47,7 +47,7 @@ public final class BeanDescriptorDraftHelp<T> {
*/
public boolean draftReset(T draftBean) {
EntityBean draftEntityBean = (EntityBean)draftBean;
EntityBean draftEntityBean = (EntityBean) draftBean;
if (draftDirty != null) {
// set @DraftDirty property to false
@@ -72,11 +72,11 @@ public final class BeanDescriptorDraftHelp<T> {
public T publish(T draftBean, T liveBean) {
if (liveBean == null) {
liveBean = (T)desc.createEntityBean();
liveBean = (T) desc.createEntityBean();
}
EntityBean draft = (EntityBean)draftBean;
EntityBean live = (EntityBean)liveBean;
EntityBean draft = (EntityBean) draftBean;
EntityBean live = (EntityBean) liveBean;
BeanProperty idProperty = desc.getIdProperty();
if (idProperty != null) {
@@ -22,7 +22,7 @@ import com.avaje.ebean.plugin.BeanType;
import com.avaje.ebeaninternal.api.ConcurrencyMode;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.api.TransactionEventTable;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.core.InternString;
import com.avaje.ebeaninternal.server.core.InternalConfiguration;
import com.avaje.ebeaninternal.server.core.Message;
@@ -794,7 +794,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
}
}
if (matchSet.size() == 0) {
if (matchSet.isEmpty()) {
// this is a unidirectional relationship
// ... that is no matching property on the 'detail' bean
return false;
@@ -2,18 +2,18 @@ package com.avaje.ebeaninternal.server.deploy;
public class BeanEmbeddedMeta {
final BeanProperty[] properties;
public BeanEmbeddedMeta(BeanProperty[] properties) {
this.properties = properties;
}
/**
* Return the properties with over ridden mapping information.
*/
public BeanProperty[] getProperties() {
return properties;
}
final BeanProperty[] properties;
public BeanEmbeddedMeta(BeanProperty[] properties) {
this.properties = properties;
}
/**
* Return the properties with over ridden mapping information.
*/
public BeanProperty[] getProperties() {
return properties;
}
}
@@ -12,41 +12,41 @@ import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
*/
public class BeanEmbeddedMetaFactory {
/**
* Create BeanProperties for embedded beans using the deployment specific DB column name and table alias.
*/
public static BeanEmbeddedMeta create(BeanDescriptorMap owner, DeployBeanPropertyAssocOne<?> prop) {
/**
* Create BeanProperties for embedded beans using the deployment specific DB column name and table alias.
*/
public static BeanEmbeddedMeta create(BeanDescriptorMap owner, DeployBeanPropertyAssocOne<?> prop) {
// we can get a BeanDescriptor for an Embedded bean
// and know that it is NOT recursive, as Embedded beans are
// only allow to hold simple scalar types...
BeanDescriptor<?> targetDesc = owner.getBeanDescriptor(prop.getTargetType());
if (targetDesc == null){
String msg = "Could not find BeanDescriptor for "+prop.getTargetType()
+". Perhaps the EmbeddedId class is not registered?";
throw new PersistenceException(msg);
}
// we can get a BeanDescriptor for an Embedded bean
// and know that it is NOT recursive, as Embedded beans are
// only allow to hold simple scalar types...
BeanDescriptor<?> targetDesc = owner.getBeanDescriptor(prop.getTargetType());
if (targetDesc == null) {
String msg = "Could not find BeanDescriptor for " + prop.getTargetType()
+ ". Perhaps the EmbeddedId class is not registered?";
throw new PersistenceException(msg);
}
// deployment override information (column names)
Map<String, String> propColMap = prop.getDeployEmbedded().getPropertyColumnMap();
// deployment override information (column names)
Map<String, String> propColMap = prop.getDeployEmbedded().getPropertyColumnMap();
BeanProperty[] sourceProperties = targetDesc.propertiesBaseScalar();
BeanProperty[] sourceProperties = targetDesc.propertiesBaseScalar();
BeanProperty[] embeddedProperties = new BeanProperty[sourceProperties.length];
BeanProperty[] embeddedProperties = new BeanProperty[sourceProperties.length];
for (int i = 0; i < sourceProperties.length; i++) {
for (int i = 0; i < sourceProperties.length; i++) {
String propertyName = sourceProperties[i].getName();
String dbColumn = propColMap.get(propertyName);
if (dbColumn == null) {
// dbColumn not overridden so take original
dbColumn = sourceProperties[i].getDbColumn();
}
String propertyName = sourceProperties[i].getName();
String dbColumn = propColMap.get(propertyName);
if (dbColumn == null) {
// dbColumn not overridden so take original
dbColumn = sourceProperties[i].getDbColumn();
}
BeanPropertyOverride overrides = new BeanPropertyOverride(dbColumn);
embeddedProperties[i] = new BeanProperty(sourceProperties[i], overrides);
}
BeanPropertyOverride overrides = new BeanPropertyOverride(dbColumn);
embeddedProperties[i] = new BeanProperty(sourceProperties[i], overrides);
}
return new BeanEmbeddedMeta(embeddedProperties);
}
return new BeanEmbeddedMeta(embeddedProperties);
}
}
@@ -1,7 +1,7 @@
package com.avaje.ebeaninternal.server.deploy;
import com.avaje.ebean.event.BeanFindController;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -21,7 +21,7 @@ public final class BeanFkeyProperty implements ElPropertyValue {
public BeanFkeyProperty(String name, String dbColumn, int deployOrder) {
this(null, name, dbColumn, deployOrder, false);
}
private BeanFkeyProperty(String prefix, String name, String dbColumn, int deployOrder, boolean containsMany) {
this.prefix = prefix;
this.name = name;
@@ -32,7 +32,7 @@ public final class BeanFkeyProperty implements ElPropertyValue {
}
public String toString() {
return "prefix:"+prefix+" name:"+name+" dbColumn:"+dbColumn+" ph:"+placeHolder;
return "prefix:" + prefix + " name:" + name + " dbColumn:" + dbColumn + " ph:" + placeHolder;
}
public int getDeployOrder() {
@@ -7,27 +7,27 @@ import com.avaje.ebeaninternal.server.persist.BeanPersister;
*/
public class BeanManager<T> {
private final BeanPersister persister;
private final BeanPersister persister;
private final BeanDescriptor<T> descriptor;
private final BeanDescriptor<T> descriptor;
public BeanManager(BeanDescriptor<T> descriptor, BeanPersister persister) {
this.descriptor = descriptor;
this.persister = persister;
}
public BeanManager(BeanDescriptor<T> descriptor, BeanPersister persister) {
this.descriptor = descriptor;
this.persister = persister;
}
/**
* Return the associated BeanPersister.
*/
public BeanPersister getBeanPersister() {
return persister;
}
/**
* Return the associated BeanPersister.
*/
public BeanPersister getBeanPersister() {
return persister;
}
/**
* Return the BeanDescriptor.
*/
public BeanDescriptor<T> getBeanDescriptor() {
return descriptor;
}
/**
* Return the BeanDescriptor.
*/
public BeanDescriptor<T> getBeanDescriptor() {
return descriptor;
}
}
@@ -38,7 +38,8 @@ public final class BeanMapHelp<T> implements BeanCollectionHelp<T> {
/**
* When help is attached to a specific many property.
*/ public BeanMapHelp(BeanPropertyAssocMany<T> many) {
*/
public BeanMapHelp(BeanPropertyAssocMany<T> many) {
this.many = many;
this.targetDescriptor = many.getTargetDescriptor();
this.propertyName = many.getName();
@@ -332,9 +332,9 @@ public class BeanProperty implements ElPropertyValue, Property {
this.softDelete = deploy.isSoftDelete();
if (softDelete) {
ScalarTypeBoolean.BooleanBase boolType = (ScalarTypeBoolean.BooleanBase)scalarType;
this.softDeleteDbSet = dbColumn+"="+boolType.getDbTrueLiteral();
this.softDeleteDbPredicate = "."+dbColumn+","+boolType.getDbFalseLiteral()+")="+boolType.getDbFalseLiteral();
ScalarTypeBoolean.BooleanBase boolType = (ScalarTypeBoolean.BooleanBase) scalarType;
this.softDeleteDbSet = dbColumn + "=" + boolType.getDbTrueLiteral();
this.softDeleteDbPredicate = "." + dbColumn + "," + boolType.getDbFalseLiteral() + ")=" + boolType.getDbFalseLiteral();
} else {
this.softDeleteDbSet = null;
this.softDeleteDbPredicate = null;
@@ -763,7 +763,7 @@ public class BeanProperty implements ElPropertyValue, Property {
public void setCacheDataValue(EntityBean bean, Object cacheData, PersistenceContext context) {
if (cacheData instanceof String) {
// parse back from string to support optimisation of java object serialisation
cacheData = scalarType.parse((String)cacheData);
cacheData = scalarType.parse((String) cacheData);
}
setValue(bean, cacheData);
}
@@ -776,7 +776,7 @@ public class BeanProperty implements ElPropertyValue, Property {
}
public Object getVal(Object bean) {
return getValue((EntityBean)bean);
return getValue((EntityBean) bean);
}
/**
@@ -814,7 +814,7 @@ public class BeanProperty implements ElPropertyValue, Property {
if (bean != null) {
Object logicalVal = convertToLogicalType(value);
setValue((EntityBean)bean, logicalVal);
setValue((EntityBean) bean, logicalVal);
}
}
@@ -823,7 +823,7 @@ public class BeanProperty implements ElPropertyValue, Property {
if (bean == null) {
return null;
}
return getValueIntercept((EntityBean)bean);
return getValueIntercept((EntityBean) bean);
}
@Override
@@ -1322,7 +1322,7 @@ public class BeanProperty implements ElPropertyValue, Property {
// change in behavior for #318
objValue = null;
String msg = "Error trying to use Jackson ObjectMapper to read transient property "
+ getFullBeanName() +" - consider marking this property with @JsonIgnore";
+ getFullBeanName() + " - consider marking this property with @JsonIgnore";
logger.error(msg, e);
}
}
@@ -1371,7 +1371,7 @@ public class BeanProperty implements ElPropertyValue, Property {
DocPropertyType type = scalarType.getDocType();
DocPropertyOptions options = docOptions.copy();
if (DocPropertyType.UUID == type || DocPropertyType.ENUM == type ||isStringId(type)) {
if (DocPropertyType.UUID == type || DocPropertyType.ENUM == type || isStringId(type)) {
options.setCode(true);
}
@@ -1,19 +1,7 @@
package com.avaje.ebeaninternal.server.deploy;
import java.util.ArrayList;
import javax.persistence.PersistenceException;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebeaninternal.server.query.SplitName;
import com.avaje.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyType;
import com.avaje.ebeanservice.docstore.api.support.DocStructure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.text.PathProperties;
import com.avaje.ebeaninternal.server.core.InternString;
import com.avaje.ebeaninternal.server.deploy.id.IdBinder;
import com.avaje.ebeaninternal.server.deploy.id.ImportedId;
@@ -22,206 +10,223 @@ import com.avaje.ebeaninternal.server.deploy.id.ImportedIdSimple;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssoc;
import com.avaje.ebeaninternal.server.el.ElPropertyChainBuilder;
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
import com.avaje.ebeaninternal.server.query.SplitName;
import com.avaje.ebeaninternal.server.query.SqlJoinType;
import com.avaje.ebeanservice.docstore.api.mapping.DocMappingBuilder;
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyMapping;
import com.avaje.ebeanservice.docstore.api.mapping.DocPropertyType;
import com.avaje.ebeanservice.docstore.api.support.DocStructure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.PersistenceException;
import java.util.ArrayList;
/**
* Abstract base for properties mapped to an associated bean, list, set or map.
*/
public abstract class BeanPropertyAssoc<T> extends BeanProperty {
private static final Logger logger = LoggerFactory.getLogger(BeanPropertyAssoc.class);
private static final Logger logger = LoggerFactory.getLogger(BeanPropertyAssoc.class);
/**
* The descriptor of the target. This MUST be initialised after construction
* so as to avoid a dependency loop between BeanDescriptors.
*/
BeanDescriptor<T> targetDescriptor;
/**
* The descriptor of the target. This MUST be initialised after construction
* so as to avoid a dependency loop between BeanDescriptors.
*/
BeanDescriptor<T> targetDescriptor;
IdBinder targetIdBinder;
IdBinder targetIdBinder;
InheritInfo targetInheritInfo;
InheritInfo targetInheritInfo;
String targetIdProperty;
String targetIdProperty;
/**
* Persist settings.
*/
final BeanCascadeInfo cascadeInfo;
/**
* Persist settings.
*/
final BeanCascadeInfo cascadeInfo;
/**
* Join between the beans.
*/
final TableJoin tableJoin;
/**
* Join between the beans.
*/
final TableJoin tableJoin;
/**
* The type of the joined bean.
*/
final Class<T> targetType;
/**
* The type of the joined bean.
*/
final Class<T> targetType;
/**
* The join table information.
*/
final BeanTable beanTable;
final String mappedBy;
/**
* The join table information.
*/
final BeanTable beanTable;
final String mappedBy;
final String docStoreDoc;
final String extraWhere;
boolean saveRecurseSkippable;
final String extraWhere;
/**
* Construct the property.
*/
public BeanPropertyAssoc(BeanDescriptor<?> descriptor, DeployBeanPropertyAssoc<T> deploy) {
super(descriptor, deploy);
this.extraWhere = InternString.intern(deploy.getExtraWhere());
this.beanTable = deploy.getBeanTable();
this.mappedBy = InternString.intern(deploy.getMappedBy());
boolean saveRecurseSkippable;
/**
* Construct the property.
*/
public BeanPropertyAssoc(BeanDescriptor<?> descriptor, DeployBeanPropertyAssoc<T> deploy) {
super(descriptor, deploy);
this.extraWhere = InternString.intern(deploy.getExtraWhere());
this.beanTable = deploy.getBeanTable();
this.mappedBy = InternString.intern(deploy.getMappedBy());
this.docStoreDoc = deploy.getDocStoreDoc();
this.tableJoin = new TableJoin(deploy.getTableJoin());
this.tableJoin = new TableJoin(deploy.getTableJoin());
this.targetType = deploy.getTargetType();
this.cascadeInfo = deploy.getCascadeInfo();
}
/**
* Initialise post construction.
*/
@Override
public void initialise() {
// this *MUST* execute after the BeanDescriptor is
// put into the map to stop infinite recursion
this.targetType = deploy.getTargetType();
this.cascadeInfo = deploy.getCascadeInfo();
}
/**
* Initialise post construction.
*/
@Override
public void initialise() {
// this *MUST* execute after the BeanDescriptor is
// put into the map to stop infinite recursion
targetDescriptor = descriptor.getBeanDescriptor(targetType);
if (!isTransient){
targetIdBinder = targetDescriptor.getIdBinder();
targetInheritInfo = targetDescriptor.getInheritInfo();
saveRecurseSkippable = targetDescriptor.isSaveRecurseSkippable();
if (!isTransient) {
targetIdBinder = targetDescriptor.getIdBinder();
targetInheritInfo = targetDescriptor.getInheritInfo();
saveRecurseSkippable = targetDescriptor.isSaveRecurseSkippable();
if (!targetIdBinder.isComplexId()){
targetIdProperty = targetIdBinder.getIdProperty();
}
}
}
/**
* Create a ElPropertyValue for a *ToOne or *ToMany.
*/
protected ElPropertyValue createElPropertyValue(String propName, String remainder, ElPropertyChainBuilder chain, boolean propertyDeploy) {
// associated or embedded bean
BeanDescriptor<?> embDesc = getTargetDescriptor();
if (chain == null) {
chain = new ElPropertyChainBuilder(isEmbedded(), propName);
}
chain.add(this);
if (containsMany()) {
chain.setContainsMany();
}
return embDesc.buildElGetValue(remainder, chain, propertyDeploy);
if (!targetIdBinder.isComplexId()) {
targetIdProperty = targetIdBinder.getIdProperty();
}
}
/**
* Add table join with table alias based on prefix.
*/
public SqlJoinType addJoin(SqlJoinType joinType, String prefix, DbSqlContext ctx) {
return tableJoin.addJoin(joinType, prefix, ctx);
}
/**
* Add table join with explicit table alias.
*/
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
return tableJoin.addJoin(joinType, a1, a2, ctx);
}
/**
* Return false.
*/
public boolean isScalar() {
return false;
}
/**
* Return the mappedBy property.
* This will be null on the owning side.
*/
public String getMappedBy() {
return mappedBy;
}
}
/**
* Return the Id property of the target entity type.
* <p>
* This will return null for multiple Id properties.
* </p>
*/
public String getTargetIdProperty() {
return targetIdProperty;
}
/**
* Create a ElPropertyValue for a *ToOne or *ToMany.
*/
protected ElPropertyValue createElPropertyValue(String propName, String remainder, ElPropertyChainBuilder chain, boolean propertyDeploy) {
/**
* Return the BeanDescriptor of the target.
*/
public BeanDescriptor<T> getTargetDescriptor() {
return targetDescriptor;
}
public boolean isSaveRecurseSkippable(Object bean) {
// associated or embedded bean
BeanDescriptor<?> embDesc = getTargetDescriptor();
if (chain == null) {
chain = new ElPropertyChainBuilder(isEmbedded(), propName);
}
chain.add(this);
if (containsMany()) {
chain.setContainsMany();
}
return embDesc.buildElGetValue(remainder, chain, propertyDeploy);
}
/**
* Add table join with table alias based on prefix.
*/
public SqlJoinType addJoin(SqlJoinType joinType, String prefix, DbSqlContext ctx) {
return tableJoin.addJoin(joinType, prefix, ctx);
}
/**
* Add table join with explicit table alias.
*/
public SqlJoinType addJoin(SqlJoinType joinType, String a1, String a2, DbSqlContext ctx) {
return tableJoin.addJoin(joinType, a1, a2, ctx);
}
/**
* Return false.
*/
public boolean isScalar() {
return false;
}
/**
* Return the mappedBy property.
* This will be null on the owning side.
*/
public String getMappedBy() {
return mappedBy;
}
/**
* Return the Id property of the target entity type.
* <p>
* This will return null for multiple Id properties.
* </p>
*/
public String getTargetIdProperty() {
return targetIdProperty;
}
/**
* Return the BeanDescriptor of the target.
*/
public BeanDescriptor<T> getTargetDescriptor() {
return targetDescriptor;
}
/**
* Return true if REFRESH should cascade.
*/
public boolean isCascadeRefresh() {
return cascadeInfo.isRefresh();
}
public boolean isSaveRecurseSkippable(Object bean) {
return saveRecurseSkippable && bean instanceof EntityBean && !((EntityBean) bean)._ebean_getIntercept().isNewOrDirty();
}
/**
* Return true if save can be skipped for unmodified bean(s) of this
* property.
* <p>
* That is, if a bean of this property is unmodified we don't need to
* saveRecurse because none of its associated beans have cascade save set to
* true.
* </p>
*/
public boolean isSaveRecurseSkippable() {
return saveRecurseSkippable;
}
/**
* Return true if save can be skipped for unmodified bean(s) of this
* property.
* <p>
* That is, if a bean of this property is unmodified we don't need to
* saveRecurse because none of its associated beans have cascade save set to
* true.
* </p>
*/
public boolean isSaveRecurseSkippable() {
return saveRecurseSkippable;
}
/**
* Return true if the unique id properties are all not null for this bean.
*/
public boolean hasId(EntityBean bean) {
/**
* Return true if the unique id properties are all not null for this bean.
*/
public boolean hasId(EntityBean bean) {
BeanDescriptor<?> targetDesc = getTargetDescriptor();
BeanProperty idProp = targetDesc.getIdProperty();
if (idProp != null) {
Object value = idProp.getValue(bean);
if (value == null) {
return false;
}
}
// all the unique properties are non-null
return true;
}
BeanDescriptor<?> targetDesc = getTargetDescriptor();
BeanProperty idProp = targetDesc.getIdProperty();
if (idProp != null) {
Object value = idProp.getValue(bean);
if (value == null) {
return false;
}
}
// all the unique properties are non-null
return true;
}
/**
* Return the type of the target.
* <p>
* This is the class of the associated bean, or beans contained in a list,
* set or map.
* </p>
*/
public Class<?> getTargetType() {
return targetType;
}
/**
* Return the type of the target.
* <p>
* This is the class of the associated bean, or beans contained in a list,
* set or map.
* </p>
*/
public Class<?> getTargetType() {
return targetType;
}
/**
* Return an extra clause to add to the query for loading or joining
* to this bean type.
*/
public String getExtraWhere() {
return extraWhere;
}
/**
* Return an extra clause to add to the query for loading or joining
* to this bean type.
*/
public String getExtraWhere() {
return extraWhere;
}
/**
* Return the elastic search doc for this embedded property.
@@ -280,104 +285,104 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty {
}
}
/**
* Return true if this association is updateable.
*/
public boolean isUpdateable() {
/**
* Return true if this association is updateable.
*/
public boolean isUpdateable() {
return tableJoin.columns().length <= 0 || tableJoin.columns()[0].isUpdateable();
}
/**
* Return true if this association is insertable.
*/
public boolean isInsertable() {
/**
* Return true if this association is insertable.
*/
public boolean isInsertable() {
return tableJoin.columns().length <= 0 || tableJoin.columns()[0].isInsertable();
}
/**
* return the join to use for the bean.
*/
public TableJoin getTableJoin() {
return tableJoin;
}
/**
* return the join to use for the bean.
*/
public TableJoin getTableJoin() {
return tableJoin;
}
/**
* Get the persist info.
*/
public BeanCascadeInfo getCascadeInfo() {
return cascadeInfo;
}
/**
* Get the persist info.
*/
public BeanCascadeInfo getCascadeInfo() {
return cascadeInfo;
}
/**
* Build the list of imported property. Matches BeanProperty from the target
* descriptor back to local database columns in the TableJoin.
*/
protected ImportedId createImportedId(BeanPropertyAssoc<?> owner, BeanDescriptor<?> target, TableJoin join) {
/**
* Build the list of imported property. Matches BeanProperty from the target
* descriptor back to local database columns in the TableJoin.
*/
protected ImportedId createImportedId(BeanPropertyAssoc<?> owner, BeanDescriptor<?> target, TableJoin join) {
BeanProperty idProp = target.getIdProperty();
BeanProperty[] others = target.propertiesBaseScalar();
BeanProperty idProp = target.getIdProperty();
BeanProperty[] others = target.propertiesBaseScalar();
if (descriptor.isSqlSelectBased()){
String dbColumn = owner.getDbColumn();
return new ImportedIdSimple(owner, dbColumn, idProp, 0);
}
if (descriptor.isSqlSelectBased()) {
String dbColumn = owner.getDbColumn();
return new ImportedIdSimple(owner, dbColumn, idProp, 0);
}
TableJoinColumn[] cols = join.columns();
TableJoinColumn[] cols = join.columns();
if (idProp == null) {
return null;
}
if (!idProp.isEmbedded()) {
// simple single scalar id
if (cols.length != 1){
String msg = "No Imported Id column for ["+idProp+"] in table ["+join.getTable()+"]";
logger.error(msg);
return null;
} else {
BeanProperty[] idProps = {idProp};
return createImportedScalar(owner, cols[0], idProps, others);
}
} else {
// embedded id
BeanPropertyAssocOne<?> embProp = (BeanPropertyAssocOne<?>)idProp;
BeanProperty[] embBaseProps = embProp.getTargetDescriptor().propertiesBaseScalar();
ImportedIdSimple[] scalars = createImportedList(owner, cols, embBaseProps, others);
if (idProp == null) {
return null;
}
if (!idProp.isEmbedded()) {
// simple single scalar id
if (cols.length != 1) {
String msg = "No Imported Id column for [" + idProp + "] in table [" + join.getTable() + "]";
logger.error(msg);
return null;
} else {
BeanProperty[] idProps = {idProp};
return createImportedScalar(owner, cols[0], idProps, others);
}
} else {
// embedded id
BeanPropertyAssocOne<?> embProp = (BeanPropertyAssocOne<?>) idProp;
BeanProperty[] embBaseProps = embProp.getTargetDescriptor().propertiesBaseScalar();
ImportedIdSimple[] scalars = createImportedList(owner, cols, embBaseProps, others);
return new ImportedIdEmbedded(owner, embProp, scalars);
}
}
return new ImportedIdEmbedded(owner, embProp, scalars);
}
}
private ImportedIdSimple[] createImportedList(BeanPropertyAssoc<?> owner, TableJoinColumn[] cols, BeanProperty[] props, BeanProperty[] others) {
private ImportedIdSimple[] createImportedList(BeanPropertyAssoc<?> owner, TableJoinColumn[] cols, BeanProperty[] props, BeanProperty[] others) {
ArrayList<ImportedIdSimple> list = new ArrayList<ImportedIdSimple>();
ArrayList<ImportedIdSimple> list = new ArrayList<ImportedIdSimple>();
for (int i = 0; i < cols.length; i++) {
list.add(createImportedScalar(owner, cols[i], props, others));
}
return ImportedIdSimple.sort(list);
}
for (int i = 0; i < cols.length; i++) {
list.add(createImportedScalar(owner, cols[i], props, others));
}
private ImportedIdSimple createImportedScalar(BeanPropertyAssoc<?> owner, TableJoinColumn col, BeanProperty[] props, BeanProperty[] others) {
return ImportedIdSimple.sort(list);
}
String matchColumn = col.getForeignDbColumn();
String localColumn = col.getLocalDbColumn();
for (int j = 0; j < props.length; j++) {
if (props[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
return new ImportedIdSimple(owner, localColumn, props[j], j);
}
}
private ImportedIdSimple createImportedScalar(BeanPropertyAssoc<?> owner, TableJoinColumn col, BeanProperty[] props, BeanProperty[] others) {
for (int j = 0; j < others.length; j++) {
if (others[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
return new ImportedIdSimple(owner, localColumn, others[j], j+props.length);
}
}
String msg = "Error with the Join on ["+getFullBeanName()
+"]. Could not find the local match for ["+matchColumn+"] "//in table["+searchTable+"]?"
+" Perhaps an error in a @JoinColumn";
throw new PersistenceException(msg);
}
String matchColumn = col.getForeignDbColumn();
String localColumn = col.getLocalDbColumn();
for (int j = 0; j < props.length; j++) {
if (props[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
return new ImportedIdSimple(owner, localColumn, props[j], j);
}
}
for (int j = 0; j < others.length; j++) {
if (others[j].getDbColumn().equalsIgnoreCase(matchColumn)) {
return new ImportedIdSimple(owner, localColumn, others[j], j + props.length);
}
}
String msg = "Error with the Join on [" + getFullBeanName()
+ "]. Could not find the local match for [" + matchColumn + "] "//in table["+searchTable+"]?"
+ " Perhaps an error in a @JoinColumn";
throw new PersistenceException(msg);
}
}
@@ -265,12 +265,11 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
*/
public void resetMany(EntityBean bean) {
Object value = getValue(bean);
if (value == null) {
// not expecting this - set an empty reference
createReference(bean);
} else {
if (value instanceof BeanCollection) {
// reset the collection back to empty
((BeanCollection)value).reset(bean, name);
} else {
createReference(bean);
}
}
@@ -638,6 +637,8 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> {
if (v instanceof BeanCollection<?>) {
BeanCollection<?> bc = (BeanCollection<?>) v;
return bc.isReference() ? bc : null;
} else if (v != null) {
return null;
} else {
return createReference(parentBean);
}
@@ -1,7 +1,7 @@
package com.avaje.ebeaninternal.server.deploy;
import com.avaje.ebean.event.BeanQueryAdapter;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -3,7 +3,7 @@ package com.avaje.ebeaninternal.server.deploy;
import java.util.List;
import com.avaje.ebean.event.BeanPersistController;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1,7 +1,7 @@
package com.avaje.ebeaninternal.server.deploy;
import com.avaje.ebean.event.BeanPersistListener;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1,7 +1,7 @@
package com.avaje.ebeaninternal.server.deploy;
import com.avaje.ebean.event.BeanPostLoad;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -477,7 +477,7 @@ public class DeployBeanDescriptor<T> {
* Return the BeanPersistController (could be a chain of them, 1 or null).
*/
public BeanPersistController getPersistController() {
if (persistControllers.size() == 0) {
if (persistControllers.isEmpty()) {
return null;
} else if (persistControllers.size() == 1) {
return persistControllers.get(0);
@@ -490,7 +490,7 @@ public class DeployBeanDescriptor<T> {
* Return the BeanPersistListener (could be a chain of them, 1 or null).
*/
public BeanPersistListener getPersistListener() {
if (persistListeners.size() == 0) {
if (persistListeners.isEmpty()) {
return null;
} else if (persistListeners.size() == 1) {
return persistListeners.get(0);
@@ -500,7 +500,7 @@ public class DeployBeanDescriptor<T> {
}
public BeanQueryAdapter getQueryAdapter() {
if (queryAdapters.size() == 0) {
if (queryAdapters.isEmpty()) {
return null;
} else if (queryAdapters.size() == 1) {
return queryAdapters.get(0);
@@ -513,7 +513,7 @@ public class DeployBeanDescriptor<T> {
* Return the BeanPostLoad (could be a chain of them, 1 or null).
*/
public BeanPostLoad getPostLoad() {
if (postLoaders.size() == 0) {
if (postLoaders.isEmpty()) {
return null;
} else if (postLoaders.size() == 1) {
return postLoaders.get(0);
@@ -46,7 +46,7 @@ public class DeployTableJoin {
* Return true if the JoinOnPair have been set.
*/
public boolean hasJoinColumns() {
return columns.size() > 0;
return !columns.isEmpty();
}
/**
@@ -1,6 +1,6 @@
package com.avaje.ebeaninternal.server.deploy.parse;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
@@ -925,6 +925,21 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return parentExprList == null ? this : parentExprList;
}
@Override
public ExpressionList<T> endAnd() {
return endJunction();
}
@Override
public ExpressionList<T> endOr() {
return endJunction();
}
@Override
public ExpressionList<T> endNot() {
return endJunction();
}
@Override
public Junction<T> and() {
return conjunction();
@@ -776,4 +776,18 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
return exprList.endJunction();
}
@Override
public ExpressionList<T> endAnd() {
return endJunction();
}
@Override
public ExpressionList<T> endOr() {
return endJunction();
}
@Override
public ExpressionList<T> endNot() {
return endJunction();
}
}
@@ -10,7 +10,7 @@ import java.util.UUID;
*/
public class UuidIdGenerator implements PlatformIdGenerator {
public static UuidIdGenerator INSTANCE = new UuidIdGenerator();
public static final UuidIdGenerator INSTANCE = new UuidIdGenerator();
/**
* Return UUID from UUID.randomUUID();
@@ -567,7 +567,7 @@ public final class DefaultPersister implements Persister {
*/
public int deleteMany(Class<?> beanType, Collection<?> ids, Transaction transaction, boolean permanent) {
if (ids == null || ids.size() == 0) {
if (ids == null || ids.isEmpty()) {
return 0;
}
@@ -139,10 +139,10 @@ public class CQueryBuilder {
if (!sqlTree.isIncludeJoins()) {
// simple - update table set ... where ...
return aliasStrip(buildSql(updateClause, request, predicates, sqlTree).getSql());
return aliasStrip(buildSqlUpdate(updateClause, request, predicates, sqlTree).getSql());
}
// wrap as - update table set ... where id in (select id ...)
String sql = buildSql(null, request, predicates, sqlTree).getSql();
String sql = buildSqlUpdate(null, request, predicates, sqlTree).getSql();
sql = updateClause + " " + request.getBeanDescriptor().getWhereIdInSql() + "in (" + sql + ")";
String alias = (rootTableAlias == null) ? "t0" : rootTableAlias;
sql = aliasReplace(sql, alias);
@@ -406,7 +406,21 @@ public class CQueryBuilder {
return new SqlTreeBuilder(request, predicates, detail, rawNoId).build();
}
/**
* Return the SQL response with row limiting (when not an update statement).
*/
private SqlLimitResponse buildSql(String selectClause, OrmQueryRequest<?> request, CQueryPredicates predicates, SqlTree select) {
return buildSql(selectClause, request, predicates, select, false);
}
/**
* Return the SQL response for update statement (stripping table alias for find by id expression).
*/
private SqlLimitResponse buildSqlUpdate(String selectClause, OrmQueryRequest<?> request, CQueryPredicates predicates, SqlTree select) {
return buildSql(selectClause, request, predicates, select, true);
}
private SqlLimitResponse buildSql(String selectClause, OrmQueryRequest<?> request, CQueryPredicates predicates, SqlTree select, boolean stripAlias) {
SpiQuery<?> query = request.getQuery();
@@ -471,6 +485,10 @@ public class CQueryBuilder {
throw new IllegalStateException("Executing FindById query on entity bean " + desc.getName()
+ " that doesn't have an @Id property??");
}
if (stripAlias) {
// strip the table alias for use in update statement
idSql = StringHelper.replaceString(idSql, "t0.","");
}
sb.append(idSql).append(" ");
hasWhere = true;
}
@@ -2,7 +2,6 @@ package com.avaje.ebeaninternal.server.query;
import com.avaje.ebean.RawSql;
import com.avaje.ebeaninternal.api.BindParams;
import com.avaje.ebeaninternal.api.BindParams.OrderedList;
import com.avaje.ebeaninternal.api.SpiExpressionList;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.core.OrmQueryRequest;
@@ -54,11 +53,6 @@ public class CQueryPredicates {
*/
private final BindParams bindParams;
/**
* Named bind parameters for the having clause.
*/
private OrderedList havingNamedParams;
/**
* Bind values from the where expressions.
*/
@@ -79,11 +73,6 @@ public class CQueryPredicates {
*/
private String whereExprSql;
/**
* SQL generated from where with named parameters.
*/
private String whereRawSql;
/**
* Bind values for having expression.
*/
@@ -94,11 +83,6 @@ public class CQueryPredicates {
*/
private String havingExprSql;
/**
* SQL generated from having with named parameters.
*/
private String havingRawSql;
private String dbHaving;
/**
@@ -193,11 +177,6 @@ public class CQueryPredicates {
}
}
if (havingNamedParams != null) {
// bind named parameters in having...
binder.bind(havingNamedParams.list(), dataBind, dataBind.log());
}
if (having != null) {
having.bind(dataBind);
}
@@ -214,84 +193,26 @@ public class CQueryPredicates {
}
}
private void buildBindHavingRawSql(boolean buildSql, boolean parseRaw, DeployParser deployParser) {
if (buildSql || bindParams != null) {
// having clause with named parameters...
havingRawSql = query.getAdditionalHaving();
if (parseRaw) {
havingRawSql = deployParser.parse(havingRawSql);
}
if (havingRawSql != null && bindParams != null) {
// convert and order named parameters if required
havingNamedParams = BindParamsParser.parseNamedParams(bindParams, havingRawSql);
havingRawSql = havingNamedParams.getPreparedSql();
}
}
}
/**
* Convert named parameters into an OrderedList.
*/
private void buildBindWhereRawSql(boolean buildSql, boolean parseRaw, DeployParser parser) {
if (buildSql || bindParams != null) {
whereRawSql = buildWhereRawSql();
boolean hasRaw = !"".equals(whereRawSql);
if (hasRaw && parseRaw) {
// parse with encrypted property awareness. This means that if we have
// an encrypted property we will insert special named parameter place
// holders for binding the encryption key values
parser.setEncrypted(true);
whereRawSql = parser.parse(whereRawSql);
parser.setEncrypted(false);
}
private void buildBindWhereRawSql(boolean buildSql) {
if (bindParams != null) {
if (hasRaw) {
whereRawSql = BindParamsParser.parse(bindParams, whereRawSql, request.getBeanDescriptor());
} else if (query.isRawSql() && !buildSql) {
// RawSql query hit cached query plan. Need to convert
// named parameters into positioned parameters so that
// the named parameters are bound
RawSql.Sql sql = query.getRawSql().getSql();
String s = sql.isParsed() ? sql.getPreWhere() : sql.getUnparsedSql();
if (bindParams.requiresNamedParamsPrepare()) {
BindParamsParser.parse(bindParams, s);
}
}
}
if (!buildSql && query.isRawSql() && bindParams != null && bindParams.requiresNamedParamsPrepare()) {
// RawSql query hit cached query plan. Need to convert
// named parameters into positioned parameters so that
// the named parameters are bound
RawSql.Sql sql = query.getRawSql().getSql();
String s = sql.isParsed() ? sql.getPreWhere() : sql.getUnparsedSql();
BindParamsParser.parse(bindParams, s);
}
}
private String buildWhereRawSql() {
// this is the where part of a OQL query which
// may contain bind parameters...
String whereRaw = query.getRawWhereClause();
if (whereRaw == null) {
whereRaw = "";
}
// add any additional stuff to the where clause
String additionalWhere = query.getAdditionalWhere();
if (additionalWhere != null) {
whereRaw += additionalWhere;
}
return whereRaw;
}
public void prepare(boolean buildSql) {
DeployParser deployParser = request.createDeployParser();
prepare(buildSql, true, deployParser);
}
/**
* This combines the sql from named/positioned parameters and expressions.
*/
private void prepare(boolean buildSql, boolean parseRaw, DeployParser deployParser) {
buildUpdateClause(buildSql, deployParser);
buildBindWhereRawSql(buildSql, parseRaw, deployParser);
buildBindHavingRawSql(buildSql, parseRaw, deployParser);
buildBindWhereRawSql(buildSql);
SpiExpressionList<?> whereExp = query.getWhereExpressions();
if (whereExp != null) {
@@ -360,7 +281,7 @@ public class CQueryPredicates {
}
private String deriveWhere(DeployParser deployParser) {
return parse(whereRawSql, whereExprSql, deployParser);
return parse(whereExprSql, deployParser);
}
/**
@@ -387,12 +308,9 @@ public class CQueryPredicates {
return s == null || s.length() == 0;
}
private String parse(String raw, String expr, DeployParser deployParser) {
private String parse(String expr, DeployParser deployParser) {
StringBuilder sb = new StringBuilder();
if (!isEmpty(raw)) {
sb.append(raw);
}
if (!isEmpty(expr)) {
if (sb.length() > 0) {
sb.append(" and ");
@@ -403,7 +321,7 @@ public class CQueryPredicates {
}
private String deriveHaving(DeployParser deployParser) {
return parse(havingRawSql, havingExprSql, deployParser);
return parse(havingExprSql, deployParser);
}
private String parseOrderBy() {
@@ -81,11 +81,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
*/
private int lazyLoadBatchSize;
/**
* The where clause from a parsed query string.
*/
private String rawWhereClause;
private OrderBy<T> orderBy;
private String loadMode;
@@ -99,10 +94,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
*/
private String query;
private String additionalWhere;
private String additionalHaving;
private String lazyLoadProperty;
private String lazyLoadManyPath;
@@ -531,7 +522,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
List<SpiExpression> exprList = whereExpressions.internalList();
if (exprList.size() > 1) {
return null;
} else if (exprList.size() == 0) {
} else if (exprList.isEmpty()) {
return namedBind;
} else {
if (namedBind != null) {
@@ -563,8 +554,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
copy.query = query;
copy.rootTableAlias = rootTableAlias;
copy.additionalWhere = additionalWhere;
copy.additionalHaving = additionalHaving;
copy.distinct = distinct;
copy.sqlDistinct = sqlDistinct;
copy.timeout = timeout;
@@ -580,7 +569,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
copy.temporalMode = temporalMode;
copy.firstRow = firstRow;
copy.maxRows = maxRows;
copy.rawWhereClause = rawWhereClause;
if (orderBy != null) {
copy.orderBy = orderBy.copy();
}
@@ -599,7 +587,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
copy.parentNode = parentNode;
copy.forUpdate = forUpdate;
copy.rawSql = rawSql;
copy.rawWhereClause = rawWhereClause;
return copy;
}
@@ -831,7 +818,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
CQueryPlanKey createQueryPlanKey() {
queryPlanKey = new OrmQueryPlanKey(includeTableJoin, type, detail, maxRows, firstRow,
disableLazyLoading, rawWhereClause, orderBy, query, additionalWhere, additionalHaving,
disableLazyLoading, orderBy, query,
distinct, sqlDistinct, mapKey, id, bindParams, whereExpressions, havingExpressions,
temporalMode, forUpdate, rootTableAlias, rawSql, updateProperties);
@@ -901,14 +888,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return rawSql != null;
}
/**
* Return any additional where clauses.
*/
@Override
public String getAdditionalWhere() {
return additionalWhere;
}
/**
* Return the timeout.
*/
@@ -917,14 +896,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return timeout;
}
/**
* Return any additional having clauses.
*/
@Override
public String getAdditionalHaving() {
return additionalHaving;
}
@Override
public boolean hasMaxRowsOrFirstRow() {
return maxRows > 0 || firstRow > 0;
@@ -1002,10 +973,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return this;
}
protected void setRawWhereClause(String rawWhereClause) {
this.rawWhereClause = rawWhereClause;
}
@Override
public DefaultOrmQuery<T> select(String columns) {
detail.select(columns);
@@ -1164,14 +1131,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return orderBy;
}
/**
* Return the order by clause.
*/
@Override
public String getRawWhereClause() {
return rawWhereClause;
}
@Override
public OrderBy<T> orderBy() {
return order();
@@ -1335,22 +1294,9 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return query;
}
@Override
public DefaultOrmQuery<T> where(String addToWhereClause) {
if (additionalWhere == null) {
additionalWhere = addToWhereClause;
} else {
additionalWhere += " " + addToWhereClause;
}
return this;
}
@Override
public DefaultOrmQuery<T> where(Expression expression) {
if (whereExpressions == null) {
whereExpressions = new DefaultExpressionList<T>(this, null);
}
whereExpressions.add(expression);
where().add(expression);
return this;
}
@@ -1371,22 +1317,9 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
return whereExpressions;
}
@Override
public DefaultOrmQuery<T> having(String addToHavingClause) {
if (additionalHaving == null) {
additionalHaving = addToHavingClause;
} else {
additionalHaving += " " + addToHavingClause;
}
return this;
}
@Override
public DefaultOrmQuery<T> having(Expression expression) {
if (havingExpressions == null) {
havingExpressions = new DefaultExpressionList<T>(this, null);
}
havingExpressions.add(expression);
having().add(expression);
return this;
}
@@ -198,7 +198,7 @@ public class OrmQueryDetail implements Serializable {
}
}
if (matchingPaths.size() == 0) {
if (matchingPaths.isEmpty()) {
return null;
}
@@ -36,14 +36,6 @@ public class OrmQueryDetailParser {
return detail;
}
protected void assign(DefaultOrmQuery<?> query) {
query.setOrmQueryDetail(detail);
query.setFirstRow(firstRow);
query.setMaxRows(maxRows);
query.setRawWhereClause(rawWhereClause);
query.order(rawOrderBy);
}
private void processInitial() {
if (parser.isMatch("select")) {
readSelect();
@@ -25,10 +25,7 @@ public class OrmQueryPlanKey implements CQueryPlanKey {
private final int maxRows;
private final int firstRow;
private final boolean disableLazyLoading;
private final String rawWhereClause;
private final String query;
private final String additionalWhere;
private final String additionalHaving;
private final boolean distinct;
private final boolean sqlDistinct;
private final String mapKey;
@@ -40,7 +37,7 @@ public class OrmQueryPlanKey implements CQueryPlanKey {
private final int planHash;
private final int bindCount;
public OrmQueryPlanKey(TableJoin includeTableJoin, SpiQuery.Type type, OrmQueryDetail detail, int maxRows, int firstRow, boolean disableLazyLoading, String rawWhereClause, OrderBy<?> orderBy, String query, String additionalWhere, String additionalHaving, boolean distinct, boolean sqlDistinct, String mapKey, Object id, BindParams bindParams, SpiExpression whereExpressions, SpiExpression havingExpressions, SpiQuery.TemporalMode temporalMode, boolean forUpdate, String rootTableAlias, RawSql rawSql, OrmUpdateProperties updateProperties) {
public OrmQueryPlanKey(TableJoin includeTableJoin, SpiQuery.Type type, OrmQueryDetail detail, int maxRows, int firstRow, boolean disableLazyLoading, OrderBy<?> orderBy, String query, boolean distinct, boolean sqlDistinct, String mapKey, Object id, BindParams bindParams, SpiExpression whereExpressions, SpiExpression havingExpressions, SpiQuery.TemporalMode temporalMode, boolean forUpdate, String rootTableAlias, RawSql rawSql, OrmUpdateProperties updateProperties) {
this.includeTableJoin = includeTableJoin;
this.type = type;
@@ -48,11 +45,8 @@ public class OrmQueryPlanKey implements CQueryPlanKey {
this.maxRows = maxRows;
this.firstRow = firstRow;
this.disableLazyLoading = disableLazyLoading;
this.rawWhereClause = rawWhereClause;
this.orderByAsSting = (orderBy == null) ? null : orderBy.toStringFormat();
this.query = query;
this.additionalWhere = additionalWhere;
this.additionalHaving = additionalHaving;
this.distinct = distinct;
this.sqlDistinct = sqlDistinct;
this.mapKey = mapKey;
@@ -72,7 +66,6 @@ public class OrmQueryPlanKey implements CQueryPlanKey {
builder.add(distinct).add(sqlDistinct).add(query);
builder.add(firstRow).add(maxRows);
builder.add(orderBy).add(forUpdate);
builder.add(rawWhereClause).add(additionalWhere).add(additionalHaving);
builder.add(mapKey);
builder.add(disableLazyLoading);
builder.add(hasIdValue);
@@ -138,10 +131,7 @@ public class OrmQueryPlanKey implements CQueryPlanKey {
// if (detail != null ? !detail.equals(that.detail) : that.detail != null) return false;
if (rawWhereClause != null ? !rawWhereClause.equals(that.rawWhereClause) : that.rawWhereClause != null) return false;
if (query != null ? !query.equals(that.query) : that.query != null) return false;
if (additionalWhere != null ? !additionalWhere.equals(that.additionalWhere) : that.additionalWhere != null) return false;
if (additionalHaving != null ? !additionalHaving.equals(that.additionalHaving) : that.additionalHaving != null) return false;
if (mapKey != null ? !mapKey.equals(that.mapKey) : that.mapKey != null) return false;
return rootTableAlias != null ? rootTableAlias.equals(that.rootTableAlias) : that.rootTableAlias == null;
}
@@ -5,7 +5,7 @@ import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebeaninternal.api.SpiTransaction;
import com.avaje.ebeanservice.docstore.api.DocStoreUpdateProcessor;
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
import java.sql.Connection;
@@ -17,10 +17,10 @@ import java.sql.Connection;
*/
public class AutoCommitTransactionManager extends TransactionManager {
public AutoCommitTransactionManager(ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
public AutoCommitTransactionManager(boolean localL2Caching, ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
DocStoreUpdateProcessor indexUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
super(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
super(localL2Caching, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
}
/**
@@ -6,7 +6,7 @@ import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebeaninternal.api.SpiTransaction;
import com.avaje.ebeanservice.docstore.api.DocStoreUpdateProcessor;
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
import javax.sql.DataSource;
@@ -17,10 +17,10 @@ import java.sql.Connection;
*/
public class ExplicitTransactionManager extends TransactionManager {
public ExplicitTransactionManager(ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
public ExplicitTransactionManager(boolean localL2Caching, ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
DocStoreUpdateProcessor indexUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
super(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
super(localL2Caching, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
}
/**
@@ -4,6 +4,7 @@ import com.avaje.ebean.TransactionCallback;
import com.avaje.ebean.annotation.DocStoreMode;
import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebean.config.PersistBatch;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.DatabasePlatform.OnQueryOnly;
import com.avaje.ebean.event.changelog.BeanChange;
import com.avaje.ebean.event.changelog.ChangeSet;
@@ -151,6 +152,16 @@ public class JdbcTransaction implements SpiTransaction {
protected int docStoreBatchSize;
/**
* Explicit control over skipCache.
*/
protected Boolean skipCache;
/**
* Default skip cache behavior from {@link ServerConfig#isSkipCacheAfterWrite()}.
*/
protected final boolean skipCacheAfterWrite;
/**
* Create a new JdbcTransaction.
*/
@@ -162,11 +173,20 @@ public class JdbcTransaction implements SpiTransaction {
this.explicit = explicit;
this.manager = manager;
this.connection = connection;
this.batchMode = manager == null ? PersistBatch.NONE : manager.getPersistBatch();
this.batchOnCascadeMode = manager == null ? PersistBatch.NONE : manager.getPersistBatchOnCascade();
this.onQueryOnly = manager == null ? OnQueryOnly.ROLLBACK : manager.getOnQueryOnly();
this.persistenceContext = new DefaultPersistenceContext();
if (manager == null) {
this.skipCacheAfterWrite = true;
this.batchMode = PersistBatch.NONE;
this.batchOnCascadeMode = PersistBatch.NONE;
this.onQueryOnly = OnQueryOnly.ROLLBACK;
} else {
this.skipCacheAfterWrite = manager.isSkipCacheAfterWrite();
this.batchMode = manager.getPersistBatch();
this.batchOnCascadeMode = manager.getPersistBatchOnCascade();
this.onQueryOnly = manager.getOnQueryOnly();
}
checkAutoCommit(connection);
} catch (Exception e) {
@@ -197,6 +217,17 @@ public class JdbcTransaction implements SpiTransaction {
return sb.toString();
}
@Override
public boolean isSkipCache() {
if (skipCache != null) return skipCache;
return skipCacheAfterWrite && !queryOnly;
}
@Override
public void setSkipCache(boolean skipCache) {
this.skipCache = skipCache;
}
@Override
public String getLogPrefix() {
return logPrefix;
@@ -84,9 +84,15 @@ public final class PostCommitProcessing {
/**
* Notify the local part of L2 cache.
*/
void notifyLocalCache(boolean viewInvalidation) {
void notifyLocalCache() {
processTableEvents(event.getEventTables());
cacheChanges = event.buildCacheChanges(viewInvalidation);
if (manager.localL2Caching) {
// process l2 cache changes in foreground
processCacheChanges(event.buildCacheChanges(manager.viewInvalidation));
} else {
// collect l2 cache changes for delayed background processing
cacheChanges = event.buildCacheChanges(manager.viewInvalidation);
}
}
/**
@@ -148,9 +154,7 @@ public final class PostCommitProcessing {
Runnable backgroundNotify() {
return new Runnable() {
public void run() {
if (cacheChanges != null) {
manager.processViewInvalidation(cacheChanges.apply());
}
processCacheChanges(cacheChanges);
localPersistListenersNotify();
notifyCluster();
processDocStoreUpdates();
@@ -158,6 +162,15 @@ public final class PostCommitProcessing {
};
}
/**
* Apply the changes to the L2 caches.
*/
private void processCacheChanges(CacheChangeSet cacheChanges) {
if (cacheChanges != null) {
manager.processViewInvalidation(cacheChanges.apply());
}
}
private void localPersistListenersNotify() {
if (persistBeanRequests != null) {
for (int i = 0; i < persistBeanRequests.size(); i++) {
@@ -14,7 +14,7 @@ import com.avaje.ebeaninternal.api.TransactionEvent;
import com.avaje.ebeaninternal.api.TransactionEventTable;
import com.avaje.ebeaninternal.api.TransactionEventTable.TableIUD;
import com.avaje.ebeaninternal.server.cluster.ClusterManager;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager;
import org.avaje.datasource.DataSourcePool;
import com.avaje.ebeanservice.docstore.api.DocStoreUpdateProcessor;
@@ -105,14 +105,20 @@ public class TransactionManager {
*/
private final ChangeLogListener changeLogListener;
private final boolean viewInvalidation;
protected final boolean localL2Caching;
protected final boolean viewInvalidation;
private final boolean skipCacheAfterWrite;
/**
* Create the TransactionManager
*/
public TransactionManager(ServerConfig config, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor, DocStoreUpdateProcessor docStoreUpdateProcessor,
BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
public TransactionManager(boolean localL2Caching, ServerConfig config, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
DocStoreUpdateProcessor docStoreUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
this.skipCacheAfterWrite = config.isSkipCacheAfterWrite();
this.localL2Caching = localL2Caching;
this.persistBatch = config.getPersistBatch();
this.persistBatchOnCascade = config.appliedPersistBatchOnCascade();
this.beanDescriptorManager = descMgr;
@@ -146,6 +152,10 @@ public class TransactionManager {
return docStoreActive;
}
public boolean isSkipCacheAfterWrite() {
return skipCacheAfterWrite;
}
public BeanDescriptorManager getBeanDescriptorManager() {
return beanDescriptorManager;
}
@@ -402,7 +412,7 @@ public class TransactionManager {
}
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, transaction);
postCommit.notifyLocalCache(viewInvalidation);
postCommit.notifyLocalCache();
backgroundExecutor.execute(postCommit.backgroundNotify());
for (TransactionEventListener listener : transactionEventListeners) {
@@ -427,7 +437,7 @@ public class TransactionManager {
event.add(tableEvents);
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, event);
postCommit.notifyLocalCache(viewInvalidation);
postCommit.notifyLocalCache();
backgroundExecutor.execute(postCommit.backgroundNotify());
}
@@ -11,7 +11,7 @@ import com.avaje.ebean.config.ScalarTypeConverter;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.config.dbplatform.DbType;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.type.reflect.CheckImmutable;
import com.avaje.ebeaninternal.server.type.reflect.CheckImmutableResponse;
import com.avaje.ebeaninternal.server.type.reflect.ImmutableMeta;
@@ -86,7 +86,11 @@ public class ScalarTypeArrayList extends ScalarTypeJsonCollection<List> {
@Override
public List read(DataReader reader) throws SQLException {
Array array = reader.getArray();
return fromArray((Object[]) array.getArray());
if (array == null) {
return null;
} else {
return fromArray((Object[]) array.getArray());
}
}
@Override
@@ -1,19 +0,0 @@
package com.avaje.ebeaninternal.server.util;
/**
* Get the paths used to search for entity beans etc.
* <p>
* Typically this will return a URL[] of the classpath.
* </p>
*/
public interface ClassPathReader {
/**
* Return the paths in the classpath to search for entity beans etc.
* <p>
* This will typically return a URL[] or String[] of the entries in the
* class path.
* </p>
*/
Object[] readPath(ClassLoader classLoader);
}
@@ -1,154 +0,0 @@
package com.avaje.ebeaninternal.server.util;
import java.util.HashSet;
import java.util.Set;
/**
* Used to reduce the classes searched by excluding jars and packages.
*/
public class ClassPathSearchFilter {
private static final String COM_AVAJE_EBEANINTERNAL_SERVER_BEAN = "com.avaje.ebeaninternal.server.bean";
private static final String COM_AVAJE_EBEAN_META = "com.avaje.ebean.meta";
private boolean defaultPackageMatch = true;
private boolean defaultJarMatch = false;
private final HashSet<String> includePackageSet = new HashSet<String>();
private final HashSet<String> excludePackageSet = new HashSet<String>();
private final HashSet<String> includeJarSet = new HashSet<String>();
private final HashSet<String> excludeJarSet = new HashSet<String>();
public ClassPathSearchFilter() {
addDefaultExcludePackages();
}
/**
* Return the explicit packages that should be searched.
*/
public Set<String> getIncludePackages() {
return includePackageSet;
}
/**
* Add some packages which by default will be excluded from a search.
* <p>
* This includes java, javax, etc.
* </p>
* <p>
* This is not used when the includePackages is set, but can speed a search
* when includePackages has not been set.
* </p>
*/
public void addDefaultExcludePackages() {
excludePackage("sun");
excludePackage("com.sun");
excludePackage("java");
excludePackage("javax");
excludePackage("junit");
excludePackage("org.w3c");
excludePackage("org.xml");
excludePackage("org.apache");
excludePackage("com.mysql");
excludePackage("oracle.jdbc");
excludePackage("com.microsoft.sqlserver");
excludePackage("com.avaje.ebean");
excludePackage("com.avaje.lib");
}
/**
* Set the default for jar matching when a jar is neither explicitly
* included or excluded.
*/
public void setDefaultJarMatch(boolean defaultJarMatch) {
this.defaultJarMatch = defaultJarMatch;
}
/**
* Set the default for package matching when a package is neither explicitly
* included or excluded.
*/
public void setDefaultPackageMatch(boolean defaultPackageMatch) {
this.defaultPackageMatch = defaultPackageMatch;
}
/**
* Add a package to explicitly include in the search.
*/
public void includePackage(String pckgName) {
includePackageSet.add(pckgName);
}
/**
* Add a package to explicitly exclude in the search.
*/
public void excludePackage(String pckgName) {
excludePackageSet.add(pckgName);
}
/**
* Add a jar to explicitly include in the search.
*/
public void includeJar(String jarName) {
includeJarSet.add(jarName);
}
/**
* Return true if the package should be included in the search.
*/
public boolean isSearchPackage(String packageName) {
// special case... "meta" entity beans.
if (COM_AVAJE_EBEAN_META.equals(packageName)) {
return true;
}
// special case... BeanFinders etc for "meta" beans.
if (COM_AVAJE_EBEANINTERNAL_SERVER_BEAN.equals(packageName)) {
return true;
}
if (includePackageSet != null && !includePackageSet.isEmpty()){
return containedIn(includePackageSet, packageName);
}
if (containedIn(excludePackageSet, packageName)) {
return false;
}
return defaultPackageMatch;
}
/**
* Return true if the jar should be included in the search.
*/
public boolean isSearchJar(String jarName, String jarOffset) {
if (containedIn(includeJarSet, jarName)) {
return true;
}
if (containedIn(excludeJarSet, jarName)) {
return false;
}
// by default scan the root level in runnable jar (spring boot etc)
return "/".equals(jarOffset) || defaultJarMatch;
}
/**
* Helper method to determine is a match is contained in the set.
*/
protected boolean containedIn(HashSet<String> set, String match) {
if (set.contains(match)) {
return true;
}
for (String val : set) {
if (match.contains(val)) {
return true;
}
}
return false;
}
}
@@ -1,16 +0,0 @@
package com.avaje.ebeaninternal.server.util;
/**
* Defines interface for finding classes via a class path search.
*/
public interface ClassPathSearchMatcher {
/**
* Return true if the class matches the specific search.
* <p>
* Note that the location in terms of jars and packages is noted and can be
* used to make future searches faster.
* </p>
*/
boolean isMatch(Class<?> cls);
}
@@ -1,67 +0,0 @@
package com.avaje.ebeaninternal.server.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URLClassLoader;
/**
* Default implementation for getting the classPath from the classLoader.
* <p>
* This class path is used to search for entity beans etc.
* </p>
*/
public class DefaultClassPathReader implements ClassPathReader {
private static final Logger logger = LoggerFactory.getLogger(DefaultClassPathReader.class);
public Object[] readPath(ClassLoader classLoader) {
if (classLoader instanceof URLClassLoader){
// this is really what we are hoping for
URLClassLoader ucl = (URLClassLoader)classLoader;
return ucl.getURLs();
}
try {
// search for a "getClassPath" method... resin2
Method method = classLoader.getClass().getMethod("getClassPath");
if (method != null){
logger.info("Using getClassPath() method on classLoader["+classLoader.getClass()+"]");
String s = method.invoke(classLoader).toString();
return s.split(File.pathSeparator);
}
} catch (NoSuchMethodException e) {
// Not really an error...
} catch (Exception e) {
throw new RuntimeException("Unexpected Error trying to read classpath from classloader", e);
}
try {
// search for a "getClasspath" method... Ant
Method method = classLoader.getClass().getMethod("getClasspath");
if (method != null){
logger.info("Using getClasspath() method on classLoader["+classLoader.getClass()+"]");
String s = method.invoke(classLoader).toString();
return s.split(File.pathSeparator);
}
} catch (NoSuchMethodException e) {
// Not really an error...
} catch (Exception e) {
throw new RuntimeException("Unexpected Error trying to read classpath from classloader", e);
}
String imsg = "Unsure how to read classpath from classLoader ["+classLoader.getClass()+"]";
logger.info(imsg);
String msg = "Using java.class.path system property to search for entity beans";
logger.warn(msg);
return System.getProperty("java.class.path", "").split(File.pathSeparator);
}
}
@@ -10,6 +10,7 @@ import com.avaje.ebeanservice.docstore.api.DocQueryRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* DocumentStore that barfs it is used.
@@ -20,6 +21,11 @@ public class NoneDocStore implements DocumentStore {
throw new IllegalStateException("DocStore implementation not included in the classPath. You need to add the maven dependency for avaje-ebeanorm-elastic");
}
@Override
public void indexSettings(String indexName, Map<String, Object> settings) {
throw implementationNotInClassPath();
}
@Override
public void dropIndex(String newIndex) {
throw implementationNotInClassPath();
@@ -41,11 +41,7 @@ public class BaseTestCase {
* Wait for the L2 cache to propagate changes post-commit.
*/
protected void awaitL2Cache() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// do nothing, used to thread sleep
}
protected <T> BeanDescriptor<T> getBeanDescriptor(Class<T> cls) {
@@ -0,0 +1,72 @@
package com.avaje.ebean;
import com.avaje.tests.model.basic.EBasic;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.OrderDetail;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
public class EbeanServer_refresh {
@Test
public void basic() {
EbeanServer server = Ebean.getDefaultServer();
EBasic basic = new EBasic("basic refresh");
basic.setStatus(EBasic.Status.NEW);
server.save(basic);
int rows =
server.update(EBasic.class)
.set("status", EBasic.Status.ACTIVE)
.where().idEq(basic.getId())
.update();
assertEquals(rows, 1);
server.refresh(basic);
assertEquals(basic.getStatus(), EBasic.Status.ACTIVE);
}
@Test
public void refresh_when_oneToManyLoaded() {
ResetBasicData.reset();
Order order = Ebean.find(Order.class, 1);
order.getCustomer().getName();
order.getDetails().size();
Ebean.refresh(order);
}
@Test
public void refresh_when_oneToManyVanilla() {
ResetBasicData.reset();
Order order = Ebean.find(Order.class, 1);
order.getCustomer().getName();
order.setDetails(new ArrayList<OrderDetail>());
Ebean.refresh(order);
}
@Test
public void refresh_when_oneToManyNull() {
ResetBasicData.reset();
Order order = Ebean.find(Order.class, 1);
order.getCustomer().getName();
order.setDetails(null);
Ebean.refresh(order);
}
}
@@ -60,29 +60,29 @@ public class TestRawSqlColumnParsing extends TestCase {
assertEquals(5, mapping.size());
Column c = mapping.get("a");
Column c = mapping.get("a0");
assertEquals("a",c.getDbColumn());
assertEquals(0, c.getIndexPos());
assertEquals("a0",c.getPropertyName());
c = mapping.get("b");
c = mapping.get("b1");
assertEquals("b",c.getDbColumn());
assertEquals(1, c.getIndexPos());
assertEquals("b1",c.getPropertyName());
c = mapping.get("c");
c = mapping.get("c2");
assertEquals("c",c.getDbColumn());
assertEquals(2, c.getIndexPos());
assertEquals("c2",c.getPropertyName());
c = mapping.get("d");
c = mapping.get("d3");
assertEquals("d",c.getDbColumn());
assertEquals(3, c.getIndexPos());
assertEquals("d3",c.getPropertyName());
c = mapping.get("e");
c = mapping.get("e4");
assertEquals("e",c.getDbColumn());
assertEquals(4, c.getIndexPos());
assertEquals("e4",c.getPropertyName());
@@ -96,29 +96,29 @@ public class TestRawSqlColumnParsing extends TestCase {
assertEquals(5, mapping.size());
Column c = mapping.get("a");
Column c = mapping.get("a0");
assertEquals("a",c.getDbColumn());
assertEquals(0, c.getIndexPos());
assertEquals("a0",c.getPropertyName());
c = mapping.get("b");
c = mapping.get("b1");
assertEquals("b",c.getDbColumn());
assertEquals(1, c.getIndexPos());
assertEquals("b1",c.getPropertyName());
c = mapping.get("MONTH(MAKEDATE(2015, 241))");
c = mapping.get("m2");
assertEquals("MONTH(MAKEDATE(2015, 241))",c.getDbColumn());
assertEquals(2, c.getIndexPos());
assertEquals("m2",c.getPropertyName());
c = mapping.get("d");
c = mapping.get("d3");
assertEquals("d",c.getDbColumn());
assertEquals(3, c.getIndexPos());
assertEquals("d3",c.getPropertyName());
c = mapping.get("e");
c = mapping.get("e4");
assertEquals("e",c.getDbColumn());
assertEquals(4, c.getIndexPos());
assertEquals("e4",c.getPropertyName());
@@ -132,29 +132,29 @@ public class TestRawSqlColumnParsing extends TestCase {
assertEquals(5, mapping.size());
Column c = mapping.get("a");
Column c = mapping.get("a0");
assertEquals("a",c.getDbColumn());
assertEquals(0, c.getIndexPos());
assertEquals("a0",c.getPropertyName());
c = mapping.get("'b'");
c = mapping.get("b1");
assertEquals("'b'",c.getDbColumn());
assertEquals(1, c.getIndexPos());
assertEquals("b1",c.getPropertyName());
c = mapping.get("\"c(blah)\"");
c = mapping.get("c2");
assertEquals("\"c(blah)\"",c.getDbColumn());
assertEquals(2, c.getIndexPos());
assertEquals("c2",c.getPropertyName());
c = mapping.get("d");
c = mapping.get("d3");
assertEquals("d",c.getDbColumn());
assertEquals(3, c.getIndexPos());
assertEquals("d3",c.getPropertyName());
c = mapping.get("e");
c = mapping.get("e4");
assertEquals("e",c.getDbColumn());
assertEquals(4, c.getIndexPos());
assertEquals("e4",c.getPropertyName());
@@ -3,7 +3,7 @@ package com.avaje.ebean.server.type;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.H2Platform;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import com.avaje.ebeaninternal.server.type.CtCompoundType;
import com.avaje.ebeaninternal.server.type.DefaultTypeManager;
import com.avaje.ebeaninternal.server.type.RsetDataReader;
@@ -0,0 +1,50 @@
package com.avaje.ebeaninternal.server.core.bootup;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class DistillPackagesTest {
@Test
public void when_unique_expect_all() throws Exception {
List<String> distill = DistillPackages.distill(group("one", "two"), group("three"));
assertThat(distill).containsExactly("one", "three", "two");
}
@Test
public void when_sub_expect_distilled() throws Exception {
List<String> distill = DistillPackages.distill(group("one", "one.sub"), group("three"));
assertThat(distill).containsExactly("one", "three");
}
@Test
public void when_sub_expect_distilled2() throws Exception {
List<String> distill = DistillPackages.distill(group("one", "one.sub"), group("one.foo"));
assertThat(distill).containsExactly("one");
}
@Test
public void when_subDotSub_expect_distilled2() throws Exception {
List<String> distill = DistillPackages.distill(group("one", "one.sub.me"), group("two"));
assertThat(distill).containsExactly("one", "two");
}
@Test
public void when_unordered_expect_naturalOrder() throws Exception {
List<String> distill = DistillPackages.distill(group("z.x.y","two"), group("one", "one.sub.me"));
assertThat(distill).containsExactly("one", "two", "z.x.y");
}
List<String> group(String... packages) {
return Arrays.asList(packages);
}
}
@@ -0,0 +1,30 @@
package com.avaje.ebeaninternal.server.core.bootup;
import org.junit.Test;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
public class ManifestReaderTest {
@Test
public void readOne() throws Exception {
Set<String> packageSet = readMf("META-INF/test/test-one.mf");
assertThat(packageSet).contains("foo");
}
@Test
public void readSome() throws Exception {
Set<String> packageSet = readMf("META-INF/test/test-some.mf");
assertThat(packageSet).contains("com.foo.domain", "com.bar.domain");
}
private Set<String> readMf(String path) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
return ManifestReader.readManifests(classLoader, path);
}
}
@@ -0,0 +1,81 @@
package com.avaje.ebeaninternal.server.deploy;
import org.junit.Test;
import javax.persistence.CascadeType;
import static org.junit.Assert.*;
public class BeanCascadeInfoTest {
@Test
public void setTypes_ALL() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setTypes(new CascadeType[]{CascadeType.ALL});
assertTrue(info.isSave());
assertTrue(info.isDelete());
assertTrue(info.isRefresh());
}
@Test
public void setTypes_PERSIST() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setTypes(new CascadeType[]{CascadeType.PERSIST});
assertTrue(info.isSave());
assertFalse(info.isDelete());
assertFalse(info.isRefresh());
}
@Test
public void setTypes_MERGE() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setTypes(new CascadeType[]{CascadeType.MERGE});
assertTrue(info.isSave());
assertFalse(info.isDelete());
assertFalse(info.isRefresh());
}
@Test
public void setTypes_REMOVE() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setTypes(new CascadeType[]{CascadeType.REMOVE});
assertFalse(info.isSave());
assertTrue(info.isDelete());
assertFalse(info.isRefresh());
}
@Test
public void setTypes_REFRESH() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setTypes(new CascadeType[]{CascadeType.REFRESH});
assertFalse(info.isSave());
assertFalse(info.isDelete());
assertTrue(info.isRefresh());
}
@Test
public void setDelete() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setDelete(true);
assertFalse(info.isSave());
assertTrue(info.isDelete());
assertFalse(info.isRefresh());
}
@Test
public void setSaveDelete() throws Exception {
BeanCascadeInfo info = new BeanCascadeInfo();
info.setSaveDelete(true, true);
assertTrue(info.isSave());
assertTrue(info.isDelete());
assertFalse(info.isRefresh());
}
}
@@ -0,0 +1,43 @@
package com.avaje.ebeaninternal.server.deploy;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.tests.model.basic.Contact;
import com.avaje.tests.model.basic.Customer;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.*;
public class BeanPropertyAssocManyTest extends BaseTestCase {
BeanDescriptor<Customer> customerDesc = spiEbeanServer().getBeanDescriptor(Customer.class);
BeanPropertyAssocMany<Customer> contacts() {
return (BeanPropertyAssocMany<Customer>)customerDesc.getBeanProperty("contacts");
}
@Test
public void createReferenceIfNull_when_notBeanCollection_expect_null() {
Customer customer = new Customer();
customer.setContacts(new ArrayList<Contact>());
BeanCollection<?> ref = contacts().createReferenceIfNull((EntityBean) customer);
assertNull(ref);
}
@Test
public void createReferenceIfNull_when_null_expect_ref() {
Customer customer = new Customer();
customer.setContacts(null);
BeanCollection<?> ref = contacts().createReferenceIfNull((EntityBean) customer);
assertNotNull(ref);
assertTrue(ref.isReference());
}
}
@@ -21,8 +21,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_defaults() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -32,8 +32,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
TableJoin tableJoin = tableJoin("id", "customer_id");
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -44,8 +44,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
TableJoin tableJoin1 = tableJoin("id", "customer_id");
TableJoin tableJoin2 = tableJoin("id", "other_customer_id");
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -56,8 +56,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
TableJoin tableJoin1 = tableJoin("id", "customer_id");
TableJoin tableJoin2 = tableJoin("id", "customer_id");
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(tableJoin1, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(tableJoin2, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -73,8 +73,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_diffQueryType() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.LIST, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.LIST, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -82,8 +82,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_firstRowsDifferent() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 10, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 10, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -91,8 +91,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_maxRowsDifferent() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -100,8 +100,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_firstRowsMaxRowsSame() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 20, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 20, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 20, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 10, 20, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -109,26 +109,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_diffDisableLazyLoading() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, true, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffRawWhereNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, "rawWhere", null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffRawWhere() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, "rawWhere", null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, "rawDiff", null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, true, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -137,8 +119,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
public void equals_when_diffOrderByNull() {
OrderBy<Object> o1 = new OrderBy<Object>("id");
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, o1, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -148,8 +130,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
OrderBy<Object> o1 = new OrderBy<Object>("id, name");
OrderBy<Object> o2 = new OrderBy<Object>("id, name");
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, o1, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, o2, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, o1, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, o2, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -157,164 +139,121 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
@Test
public void equals_when_diffQueryNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, "query", null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, "query", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffQuery() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, "query", null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, "queryDiff", null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, "query", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, "queryDiff", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_querySame() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, "query", null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, "query", null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, "query", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, "query", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffAddWhereNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, "addWhere", null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffAddWhere() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, "addWhere", null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, "diff", null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameAddWhere() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, "addWhere", null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, "addWhere", null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffAddHavingNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, "addHaving", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffAddHaving() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, "addHaving", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, "diff", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameAddHaving() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, "addHaving", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, "addHaving", false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffDistinct() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameDistinct() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, true, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffSqlDistinct() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameSqlDistinct() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, true, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffMapKeyNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffMapKey() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, "diff", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, "diff", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameMapKey() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, "mapKey", null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffIdNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_idBothGiven() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, 23, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, 42, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, 23, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@Test
public void equals_when_diffTemporalMode() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffForUpdate() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, true, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, true, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffRootAliasNull() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_diffRootAlias() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "diff", null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "diff", null, null);
assertDifferent(key1, key2);
}
@Test
public void equals_when_sameRootAlias() {
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, "rootAlias", null, null);
assertSame(key1, key2);
}
@@ -341,8 +280,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpressionList<Customer> list1 = list_id_eq_42();
SpiExpressionList<Customer> list2 = list_id_eq_43();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, list2, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, list2, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -353,8 +292,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpressionList<Customer> where1 = list_id_eq_42();
SpiExpressionList<Customer> where2 = list_id_eq_42_and_name_eq_rob();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, where1, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, where2, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, where1, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, where2, null, SpiQuery.TemporalMode.DRAFT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -363,8 +302,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpressionList<Customer> list1 = list_id_eq_42();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -373,8 +312,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpressionList<Customer> list1 = list_id_eq_42();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, list1, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -384,8 +323,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpression having1 = list_id_eq_42().copyForPlanKey();
SpiExpression having2 = list_id_eq_42_and_name_eq_rob().copyForPlanKey();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -395,8 +334,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpression having1 = list_id_eq_42().copyForPlanKey();
SpiExpression having2 = list_id_eq_42().copyForPlanKey();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having2, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertSame(key1, key2);
}
@@ -405,8 +344,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpression having1 = list_id_eq_42().copyForPlanKey();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -415,8 +354,8 @@ public class OrmQueryPlanKeyTest extends BaseExpressionTest {
SpiExpression having1 = list_id_eq_42().copyForPlanKey();
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, null, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key1 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, null, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
OrmQueryPlanKey key2 = new OrmQueryPlanKey(null, SpiQuery.Type.BEAN, null, 0, 0, false, null, null, false, false, null, null, null, null, having1, SpiQuery.TemporalMode.CURRENT, false, null, null, null);
assertDifferent(key1, key2);
}
@@ -1,97 +0,0 @@
package com.avaje.ebeaninternal.server.querydefn;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.expression.DefaultExpressionFactory;
import com.avaje.tests.model.basic.Order;
import org.junit.Assert;
import org.junit.Test;
import java.util.Set;
public class TestQueryLanguage extends BaseTestCase {
@Test
public void test() {
DefaultOrmQuery<Order> q = check("find order join customer (id, name)");
OrmQueryDetail detail = q.getDetail();
OrmQueryProperties chunk = detail.getChunk("customer", false);
Set<String> props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
q = check("find order join customer(id, name)");
detail = q.getDetail();
chunk = detail.getChunk("customer", false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
Assert.assertFalse(chunk.isCache());
Assert.assertFalse(chunk.isReadOnly());
q = check("find order join customer(+cache +readonly, id, name)");
detail = q.getDetail();
chunk = detail.getChunk("customer", false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
Assert.assertTrue(chunk.isCache());
Assert.assertTrue(chunk.isReadOnly());
q = check("find order join customer(+cache +readonly,id,name)");
detail = q.getDetail();
chunk = detail.getChunk("customer", false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
Assert.assertTrue(chunk.isCache());
Assert.assertTrue(chunk.isReadOnly());
q = check("find order(id,status) join customer(+cache +readonly,id,name)");
detail = q.getDetail();
chunk = detail.getChunk("customer", false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
Assert.assertTrue(chunk.isCache());
Assert.assertTrue(chunk.isReadOnly());
chunk = detail.getChunk(null, false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("status"));
Assert.assertFalse(props.contains("orderDate"));
q = check("find order(id,status) join customer(+cache +readonly,id,name) where id > :minId order by status");
detail = q.getDetail();
chunk = detail.getChunk("customer", false);
props = chunk.getIncluded();
Assert.assertTrue(props.contains("id"));
Assert.assertTrue(props.contains("name"));
Assert.assertTrue(chunk.isCache());
Assert.assertTrue(chunk.isReadOnly());
String orderBy = q.getOrderBy().toStringFormat();
Assert.assertEquals("status", orderBy);
}
private DefaultOrmQuery<Order> check(String q) {
SpiEbeanServer server = (SpiEbeanServer)Ebean.getServer(null);
OrmQueryDetailParser p = new OrmQueryDetailParser(q);
p.parse();
BeanDescriptor<Order> desc = server.getBeanDescriptor(Order.class);
DefaultOrmQuery<Order> qry = new DefaultOrmQuery<Order>(desc, server,
new DefaultExpressionFactory(false, false));
p.assign(qry);
return qry;
}
}
@@ -0,0 +1,77 @@
package com.avaje.ebeaninternal.server.transaction;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.cache.ServerCache;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.tests.model.basic.Contact;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.EBasic;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class JdbcTransactionTest {
@Test
public void isSkipCache() throws Exception {
Transaction transaction = Ebean.beginTransaction();
try {
// implicitly skip false due to query only at this point
assertThat(transaction.isSkipCache()).isFalse();
EBasic basic = new EBasic("b1");
Ebean.save(basic);
// implicitly skip true due to save
assertThat(transaction.isSkipCache()).isTrue();
Customer.find.byId(1);
// explicit control
transaction.setSkipCache(false);
assertThat(transaction.isSkipCache()).isFalse();
transaction.setSkipCache(true);
assertThat(transaction.isSkipCache()).isTrue();
} finally {
transaction.end();
}
}
@Test
public void skipCacheAfterSave() throws Exception {
ServerCacheManager cacheManager = Ebean.getDefaultServer().getServerCacheManager();
ServerCache customerBeanCache = cacheManager.getBeanCache(Customer.class);
ServerCache contactNatKeyCache = cacheManager.getNaturalKeyCache(Contact.class);
Transaction transaction = Ebean.beginTransaction();
try {
customerBeanCache.getStatistics(true);
contactNatKeyCache.getStatistics(true);
Customer.find.byId(19898989);
Ebean.find(Contact.class).where().eq("email","junk@foo.com").findUnique();
assertThat(customerBeanCache.getStatistics(true).getMissCount()).isEqualTo(1);
assertThat(contactNatKeyCache.getStatistics(true).getMissCount()).isEqualTo(1);
EBasic basic = new EBasic("b1");
Ebean.save(basic);
// these don't hit L2 cache due to the save of b1
Customer.find.byId(29898989);
Ebean.find(Contact.class).where().eq("email","junk2@foo.com").findUnique();
assertThat(customerBeanCache.getStatistics(true).getMissCount()).isEqualTo(0);
assertThat(contactNatKeyCache.getStatistics(true).getMissCount()).isEqualTo(0);
} finally {
transaction.end();
}
}
}
@@ -2,7 +2,7 @@ package com.avaje.ebeaninternal.server.type;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.PostgresPlatform;
import com.avaje.ebeaninternal.server.core.BootupClasses;
import com.avaje.ebeaninternal.server.core.bootup.BootupClasses;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -0,0 +1,21 @@
package com.avaje.ebeaninternal.server.type;
import org.junit.Test;
import org.mockito.Mockito;
import java.sql.SQLException;
public class ScalarTypeArrayListTest {
@Test
public void read_when_null() throws SQLException {
DataReader mock = Mockito.mock(DataReader.class);
Mockito.when(mock.getArray()).thenReturn(null);
ScalarTypeArrayList scalarType = ScalarTypeArrayList.typeFor(Long.class);
scalarType.read(mock);
}
}
@@ -1,26 +0,0 @@
package com.avaje.ebeaninternal.server.util;
import org.junit.Test;
import java.util.HashSet;
import static org.junit.Assert.*;
public class ClassPathSearchFilterTest {
@Test
public void testContainedIn() throws Exception {
HashSet<String> set = new HashSet<String>();
set.add("the-rock");
set.add("fooBar.jar");
ClassPathSearchFilter filter = new ClassPathSearchFilter();
assertTrue(filter.containedIn(set, "the-rock.jar"));
assertTrue(filter.containedIn(set, "the-rock-1.0.1.jar"));
assertTrue(filter.containedIn(set, "prefix-the-rock-1.0.1.jar"));
assertTrue(filter.containedIn(set, "fooBar.jar"));
assertFalse(filter.containedIn(set, "fooBar-1.3.jar"));
}
}
@@ -1,9 +0,0 @@
package com.avaje.ebeaninternal.server.util;
/**
* Exists only for including in the jar for the Class Path Search Tests.
*
* author: Richard Vowles - http://plus.google.com/RichardVowles
*/
public class SimpleJarBangClass {
}
@@ -1,9 +0,0 @@
package com.avaje.ebeaninternal.server.util;
/**
* Exists only for the purpose of putting in a jar for the ClassPathSearchTests.
*
* author: Richard Vowles - http://plus.google.com/RichardVowles
*/
public class SimpleJarClass {
}
@@ -2,6 +2,7 @@ package com.avaje.tests.basic;
import java.util.List;
import com.avaje.ebean.Query;
import com.avaje.ebean.RawSql;
import com.avaje.ebean.RawSqlBuilder;
import org.junit.Assert;
@@ -12,6 +13,8 @@ import com.avaje.ebean.Ebean;
import com.avaje.tests.model.basic.OrderAggregate;
import com.avaje.tests.model.basic.ResetBasicData;
import static org.assertj.core.api.Assertions.assertThat;
public class TestOrderTotalAmountReportBean extends BaseTestCase {
@Test
@@ -46,4 +49,29 @@ public class TestOrderTotalAmountReportBean extends BaseTestCase {
}
@Test
public void test_when_explicitMapping() {
ResetBasicData.reset();
String sql =
"select order_id, count(*) as total_items, sum(order_qty*unit_price) as total_amount \n" +
"from o_order_detail \n" +
"group by order_id";
RawSql rawSql = RawSqlBuilder.parse(sql)
.columnMapping("order_id", "order.id")
.columnMapping("total_items", "totalItems")
.columnMapping("total_amount", "totalAmount")
.create();
Query<OrderAggregate> query = Ebean.find(OrderAggregate.class)
.setRawSql(rawSql);
query.findList();
assertThat(query.getGeneratedSql()).contains("count(*) as total_items, sum(order_qty*unit_price) as total_amount");
}
}
@@ -1,25 +1,25 @@
package com.avaje.tests.el;
import java.util.List;
import junit.framework.TestCase;
import org.junit.Assert;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import org.junit.Test;
public class TestUnderscoreParam extends TestCase {
import static org.assertj.core.api.Assertions.assertThat;
public class TestUnderscoreParam {
@Test
public void test() {
Query<Customer> query = Ebean.find(Customer.class)
.where().raw("name like ?", "Rob%")
.query();
query.findList();
assertThat(query.getGeneratedSql()).contains("where t0.name like ?");
}
public void test() {
List<Customer> list = Ebean.find(Customer.class)
.where("name like :cust_name")
.setParameter("cust_name", "Rob%")
.findList();
Assert.assertNotNull(list);
}
}
@@ -1,5 +1,10 @@
package com.avaje.tests.idkeys;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.tests.idkeys.db.AuditLog;
import com.avaje.tests.lib.EbeanTestCase;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
@@ -9,179 +14,161 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.bean.EntityBean;
import com.avaje.tests.idkeys.db.AuditLog;
import com.avaje.tests.lib.EbeanTestCase;
/**
* Test various aspects of the PropertyChangeSupport
*/
public class TestPropertyChangeSupport extends EbeanTestCase implements PropertyChangeListener
{
private int nuofEvents = 0;
private List<PropertyChangeEvent> pces = new ArrayList<PropertyChangeEvent>();
private PropertyChangeEvent lastPce;
public class TestPropertyChangeSupport extends EbeanTestCase implements PropertyChangeListener {
private int nuofEvents = 0;
private List<PropertyChangeEvent> pces = new ArrayList<PropertyChangeEvent>();
private PropertyChangeEvent lastPce;
public void propertyChange(PropertyChangeEvent evt)
{
nuofEvents++;
lastPce = evt;
pces.add(evt);
}
public void propertyChange(PropertyChangeEvent evt) {
nuofEvents++;
lastPce = evt;
pces.add(evt);
}
/**
* Test the core property change functionality
*/
public void testPropertyChange() throws SQLException
{
resetEvent();
/**
* Test the core property change functionality
*/
public void testPropertyChange() throws SQLException {
resetEvent();
AuditLog al = new AuditLog();
AuditLog al = new AuditLog();
assertTrue("is EntityBean check", al instanceof EntityBean);
assertTrue("is EntityBean check", al instanceof EntityBean);
addListener(al, this);
// test if we get property notification about simple property changes
al.setDescription("ABC");
addListener(al, this);
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertEquals("ABC", lastPce.getNewValue());
// test if we get property notification about simple property changes
al.setDescription("ABC");
al.setDescription("DEF");
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertEquals("ABC", lastPce.getNewValue());
assertNotNull(lastPce);
assertEquals(2, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals("ABC", lastPce.getOldValue());
assertEquals("DEF", lastPce.getNewValue());
al.setDescription("DEF");
resetEvent();
assertNotNull(lastPce);
assertEquals(2, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals("ABC", lastPce.getOldValue());
assertEquals("DEF", lastPce.getNewValue());
// test if we get change notification if EBean assigns an id to the bean
getServer().save(al);
resetEvent();
assertNotNull(lastPce);
assertEquals("id", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertNotNull(lastPce.getNewValue());
// test if we get change notification if EBean assigns an id to the bean
getServer().save(al);
String prevLogDesc = al.getDescription();
resetEvent();
// simulate external change and test if we get change notification when we refresh the entity
Transaction tx = getServer().beginTransaction();
PreparedStatement pstm = tx.getConnection().prepareStatement("update audit_log set description = ? where id = ?");
pstm.setString(1, "GHI");
pstm.setLong(2, al.getId());
int updated = pstm.executeUpdate();
pstm.close();
assertEquals(1, updated);
tx.commit();
assertNull(lastPce);
assertEquals(0, nuofEvents);
getServer().refresh(al);
assertEquals("GHI", al.getDescription());
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals(prevLogDesc, lastPce.getOldValue());
assertNotNull("GHI", lastPce.getNewValue());
// check if we fire with the real new value which might be a modified version of what we passed to the set method
resetEvent();
al.setModifiedDescription("MODIFIED_VALUE");
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("modifiedDescription", lastPce.getPropertyName());
assertEquals(null, lastPce.getOldValue());
assertNotNull("_MODIFIED_VALUE_", lastPce.getNewValue());
}
/**
* check if
* <ul>
* <li>updating a lazy loaded property fires two events</li>
* </ul>
*/
public void testPartialLoad() throws SQLException
{
AuditLog log = new AuditLog();
log.setDescription("log");
getServer().save(log);
assertNotNull(log.getId());
resetEvent();
List<AuditLog> logs = getServer().find(AuditLog.class)
.where().eq("id", log.getId())
.select("id")
.findList();
assertNotNull(logs);
assertEquals(1, logs.size());
AuditLog logLazy = logs.get(0);
addListener(logLazy, this);
// this will lazy load and update the property
logLazy.setDescription("updated log");
// which should result in one PCE events
assertEquals(1, pces.size());
// test for the acutal update of the value
PropertyChangeEvent propertyChangeEvent = pces.get(0);
assertEquals("description", propertyChangeEvent.getPropertyName());
assertEquals("log", propertyChangeEvent.getOldValue());
assertEquals("updated log", propertyChangeEvent.getNewValue());
}
private void resetEvent()
{
lastPce = null;
nuofEvents = 0;
pces.clear();
}
private static void addListener(AuditLog al, PropertyChangeListener listener)
{
try
{
//Ebean.getBeanState(al).addPropertyChangeListener(listener);
Method apcs = al.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
apcs.invoke(al, listener);
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
assertNotNull(lastPce);
assertEquals("id", lastPce.getPropertyName());
assertNull(lastPce.getOldValue());
assertNotNull(lastPce.getNewValue());
String prevLogDesc = al.getDescription();
resetEvent();
// simulate external change and test if we get change notification when we refresh the entity
Transaction tx = getServer().beginTransaction();
PreparedStatement pstm = tx.getConnection().prepareStatement("update audit_log set description = ? where id = ?");
pstm.setString(1, "GHI");
pstm.setLong(2, al.getId());
int updated = pstm.executeUpdate();
pstm.close();
assertEquals(1, updated);
tx.commit();
assertNull(lastPce);
assertEquals(0, nuofEvents);
getServer().refresh(al);
assertEquals("GHI", al.getDescription());
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("description", lastPce.getPropertyName());
assertEquals(prevLogDesc, lastPce.getOldValue());
assertNotNull("GHI", lastPce.getNewValue());
// check if we fire with the real new value which might be a modified version of what we passed to the set method
resetEvent();
al.setModifiedDescription("MODIFIED_VALUE");
assertNotNull(lastPce);
assertEquals(1, nuofEvents);
assertEquals("modifiedDescription", lastPce.getPropertyName());
assertEquals(null, lastPce.getOldValue());
assertNotNull("_MODIFIED_VALUE_", lastPce.getNewValue());
}
/**
* check if
* <ul>
* <li>updating a lazy loaded property fires two events</li>
* </ul>
*/
public void testPartialLoad() throws SQLException {
AuditLog log = new AuditLog();
log.setDescription("log");
getServer().save(log);
assertNotNull(log.getId());
resetEvent();
List<AuditLog> logs = getServer().find(AuditLog.class)
.where().eq("id", log.getId())
.select("id")
.findList();
assertNotNull(logs);
assertEquals(1, logs.size());
AuditLog logLazy = logs.get(0);
addListener(logLazy, this);
// this will lazy load and update the property
logLazy.setDescription("updated log");
// which should result in one PCE events
assertEquals(1, pces.size());
// test for the acutal update of the value
PropertyChangeEvent propertyChangeEvent = pces.get(0);
assertEquals("description", propertyChangeEvent.getPropertyName());
assertEquals("log", propertyChangeEvent.getOldValue());
assertEquals("updated log", propertyChangeEvent.getNewValue());
}
private void resetEvent() {
lastPce = null;
nuofEvents = 0;
pces.clear();
}
private static void addListener(AuditLog al, PropertyChangeListener listener) {
try {
//Ebean.getBeanState(al).addPropertyChangeListener(listener);
Method apcs = al.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class);
apcs.invoke(al, listener);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
@@ -35,6 +35,14 @@ public class EBasic {
Timestamp someDate;
public EBasic() {
}
public EBasic(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
@@ -12,9 +12,9 @@ import java.util.concurrent.atomic.AtomicLong;
public class MyEBasicConfigStartup implements ServerConfigStartup {
public static AtomicLong insertCount = new AtomicLong();
public static AtomicLong updateCount = new AtomicLong();
public static AtomicLong deleteCount = new AtomicLong();
public static final AtomicLong insertCount = new AtomicLong();
public static final AtomicLong updateCount = new AtomicLong();
public static final AtomicLong deleteCount = new AtomicLong();
public static void resetCounters() {
insertCount.set(0);
@@ -10,7 +10,7 @@ import java.util.List;
@Entity
public class InfoCompany extends Model {
public static Finder<Long,InfoCompany> find = new Finder<Long,InfoCompany>(InfoCompany.class);
public static final Finder<Long,InfoCompany> find = new Finder<Long,InfoCompany>(InfoCompany.class);
@Id
Long id;
@@ -11,7 +11,7 @@ import javax.persistence.Version;
@Entity
public class InfoCustomer extends Model {
public static Finder<Long,InfoCustomer> find = new Finder<Long,InfoCustomer>(InfoCustomer.class);
public static final Finder<Long,InfoCustomer> find = new Finder<Long,InfoCustomer>(InfoCustomer.class);
@Id
Long id;
@@ -1,13 +1,11 @@
package com.avaje.tests.query;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
@@ -20,16 +18,17 @@ public class TestExprNestedDisjunction extends BaseTestCase {
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class).where().disjunction()
.conjunction().startsWith("name", "r").eq("anniversary", onAfter).endJunction()
.conjunction().eq("status", Customer.Status.ACTIVE).gt("id", 0).endJunction().orderBy()
.asc("name");
Query<Customer> q = Ebean.find(Customer.class).where()
.disjunction()
.conjunction().startsWith("name", "r").eq("anniversary", onAfter).endJunction()
.conjunction().eq("status", Customer.Status.ACTIVE).gt("id", 0).endJunction()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
Assert.assertTrue(s.contains("(t0.name like ? "));
Assert.assertTrue(s.contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )"));
assertThat(s).contains("(t0.name like ? ");
assertThat(s).contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )");
}
@@ -44,16 +43,16 @@ public class TestExprNestedDisjunction extends BaseTestCase {
.where()
.or()
.and()
.startsWith("name", "r").eq("anniversary", onAfter).endJunction()
.startsWith("name", "r").eq("anniversary", onAfter).endAnd()
.and()
.eq("status", Customer.Status.ACTIVE).gt("id", 0).endJunction()
.eq("status", Customer.Status.ACTIVE).gt("id", 0).endAnd()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
Assert.assertTrue(s.contains("(t0.name like ? "));
Assert.assertTrue(s.contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )"));
assertThat(s).contains("(t0.name like ? ");
assertThat(s).contains(" and t0.anniversary = ? ) or (t0.status = ? and t0.id > ? )");
}
@Test
@@ -68,7 +67,7 @@ public class TestExprNestedDisjunction extends BaseTestCase {
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
.endJunction()
.endNot()
.orderBy().asc("name");
q.findList();
@@ -91,7 +90,30 @@ public class TestExprNestedDisjunction extends BaseTestCase {
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
//.endNot()
.orderBy().asc("name");
q.findList();
String s = q.getGeneratedSql();
assertThat(s).contains("where (t0.status = ? or not (t0.id > ? and t0.anniversary = ? ) )");
}
@Test
public void test_not_nested_with_endNot() {
ResetBasicData.reset();
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
Query<Customer> q = Ebean.find(Customer.class)
.where()
.or()
.eq("status", Customer.Status.ACTIVE)
.not()
.gt("id", 1)
.eq("anniversary", onAfter)
.endNot()
.endOr()
.orderBy().asc("name");
q.findList();
@@ -1,16 +1,16 @@
package com.avaje.tests.query;
import java.util.List;
import com.avaje.ebean.RawSql;
import com.avaje.ebean.RawSqlBuilder;
import org.junit.Assert;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebean.RawSql;
import com.avaje.ebean.RawSqlBuilder;
import com.avaje.tests.model.basic.MyAdHoc;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
public class TestMyAdHocSqlSelect extends BaseTestCase {
@@ -20,12 +20,44 @@ public class TestMyAdHocSqlSelect extends BaseTestCase {
ResetBasicData.reset();
String sql = "select order_id, count(*) as detailCount from o_order_detail group by order_id";
RawSql rawSql = RawSqlBuilder.parse(sql).columnMapping("order_id", "order.id").create();
List<MyAdHoc> list = Ebean.find(MyAdHoc.class).setRawSql(rawSql).where().gt("order_id", 0).having()
.gt("detailCount", 0).findList();
RawSql rawSql = RawSqlBuilder
.parse(sql)
.columnMapping("order_id", "order.id")
.create();
Assert.assertNotNull(list);
Query<MyAdHoc> query = Ebean.find(MyAdHoc.class)
.setRawSql(rawSql)
.where().gt("order_id", 0)
.having().gt("detailCount", 0)
.query();
assertNotNull(query.findList());
assertThat(query.getGeneratedSql()).contains(" group by order_id having count(*) > ?");
}
@Test
public void test_when_explicitColumnMapping() {
ResetBasicData.reset();
String sql = "select order_id, count(*) as detail_count from o_order_detail group by order_id";
RawSql rawSql = RawSqlBuilder
.parse(sql)
.columnMapping("order_id", "order.id")
.columnMapping("detail_count", "detailCount")
.create();
Query<MyAdHoc> query = Ebean.find(MyAdHoc.class)
.setRawSql(rawSql)
.where().gt("order_id", 0)
.having().gt("detailCount", 0)
.query();
assertNotNull(query.findList());
assertThat(query.getGeneratedSql()).contains(" group by order_id having count(*) > ?");
}
}
@@ -1,5 +1,7 @@
package com.avaje.tests.query;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Order;
import org.junit.Test;
import com.avaje.ebean.BaseTestCase;
@@ -8,8 +10,29 @@ import com.avaje.ebean.Expr;
import com.avaje.tests.model.basic.OrderDetail;
import com.avaje.tests.model.basic.ResetBasicData;
import java.sql.Timestamp;
import static org.assertj.core.api.Assertions.assertThat;
public class TestWhereRawClause extends BaseTestCase {
@Test
public void testRawClauseWithJunction() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class)
.where()
.raw("(status = ? or (orderDate < ? and shipDate is null) or customer.name like ?)",
Order.Status.APPROVED, new Timestamp(System.currentTimeMillis()), "Rob")
.query();
query.findList();
assertThat(query.getGeneratedSql()).contains(" where (t0.status = ? or (t0.order_date < ? and t0.ship_date is null) or t1.name like ?)");
}
@Test
public void testRawClause() {
@@ -0,0 +1 @@
packages: foo
@@ -0,0 +1 @@
packages: com.foo.domain, com.bar.domain
+5
View File
@@ -19,4 +19,9 @@
-- oracle only script
</ddl-script>
<ddl-script name="pg indexes" platforms="postgres">
-- postgres specific indexes
create index ix_ebasic_jmjb_gin2 on ebasic_json_map_json_b using gin(content jsonb_path_ops);
</ddl-script>
</extra-ddl>
+3 -1
View File
@@ -2,4 +2,6 @@ datasource.h2.username=sa
ebean.jodaLocalTimeMode=normal
#ebean.jodaLocalTimeMode=utc
#ebean.jodaLocalTimeMode=utc
#ebean.skipCacheAfterWrite=false