Compare commits

..
Author SHA1 Message Date
rob bygrave d5d9a897ae [maven-release-plugin] prepare release ebean-11.40.1 2019-06-29 00:44:05 +12:00
rob bygrave ddf200ffdd #1738 - Refactor toArray() plus various 2019-06-29 00:40:16 +12:00
rob bygrave 7fa5e2aa8c #1738 - Refactor add final, Object.equals, Integer.compare 2019-06-29 00:23:12 +12:00
rob bygrave 8bfae9deef #1738 - Refactor simplify switch and various 2019-06-28 23:48:03 +12:00
rob bygrave e6c9f151c1 #1738 - Refactor tidy suppressWarnings and access 2019-06-28 23:20:57 +12:00
rob bygrave 30a0935300 #1738 - Refactor tidy suppressWarnings 2019-06-28 23:04:20 +12:00
rob bygrave b4182d4519 #1738 - Refactor SqlTreeNodeBean tidy 2019-06-28 22:40:14 +12:00
rob bygrave 93cc0399f1 #1738 - Refactor SqlTreeNodeBean load method 2019-06-28 22:35:36 +12:00
rob bygrave 5404dab5a3 Bump to 11.40.1-SNAPSHOT 2019-06-28 21:35:02 +12:00
rob bygrave d70da1d805 #1738 - Refactor tidy internals - refactor move server.lib.Str 2019-06-28 21:32:15 +12:00
rob bygrave 2225d5b7e8 #1738 - Refactor tidy internals - refactor move DtoQueryRequest 2019-06-28 21:30:15 +12:00
rob bygrave 270369bd65 #1738 - Refactor tidy internals - DLoadContext 2019-06-28 21:20:42 +12:00
rob bygrave a932d61a94 #1737 - PersistenceException while using aggregate query on related entity
This part includes support for joins off an aggregation formula
on a ManyToOne.

e.g. We use min(customer) ... to 'query join' to customer
in the query below.

    List<Contact> contacts = Ebean.find(Contact.class)
      .select("lastName, min(customer)")
      .fetchQuery("customer", "name, status")
      .findList();
2019-06-28 21:03:14 +12:00
rob bygrave 24b08663af #1737 - PersistenceException while using aggregate query on related entity
Fix excluding the ability to additionally join (off the min(manyToOne))
2019-06-28 20:16:05 +12:00
rob bygrave bb6c9c84ba #1736 - Bump to ebean-agent 11.40.1 (with synthetic modifier on generated code) 2019-06-28 10:55:14 +12:00
rob bygrave a1e185b0f6 Refactor tidy internals - BatchedPstmtHolder, always true condition (no effective change)
Remove condition check on firstError == null ... as it is always true
2019-06-24 13:41:21 +12:00
Rob BygraveandGitHub e2a467ca5a Create FUNDING.yml 2019-06-19 23:49:00 +12:00
rob bygrave 4b28933298 [maven-release-plugin] prepare for next development iteration 2019-06-14 16:45:16 +12:00
rob bygrave 6077acf134 [maven-release-plugin] prepare release ebean-11.39.3 2019-06-14 16:45:05 +12:00
rob bygrave 8a4ffd21ab #1722 - Fix for - L2 cache throw exception when query with custom ManyToMany relation model 2019-06-14 16:38:58 +12:00
rob bygrave d1314124af #1722 - Failing test for - L2 cache throw exception when query with custom ManyToMany relation model 2019-06-14 16:38:43 +12:00
rob bygrave 36f018b6aa [maven-release-plugin] prepare for next development iteration 2019-06-13 23:38:28 +12:00
rob bygrave 87ccb6e333 [maven-release-plugin] prepare release ebean-11.39.2 2019-06-13 23:38:18 +12:00
rob bygrave 3432c365f6 Bump ebean-migration to 11.16.2 with fix for migration sql that ...
That includes semi-colon and new line in literal content
2019-06-13 00:14:20 +12:00
rob bygrave b7d5aa344f Fix test only - add missing assert on NoopExpressionTest 2019-06-13 00:11:34 +12:00
rob bygrave 7e768623e4 #1730 - Fix for wrong JDBC batch sorting / ordering
This is a bit of a refactor that simplifies the ordering of
batch execution (BatchedBeanHolder ordering). In short we
batch by bean type and depth (rather than just type).

This means that there are some cases we are not optimal
(where we could batch by bean type in different depths)
but that is expected to be rare and problematic for
hierarchies of the same type.
2019-06-12 23:41:48 +12:00
rob bygrave 73ab2ee1fe Merge branch 'FOCONIS-bug/wrong_batch_sorting' 2019-06-12 21:17:15 +12:00
rob bygrave 122fed448c Merge branch 'bug/wrong_batch_sorting' of https://github.com/FOCONIS/ebean into FOCONIS-bug/wrong_batch_sorting 2019-06-12 21:16:50 +12:00
rob bygrave 6e52bee91f #1723 - Fix for TestUpdateCircularSave.testCircularCascade() 2019-06-10 23:31:47 +12:00
rob bygrave cc26afad13 Merge branch 'tobias--circular_saves_bugs' 2019-06-10 21:04:17 +12:00
rob bygrave bf20449fb5 Merge branch 'circular_saves_bugs' of https://github.com/tobias-/ebean into tobias--circular_saves_bugs 2019-06-10 21:03:55 +12:00
Rob BygraveandGitHub 6af5fae8e9 #1727 - Refactor internals to use Instant for json parse on date time types (#1728) 2019-06-10 16:16:04 +12:00
rob bygrave e26a38ecaa #1727 - No effective change, simplify DefaultServer.createEntityBean() 2019-06-10 16:14:12 +12:00
rob bygrave 1cdf68f1c0 #1727 - No effective change, tests with static imports 2019-06-10 16:13:19 +12:00
jonasPoehlerandRob Bygrave 2923dd1d96 Bugfix/create entity bean unload (#1729)
* #1726 Add a testcase to reveal wrong behaviour of createEntityBean

* #1726 FIX: createEntityBean must not unload properties for "new" beans

(cherry picked from commit 270721bdb54373a83ef00b19a3c35da50f2a2bf5)
2019-06-10 16:09:12 +12:00
Jonas Pöhler (JPo) 9067508e1d Add testcase for wrong batch sorting 2019-06-07 13:42:31 +02:00
rob bygrave 385cc76e34 #1724 - Fix, UtilDateTimeParser - date time parsing with nanos precision 2019-06-04 22:20:28 +12:00
SnōwballandRob Bygrave c14cb4b85e Add (failing) java 11 to travis - date time parsing with nanos precision (#1724)
* Add (failing) java 11 to travis

* Extra test-case for date parser
2019-06-04 21:56:25 +12:00
Snōwball 52644647e4 Add another test case for circular dependencies 2019-05-27 11:14:48 +02:00
Snōwball 3bf9dd6743 Testcase for ebean with circular dependences
1. While the javax.persistance api discourages the use of bidirectional
   cascades, it does not prohibit them. They're very useful and natural
   if you think of the database as a graph instead of a tree.
   test case 1 (testCircularCascade) tests this.
2. Second test case fetches the child, but saves the parent. If used like
   that, the child will not have it's changes saved.
2019-05-23 16:38:55 +02:00
rob bygrave aececa2199 [maven-release-plugin] prepare for next development iteration 2019-05-22 22:23:33 +12:00
rob bygrave b4e22a4ca7 [maven-release-plugin] prepare release ebean-11.39.1 2019-05-22 22:23:19 +12:00
rob bygrave 9b8b4414c4 Bump agent and ebean-migration 2019-05-22 22:21:35 +12:00
rob bygrave b8fd2c7a02 Bump to 11.39.1-SNAPSHOT 2019-05-22 21:46:49 +12:00
rob bygrave a94f5d74ca No effective change - add test for select formula with positioned parameters 2019-05-21 16:59:39 +12:00
rob bygrave 3829613c37 #1717 #1721 - Fix for table touch with query cache clear 2019-05-21 09:17:07 +12:00
Roland PramlandRob Bygrave 0762eaf0ab changed test to detect issue #1717 (#1721) 2019-05-21 09:12:43 +12:00
Rob BygraveandGitHub 7fbdab6220 Refactor TableModState to use nanoTime refactor (#1720)
* #1719 - Refactor TableModState to use nanoTime

* Tests only - reduce logging
2019-05-21 00:42:17 +12:00
Roland PramlandRob Bygrave cf4d45befb refactor: unwrap invocationTargetException (#1718) 2019-05-21 00:37:03 +12:00
rob bygrave dcd81a857d #1717 - Add tests for Query Cache invalidation
Revert the prior change that added the extra calls to
changeSet.addInvalidate(desc); as they are not needed.
2019-05-20 21:14:47 +12:00
Roland PramlandRob Bygrave 0cac723eac Query Cache will not always be invalidated (#1717)
* provide failing test, that shows missing cache invalidation

* FIX: proper cache invalidation when dependent table will be modified
2019-05-20 20:25:18 +12:00
Rob BygraveandGitHub c6ba4d8155 Refactor DefaultTransactionThreadLocal, convert ThreadLocal to field (from map) (#1716)
* Refactor DefaultTransactionThreadLocal, convert ThreadLocal to field (from map)

* Add test for multiple database thread locals
2019-05-18 15:16:17 +12:00
Rob BygraveandGitHub 201958f38c Refactor tidy on DefaultTransactionThreadLocal (#1715)
- remove unused methods
- use clear() rather than set(null)
2019-05-18 12:32:17 +12:00
rob bygrave 9326c9c79e Adjustment on #1711, fix clearing of inactive transactions from thread local
Handles implicit transactions for update and delete queries plus delete
by id
2019-05-18 12:09:50 +12:00
rob bygrave 1042fdb280 Merge branch 'feature/1711-v2' 2019-05-18 11:43:51 +12:00
Roland PramlandRob Bygrave 197056dbc5 Refactor: Ebean uses the MigrationVersion from the ebean-migration artifact (#1713) 2019-05-18 11:32:17 +12:00
Roland PramlandRob Bygrave 895b5ee4ff The BaseTestCase ensures, that the threadLocal is cleared after each test. (#1712)
* The BaseTestCase ensures, that the threadLocal is cleared after each test.

* Change JdbcTransaction.toString to distingush between active and inactive transaction
2019-05-18 11:28:46 +12:00
rob bygrave c839fe6520 Adjustment on #1711, more explicit clearing of inactive transactions from thread local 2019-05-18 11:21:11 +12:00
Roland PramlandRob Bygrave 2678f85506 Fix memory leak in threadLocal on implicit transactions (#1711)
* refactor TestExecutionComplete

* Add more tests to discover missing threadScope cleanups

* FIX: clear threadScope on implicit created Jdbc transactions

* FIX: clear threadScope on completed JTA transactions

* Revert "FIX: clear threadScope on completed JTA transactions"

This reverts commit f844405542.
2019-05-18 10:00:34 +12:00
Rob BygraveandGitHub 2b1b4af7a2 Merge pull request #1710 from FOCONIS/sqlserver-platform-test
New test for SqlServerPlatform
2019-05-18 09:48:59 +12:00
Rob BygraveandGitHub 4218b8a2e8 Merge pull request #1708 from FOCONIS/refactor-tests-idtype
Refactor Tests: Check idType instead of assuming idType for a platform
2019-05-18 09:46:40 +12:00
Roland Praml fe7d73a4a4 New test for SqlServerPlatform 2019-05-17 18:07:24 +02:00
Roland Praml 81e86b07e3 Refactor Tests: Check idType instead of assuming idType for a platform 2019-05-17 16:38:25 +02:00
rob bygrave 910c04e373 Add sponsorship from timerbee.de 2019-05-17 21:08:44 +12:00
Rob BygraveandGitHub 205f1f5e89 Merge pull request #1704 from ebean-orm/feature/1701-v2
#1701 (v2) - Replace TransactionMap with HashMap in DefaultTransactionThreadLocal
2019-05-17 21:04:54 +12:00
rob bygrave a1a6d2b725 Fix test TestExecuteComplete 2019-05-17 14:56:35 +12:00
rob bygrave 30da589ea0 #1701 (v2) - Replace TransactionMap with HashMap in DefaultTransactionThreadLocal
- Use ThreadLocal.withInitial to always have a map.
- Remove the calls to local.remove(); when the map is empty (with the expectation that the thread local will GC with an empty map.
2019-05-17 12:01:28 +12:00
rob bygrave c66e9547e1 #1705 - SpiTransactionProxy depth(int diff) ... does not pass on depth to underlying transaction 2019-05-16 22:44:09 +12:00
rob bygrave 73990e3fb7 #1701 (v2) - Replace TransactionMap with HashMap in DefaultTransactionThreadLocal 2019-05-16 22:26:11 +12:00
rob bygrave f7920de3c2 #1698 No effective change - reformat 2019-05-16 20:27:16 +12:00
rob bygrave 3dd5069f5a #1698 FIX for IAE "key can't be empty" in System.getProperty()
That is, assertEquals("${}", PropertyEval.eval("${}"));
... for when we load properties that include the "${}" placeholder
2019-05-16 20:26:45 +12:00
rob bygrave 1d363776ec No effective change - refactor rename in test for StartMySql 2019-05-16 20:08:06 +12:00
rob bygrave c512eb564d #1702 - Format only change 2019-05-16 20:07:43 +12:00
Rob BygraveandGitHub 7f332e91ff Merge pull request #1702 from FOCONIS/fix-mig-default-value
Fix: Migration when dbdefault is involved
2019-05-16 20:00:34 +12:00
Rob BygraveandGitHub 8e9d644bc6 Merge pull request #1697 from ebean-orm/feature/1695-binary
#1695 - For MySql like remove the binary keyword + Add caseSensitiveCollation configuration option
2019-05-16 19:46:38 +12:00
rob bygrave fa5ce9cbba #1695 Add StartMyServer - docker mysql with collation options
- Adjust TestWhereLikeWithSlash ignoring slash escaping assert for mysql (due to dependency on no_backslash_escapes setting)
2019-05-16 16:55:05 +12:00
rob bygrave b7905daeb5 #1695 Fix case sensitive builtin sql server proc
- Update main.StartSqlServer to use updated ebean-test-docker with collation support
2019-05-16 15:36:22 +12:00
rob bygrave 9da7c9468e #1695 Add caseSensitiveCollation configuration option
This is really only to use with testing via
platform.isCaseSensitiveCollation() to determine
which asserts/tests apply (based on collation).
2019-05-15 16:19:12 +12:00
Roland Praml 9eee224e03 migration scripts 2019-05-14 20:05:24 +02:00
Roland Praml 906d5f04ad FIX: Migration when default value was changed 2019-05-14 20:02:55 +02:00
rob bygrave 654c3f7f67 #1695 - For SQL Server like remove the binary collation (Latin1_General_BIN) 2019-05-12 15:22:08 +12:00
rob bygrave c61e6b04a2 Update sql server testing 2019-05-12 11:41:24 +12:00
Rob BygraveandGitHub f893653090 Merge pull request #1699 from FOCONIS/fix-equals-modify-aware
Fix: equals() and hashCode() in ModifyAwareXXX
2019-05-11 13:43:40 +12:00
Roland Praml 579c1efcf6 Add tests and fixes in hashCode 2019-05-08 17:00:08 +02:00
Roland Praml 662f9cdeb3 fixed equals() method in ModifyAware collections. 2019-05-08 16:45:02 +02:00
rob bygrave b4782425f8 #1695 - For MySql like remove the binary keyword 2019-05-08 23:38:25 +12:00
rob bygrave 2648423930 #1696 - Refactor - trim unnecessary whitespace around IN clause bind parameters 2019-05-08 23:22:13 +12:00
rob bygrave b62cea5073 No effective change - add findNative tests with named params in select 2019-05-08 23:12:10 +12:00
rob bygrave c10ad11b8b No effective change - add example use of PathProperties 2019-05-08 22:50:37 +12:00
rob bygrave 4aa8a0dc63 #1694 - findList() with firstRows/maxRows adds "order by id" (even with orderById(false)) 2019-05-03 14:33:42 +12:00
rob bygrave e4569f9362 #1693 - Update ebean-migration 11.15.1 2019-05-03 12:45:03 +12:00
rob bygrave ed83bababc [maven-release-plugin] prepare for next development iteration 2019-05-01 00:39:58 +12:00
308 changed files with 3718 additions and 1788 deletions
+3
View File
@@ -0,0 +1,3 @@
# These are supported funding model platforms
custom: https://ebean.io/sponsors
+1
View File
@@ -3,6 +3,7 @@ sudo: required
language: java
jdk:
- oraclejdk8
- openjdk11
git:
depth: 3
+5
View File
@@ -20,6 +20,11 @@
<img width="222px" src="https://ebean.io/images/logo-med-principal.png">
</a>
</td>
<td align="center" valign="middle">
<a href="https://timerbe.de" target="_blank">
<img width="222px" src="https://ebean.io/images/logo-timerbee.png">
</a>
</td>
</tr>
</tbody>
</table>
+9 -9
View File
@@ -9,7 +9,7 @@
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>11.38.1</version>
<version>11.40.1</version>
<packaging>jar</packaging>
<name>ebean</name>
@@ -22,7 +22,7 @@
<scm>
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
<tag>ebean-11.38.1</tag>
<tag>ebean-11.40.1</tag>
</scm>
<profiles>
@@ -141,7 +141,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-migration</artifactId>
<version>11.14.1</version>
<version>11.16.2</version>
</dependency>
<dependency>
@@ -227,9 +227,9 @@
<!--</dependency>-->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-docker-run</artifactId>
<version>1.5.1</version>
<groupId>io.ebean.test</groupId>
<artifactId>ebean-test-docker</artifactId>
<version>2.5.1</version>
<scope>test</scope>
</dependency>
@@ -250,7 +250,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-agent</artifactId>
<version>11.37.1</version>
<version>11.40.1</version>
<scope>test</scope>
</dependency>
@@ -280,7 +280,7 @@
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.2.0.jre8</version>
<version>7.2.2.jre8</version>
<scope>test</scope>
</dependency>
@@ -330,7 +330,7 @@
<plugin>
<groupId>io.ebean</groupId>
<artifactId>ebean-maven-plugin</artifactId>
<version>11.37.1</version>
<version>11.40.1</version>
<executions>
<execution>
<id>test</id>
+2 -2
View File
@@ -69,8 +69,8 @@ public enum CacheMode {
*/
GET(true, false);
private boolean get;
private boolean put;
private final boolean get;
private final boolean put;
CacheMode(boolean get, boolean put) {
this.get = get;
@@ -1,6 +1,7 @@
package io.ebean.bean;
import java.io.Serializable;
import java.util.Objects;
/**
* Identifies a unique node of an object graph.
@@ -85,8 +86,7 @@ public final class ObjectGraphNode implements Serializable {
}
ObjectGraphNode e = (ObjectGraphNode) obj;
//noinspection StringEquality
return ((e.path == path) || (e.path != null && e.path.equals(path)))
return (Objects.equals(e.path, path))
&& e.originQueryPoint.equals(originQueryPoint);
}
}
+2 -9
View File
@@ -10,22 +10,15 @@ import java.util.Set;
*/
public class ServerCacheNotification {
private final long modifyTimestamp;
private final Set<String> dependentTables;
public ServerCacheNotification(long modifyTimestamp, Set<String> dependentTables) {
this.modifyTimestamp = modifyTimestamp;
public ServerCacheNotification(Set<String> dependentTables) {
this.dependentTables = dependentTables;
}
@Override
public String toString() {
return "ts:" + modifyTimestamp + " tables:" + dependentTables;
}
public long getModifyTimestamp() {
return modifyTimestamp;
return "tables:" + dependentTables;
}
public Set<String> getDependentTables() {
+1 -1
View File
@@ -25,7 +25,7 @@ public enum ServerCacheType {
*/
QUERY("_Q");
private String code;
private final String code;
ServerCacheType(String code) {
this.code = code;
@@ -219,7 +219,6 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
/**
* Copies all relevant properties for a clone. See {@link #getShallowCopy()}
* @param other
*/
protected void setFromOriginal(AbstractBeanCollection<E> other) {
this.disableLazyLoad = other.disableLazyLoad;
+1 -1
View File
@@ -237,7 +237,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({"unchecked"})
public Set<Entry<K, E>> entrySet() {
init();
if (isReadOnly()) {
@@ -52,6 +52,8 @@ public class PlatformConfig {
*/
private boolean databaseInetAddressVarchar;
private boolean caseSensitiveCollation = true;
/**
* Modify the default mapping of standard types such as default precision for DECIMAL etc.
*/
@@ -74,6 +76,10 @@ public class PlatformConfig {
this.idType = platformConfig.idType;
this.geometrySRID = platformConfig.geometrySRID;
this.dbUuid = platformConfig.dbUuid;
this.caseSensitiveCollation = platformConfig.caseSensitiveCollation;
this.allQuotedIdentifiers = platformConfig.allQuotedIdentifiers;
this.databaseInetAddressVarchar = platformConfig.databaseInetAddressVarchar;
this.customDbTypeMappings = platformConfig.customDbTypeMappings;
}
/**
@@ -90,6 +96,20 @@ public class PlatformConfig {
this.allQuotedIdentifiers = allQuotedIdentifiers;
}
/**
* Return true if the collation is case sensitive.
*/
public boolean isCaseSensitiveCollation() {
return caseSensitiveCollation;
}
/**
* Set to false to indicate that the collation is case insensitive.
*/
public void setCaseSensitiveCollation(boolean caseSensitiveCollation) {
this.caseSensitiveCollation = caseSensitiveCollation;
}
/**
* Return a value used to represent TRUE in the database.
* <p>
@@ -255,6 +275,7 @@ public class PlatformConfig {
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
databaseBooleanFalse = p.get("databaseBooleanFalse", databaseBooleanFalse);
databaseInetAddressVarchar = p.getBoolean("databaseInetAddressVarchar", databaseInetAddressVarchar);
caseSensitiveCollation = p.getBoolean("caseSensitiveCollation", caseSensitiveCollation);
DbUuid dbUuid = p.getEnum(DbUuid.class, "dbuuid", null);
if (dbUuid != null) {
@@ -518,7 +518,7 @@ public class ServerConfig {
/**
* Controls the default order by id setting of queries. See {@link Query#orderById(boolean)}
*/
private boolean defaultOrderById = false;
private boolean defaultOrderById;
/**
* The mappingLocations for searching xml mapping.
@@ -585,8 +585,9 @@ public class ServerConfig {
/**
* Sets the default orderById setting for queries.
* Deprecated - look to have explicit order by. Sets the default orderById setting for queries.
*/
@Deprecated
public void setDefaultOrderById(boolean defaultOrderById) {
this.defaultOrderById = defaultOrderById;
}
@@ -652,6 +653,7 @@ public class ServerConfig {
* @param cls The type of the service object to obtain
* @return The service object given the class type
*/
@SuppressWarnings("unchecked")
public <P> P getServiceObject(Class<P> cls) {
return (P) serviceObject.get(serviceObjectKey(cls));
}
@@ -35,9 +35,9 @@ public enum TenantMode {
* (that holds configuration e.g.)
*/
DB_WITH_MASTER(true, true);
boolean dynamicDataSource;
boolean ddlEnabled;
final boolean dynamicDataSource;
final boolean ddlEnabled;
TenantMode(boolean dynamicDataSource, boolean ddlEnabled) {
this.dynamicDataSource = dynamicDataSource;
@@ -50,12 +50,12 @@ public enum TenantMode {
public boolean isDynamicDataSource() {
return dynamicDataSource;
}
/**
* Returns true, if DDL is enabled.
*/
public boolean isDdlEnabled() {
return ddlEnabled;
}
}
@@ -71,6 +71,8 @@ public class DatabasePlatform {
*/
protected boolean allQuotedIdentifiers;
protected boolean caseSensitiveCollation = true;
/**
* For limit/offset, row_number etc limiting of SQL queries.
*/
@@ -226,6 +228,7 @@ public class DatabasePlatform {
*/
public void configure(PlatformConfig config) {
this.sequenceBatchSize = config.getDatabaseSequenceBatchSize();
this.caseSensitiveCollation = config.isCaseSensitiveCollation();
configureIdType(config.getIdType());
configure(config, config.isAllQuotedIdentifiers());
}
@@ -315,6 +318,16 @@ public class DatabasePlatform {
return supportsDeleteTableAlias;
}
/**
* Return true if the collation is case sensitive.
* <p>
* This is expected to be used for testing only.
* </p>
*/
public boolean isCaseSensitiveCollation() {
return caseSensitiveCollation;
}
/**
* Return the maximum table name length.
* <p>
@@ -27,15 +27,13 @@ public class DbDefaultValue {
* The key for the NOW / current timestamp.
*/
public static final String NOW = "now";
/**
* The 'null' literal.
*/
public static final String NULL = "null";
protected Map<String, String> map = new LinkedHashMap<>();
protected final Map<String, String> map = new LinkedHashMap<>();
/**
* Set the DB now function.
@@ -82,10 +80,9 @@ public class DbDefaultValue {
return val != null ? val : dbDefaultLiteral;
}
/**
* This method checks & convert the {@link DbDefault#value()} to a valid SQL literal.
*
*
* This is mainly to quote string literals and verify integer/dates for correctness.
* <p>
* Note: There are some special cases:
@@ -98,24 +95,24 @@ public class DbDefaultValue {
* If you need really the String "null", you have to specify <code>@DbDefault("'null'")</code>
* which gives you the <code>default 'null'</code> statement.</li>
* <li>Any statement, that begins and ends with single quote will not be checked or get quoted again.</li>
* <li>A statement that begins with "$RAW:", e.g <code>@DbDefault("$RAW:N'SANDNES'")</code> will lead to
* <li>A statement that begins with "$RAW:", e.g <code>@DbDefault("$RAW:N'SANDNES'")</code> will lead to
* a <code>default N'SANDNES'</code> in DDL. Note that this is platform specific!</li>
* </ul>
*/
public static String toSqlLiteral(String defaultValue, Class<?> propertyType, int sqlType) {
if (propertyType == null
|| defaultValue == null
|| defaultValue == null
|| NULL.equals(defaultValue)
|| (defaultValue.startsWith("'") && defaultValue.endsWith("'"))
|| (defaultValue.startsWith("$RAW:"))) {
|| (defaultValue.startsWith("$RAW:"))) {
return defaultValue;
}
if (Boolean.class.isAssignableFrom(propertyType) || Boolean.TYPE.isAssignableFrom(propertyType)) {
return toBooleanLiteral(defaultValue);
}
if (Number.class.isAssignableFrom(propertyType)
if (Number.class.isAssignableFrom(propertyType)
|| Byte.TYPE.equals(propertyType)
|| Short.TYPE.equals(propertyType)
|| Integer.TYPE.equals(propertyType)
@@ -126,7 +123,7 @@ public class DbDefaultValue {
Double.valueOf(defaultValue); // verify if it is a number
return defaultValue;
}
// check if it is a date/time - in all other cases return quoted defaultValue
switch (sqlType) {
// date
@@ -155,7 +152,7 @@ public class DbDefaultValue {
}
throw new IllegalArgumentException("'" + value + "' is not a valid value for boolean");
}
/**
* This adds single qoutes around the <code>value</code> and doubles single quotes.
* "User's home" will return "'User''s home'"
@@ -175,7 +172,7 @@ public class DbDefaultValue {
return sb.toString();
}
private static String toDateLiteral(String value) {
if (NOW.equals(value)) {
return value; // this will get translated later
@@ -191,7 +188,7 @@ public class DbDefaultValue {
DatatypeConverter.parseTime(value); // verify
return toTextLiteral(value);
}
private static String toDateTimeLiteral(String value) {
if (NOW.equals(value)) {
return value; // this will get translated later
@@ -11,12 +11,12 @@ class DbPlatformTypeLookup {
/**
* A map to lookup the type by name.
*/
private Map<String, DbType> nameLookup = new HashMap<>();
private final Map<String, DbType> nameLookup = new HashMap<>();
/**
* A map to lookup the type by JDBC int value.
*/
private Map<Integer, DbType> idLookup = new HashMap<>();
private final Map<Integer, DbType> idLookup = new HashMap<>();
DbPlatformTypeLookup() {
addAll();
@@ -23,7 +23,7 @@ public class DbPlatformTypeMapping {
}
}
private static DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
private static final DbPlatformTypeLookup lookup = new DbPlatformTypeLookup();
private static final DbPlatformType BOOLEAN_LOGICAL = new BooleanLogicalType();
@@ -8,7 +8,7 @@ import java.util.Map;
*/
public class SqlErrorCodes {
private Map<String,DataErrorType> map = new HashMap<>();
private final Map<String,DataErrorType> map = new HashMap<>();
/**
* Map the codes to AcquireLockException.
@@ -35,7 +35,7 @@ public class MySqlPlatform extends DatabasePlatform {
this.dbIdentity.setSupportsGetGeneratedKeys(true);
this.dbIdentity.setSupportsIdentity(true);
this.dbIdentity.setSupportsSequence(false);
this.dbDefaultValue.setNow("now(6)"); // must have same precision as TIMESTAMP
this.dbDefaultValue.setFalse("0");
this.dbDefaultValue.setTrue("1");
@@ -51,8 +51,8 @@ public class MySqlPlatform extends DatabasePlatform {
this.openQuote = "`";
this.closeQuote = "`";
// use pipe for escaping as it depends if mysql runs in no_backslash_escapes or not.
this.likeClauseRaw = "like binary ? escape ''";
this.likeClauseEscaped = "like binary ? escape '|'";
this.likeClauseRaw = "like ? escape ''";
this.likeClauseEscaped = "like ? escape '|'";
this.forwardOnlyHintOnFindIterate = true;
this.booleanDbType = Types.BIT;
@@ -47,8 +47,8 @@ abstract class SqlServerBasePlatform extends DatabasePlatform {
this.openQuote = "[";
this.closeQuote = "]";
this.likeSpecialCharacters = new char[]{'%', '_', '['};
this.likeClauseRaw = "like ? collate Latin1_General_BIN";
this.likeClauseEscaped = "like ? collate Latin1_General_BIN";
this.likeClauseRaw = "like ?";
this.likeClauseEscaped = "like ?";
booleanDbType = Types.INTEGER;
this.dbDefaultValue.setFalse("0");
@@ -14,189 +14,192 @@ import javax.naming.NamingException;
*/
final class PropertyEval {
/**
* Prefix for looking up JNDI Environment variable.
*/
private static final String JAVA_COMP_ENV = "java:comp/env/";
/**
* Prefix for looking up JNDI Environment variable.
*/
private static final String JAVA_COMP_ENV = "java:comp/env/";
/**
* Used to detect the start of an expression.
*/
private static final String START = "${";
/**
* Used to detect the start of an expression.
*/
private static final String START = "${";
/**
* Used to detect the end of an expression.
*/
private static final String END = "}";
/**
* Used to detect the end of an expression.
*/
private static final String END = "}";
/**
* Specify the PropertyHolder.
*/
private PropertyEval() {
}
/**
* Specify the PropertyHolder.
*/
private PropertyEval() {
}
/**
* Return the property value evaluating and replacing any expressions such as
* ${CATALINA_HOME}.
*/
static String eval(String val) {
if (val == null) {
return null;
}
int sp = val.indexOf(START);
if (sp > -1) {
int ep = val.indexOf(END, sp + 1);
if (ep > -1) {
return eval(val, sp, ep);
}
}
return val;
}
/**
* Return the property value evaluating and replacing any expressions such as
* ${CATALINA_HOME}.
*/
static String eval(String val) {
if (val == null) {
return null;
}
int sp = val.indexOf(START);
if (sp > -1) {
int ep = val.indexOf(END, sp + 1);
if (ep > -1) {
return eval(val, sp, ep);
}
}
return val;
}
/**
* Convert the expression using JNDI, Environment variables, System Properties
* or existing an property in SystemProperties itself.
*/
private static String evaluateExpression(String exp) {
/**
* Convert the expression using JNDI, Environment variables, System Properties
* or existing an property in SystemProperties itself.
*/
private static String evaluateExpression(String exp) {
if (isJndiExpression(exp)) {
// JNDI property lookup...
String val = getJndiProperty(exp);
if (val != null) {
return val;
}
}
String val = System.getProperty(exp);
if (val == null) {
val = System.getenv(exp);
}
return val;
}
if (exp.isEmpty()) {
return null;
}
if (isJndiExpression(exp)) {
// JNDI property lookup...
String val = getJndiProperty(exp);
if (val != null) {
return val;
}
}
String val = System.getProperty(exp);
if (val == null) {
val = System.getenv(exp);
}
return val;
}
private static String eval(String val, int sp, int ep) {
private static String eval(String val, int sp, int ep) {
return new EvalBuffer(val, sp, ep).process();
}
return new EvalBuffer(val, sp, ep).process();
}
private static boolean isJndiExpression(String exp) {
return exp.startsWith("JNDI:") || exp.startsWith("jndi:");
}
private static boolean isJndiExpression(String exp) {
return exp.startsWith("JNDI:") || exp.startsWith("jndi:");
}
/**
* Returns null if JNDI is not setup or if the property is not found.
*
* @param key the key of the JNDI Environment property including a JNDI: prefix.
*/
private static String getJndiProperty(String key) {
/**
* Returns null if JNDI is not setup or if the property is not found.
*
* @param key the key of the JNDI Environment property including a JNDI: prefix.
*/
private static String getJndiProperty(String key) {
try {
// remove the JNDI: prefix
key = key.substring(5);
return (String) getJndiObject(key);
} catch (NamingException ex) {
return null;
}
}
try {
// remove the JNDI: prefix
key = key.substring(5);
return (String) getJndiObject(key);
} catch (NamingException ex) {
return null;
}
}
/**
* Similar to getProperty but throws NamingException if JNDI is not setup or
* if the property is not found.
*/
private static Object getJndiObject(String key) throws NamingException {
/**
* Similar to getProperty but throws NamingException if JNDI is not setup or
* if the property is not found.
*/
private static Object getJndiObject(String key) throws NamingException {
InitialContext ctx = new InitialContext();
return ctx.lookup(JAVA_COMP_ENV + key);
}
InitialContext ctx = new InitialContext();
return ctx.lookup(JAVA_COMP_ENV + key);
}
private static class EvalBuffer {
private static class EvalBuffer {
private final StringBuilder buf = new StringBuilder();
private final String original;
private int position;
private int start;
private int end;
private final StringBuilder buf = new StringBuilder();
private final String original;
private int position;
private int start;
private int end;
private String expression;
private String defaultValue;
private String expression;
private String defaultValue;
EvalBuffer(String val, int start, int ep) {
this.original = val;
this.start = start;
this.end = ep;
this.position = 0;
moveToStart();
}
EvalBuffer(String val, int start, int ep) {
this.original = val;
this.start = start;
this.end = ep;
this.position = 0;
moveToStart();
}
void moveToStart() {
if (start > position) {
buf.append(original.substring(position, start));
position = start;
}
}
void moveToStart() {
if (start > position) {
buf.append(original.substring(position, start));
position = start;
}
}
void parseForDefault() {
int colonPos = original.lastIndexOf(':', end);
if (colonPos > start) {
expression = original.substring(start + START.length(), colonPos);
defaultValue = original.substring(colonPos + 1, end);
} else {
expression = original.substring(start + START.length(), end);
}
}
void parseForDefault() {
int colonPos = original.lastIndexOf(':', end);
if (colonPos > start) {
expression = original.substring(start + START.length(), colonPos);
defaultValue = original.substring(colonPos + 1, end);
} else {
expression = original.substring(start + START.length(), end);
}
}
void evaluate() {
String eval = evaluateExpression(expression);
if (eval != null) {
buf.append(eval);
} else {
if (defaultValue != null) {
buf.append(defaultValue);
} else {
buf.append(START).append(expression).append(END);
}
}
}
void evaluate() {
String eval = evaluateExpression(expression);
if (eval != null) {
buf.append(eval);
} else {
if (defaultValue != null) {
buf.append(defaultValue);
} else {
buf.append(START).append(expression).append(END);
}
}
}
String end() {
if (end < original.length() - 1) {
buf.append(original.substring(end + 1));
}
return buf.toString();
}
String end() {
if (end < original.length() - 1) {
buf.append(original.substring(end + 1));
}
return buf.toString();
}
boolean next() {
if (end < original.length()) {
int startPos = original.indexOf(START, end + 1);
if (startPos > -1) {
int endPos = original.indexOf(END, startPos + 1);
if (endPos > -1) {
if (startPos > end + 1) {
buf.append(original.substring(end + 1, startPos));
}
this.start = startPos;
this.end = endPos;
return true;
}
}
}
return false;
}
boolean next() {
if (end < original.length()) {
int startPos = original.indexOf(START, end + 1);
if (startPos > -1) {
int endPos = original.indexOf(END, startPos + 1);
if (endPos > -1) {
if (startPos > end + 1) {
buf.append(original.substring(end + 1, startPos));
}
this.start = startPos;
this.end = endPos;
return true;
}
}
}
return false;
}
private void evalNext() {
parseForDefault();
evaluate();
}
private void evalNext() {
parseForDefault();
evaluate();
}
String process() {
evalNext();
while (next()) {
evalNext();
}
return end();
}
String process() {
evalNext();
while (next()) {
evalNext();
}
return end();
}
}
}
}
@@ -10,7 +10,7 @@ import java.util.Set;
*/
public class QueryPlanRequest {
private List<MetaQueryPlan> plans = new ArrayList<>();
private final List<MetaQueryPlan> plans = new ArrayList<>();
private Connection connection;
@@ -10,7 +10,7 @@ import java.util.ServiceLoader;
*/
class MetricServiceProvider {
private static MetricFactory metricFactory = init();
private static final MetricFactory metricFactory = init();
private static MetricFactory init() {
@@ -223,7 +223,6 @@ public interface BeanType<T> {
/**
* Visit all children recursively
* @param visitor
*/
void visitAllInheritanceChildren(Consumer<BeanType<?>> visitor);
@@ -77,7 +77,7 @@ public interface ExpressionPath {
/**
* Return the underlying bean property.
*/
public Property getProperty();
Property getProperty();
/**
* The ElPrefix plus name.
@@ -49,13 +49,12 @@ class PathPropertiesParser {
private String getPath() {
do {
char c1 = chars[pos++];
switch (c1) {
case '(':
return currentWord();
default:
if (pos == 1) {
return "";
}
if (c1 == '(') {
return currentWord();
} else {
if (pos == 1) {
return "";
}
}
} while (pos < eof);
throw new RuntimeException("Hit EOF while reading sectionTitle from " + startPos);
@@ -8,7 +8,7 @@ import java.util.List;
*/
public class BeanCacheResult<T> {
private List<Entry<T>> list = new ArrayList<>();
private final List<Entry<T>> list = new ArrayList<>();
/**
* Add an entry.
@@ -115,10 +115,10 @@ public class BindParams implements Serializable {
* Return a Natural Key bind param if supported.
*/
public NaturalKeyBindParam getNaturalKeyBindParam() {
if (positionedParameters != null) {
if (!positionedParameters.isEmpty()) {
return null;
}
if (namedParameters != null && namedParameters.size() == 1) {
if (namedParameters.size() == 1) {
Entry<String, Param> e = namedParameters.entrySet().iterator().next();
return new NaturalKeyBindParam(e.getKey(), e.getValue().getInValue());
}
@@ -12,8 +12,8 @@ import java.util.Map;
*/
public class NaturalKeyEntry {
private Map<String,Object> map = new HashMap<>();
private Object key;
private final Map<String,Object> map = new HashMap<>();
private final Object key;
private Object inValue;
/**
@@ -17,7 +17,7 @@ public class ScopedTransaction extends SpiTransactionProxy {
/**
* Stack of 'nested' transactions.
*/
private ArrayStack<ScopeTrans> stack = new ArrayStack<>();
private final ArrayStack<ScopeTrans> stack = new ArrayStack<>();
private ScopeTrans current;
@@ -70,7 +70,7 @@ public class ScopedTransaction extends SpiTransactionProxy {
private void clearScopeOnce() {
if (!scopeCleared) {
manager.set(null);
manager.clear();
scopeCleared = true;
}
}
@@ -133,6 +133,11 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanLoader,
*/
void externalModification(TransactionEventTable event);
/**
* Clear an implicit transaction from the scope.
*/
void clearServerTransaction();
/**
* Begin a managed transaction (Uses scope manager / ThreadLocal).
*/
@@ -106,9 +106,9 @@ public interface SpiQuery<T> extends Query<T>, TxnProfileEventCodes {
*/
UPDATE(FIND_UPDATE, "update", true);
private boolean update;
private String profileEventId;
private String label;
private final boolean update;
private final String profileEventId;
private final String label;
Type(String profileEventId, String label) {
this(profileEventId, label, false);
@@ -98,7 +98,7 @@ public interface SpiTransaction extends Transaction {
/**
* Return the start timestamp for the transaction (JVM side).
*/
long getStartMillis();
long getStartNanoTime();
/**
* Return true if this transaction has updateAllLoadedProperties set.
@@ -1,6 +1,7 @@
package io.ebeaninternal.api;
import io.ebean.TxScope;
import io.ebeaninternal.server.transaction.TransactionScopeManager;
import javax.sql.DataSource;
@@ -9,6 +10,11 @@ import javax.sql.DataSource;
*/
public interface SpiTransactionManager {
/**
* Return the scope manager for this server.
*/
TransactionScopeManager scope();
/**
* Return the main DataSource.
*/
@@ -29,8 +29,8 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
}
@Override
public long getStartMillis() {
return transaction.getStartMillis();
public long getStartNanoTime() {
return transaction.getStartNanoTime();
}
@Override
@@ -325,7 +325,7 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
@Override
public void depth(int diff) {
transaction.depth();
transaction.depth(diff);
}
@Override
@@ -30,8 +30,6 @@ public class TransactionEvent implements Serializable {
*/
private final transient boolean local;
private final long startMillis;
private TransactionEventTable eventTables;
private transient List<PersistRequestBean<?>> listenerNotify;
@@ -43,8 +41,7 @@ public class TransactionEvent implements Serializable {
/**
* Create the TransactionEvent, one per Transaction.
*/
public TransactionEvent(long startMillis) {
this.startMillis = startMillis;
public TransactionEvent() {
this.local = true;
}
@@ -78,7 +75,7 @@ public class TransactionEvent implements Serializable {
* Return the list of PersistRequestBean's for this transaction.
*/
public List<PersistRequestBean<?>> getListenerNotify() {
return (listenerNotify == null) ? null : listenerNotify;
return listenerNotify;
}
public TransactionEventTable getEventTables() {
@@ -119,7 +116,7 @@ public class TransactionEvent implements Serializable {
}
if (changeSet == null) {
changeSet = new CacheChangeSet(manager.clockNowMillis());
changeSet = new CacheChangeSet();
}
if (eventTables != null && !eventTables.isEmpty()) {
// notify cache with table based changes
@@ -154,7 +151,7 @@ public class TransactionEvent implements Serializable {
*/
public CacheChangeSet obtainCacheChangeSet() {
if (changeSet == null) {
changeSet = new CacheChangeSet(startMillis);
changeSet = new CacheChangeSet();
}
return changeSet;
}
@@ -22,6 +22,7 @@ import io.ebean.config.dbplatform.sqlite.SQLitePlatform;
import io.ebean.config.dbplatform.sqlserver.SqlServer16Platform;
import io.ebean.config.dbplatform.sqlserver.SqlServer17Platform;
import io.ebean.dbmigration.DbMigration;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.ddlgeneration.DdlWrite;
import io.ebeaninternal.dbmigration.migration.Migration;
@@ -29,7 +30,6 @@ import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlWriter;
import io.ebeaninternal.dbmigration.model.CurrentModel;
import io.ebeaninternal.dbmigration.model.MConfiguration;
import io.ebeaninternal.dbmigration.model.MigrationModel;
import io.ebeaninternal.dbmigration.model.MigrationVersion;
import io.ebeaninternal.dbmigration.model.ModelContainer;
import io.ebeaninternal.dbmigration.model.ModelDiff;
import io.ebeaninternal.dbmigration.model.PlatformDdlWriter;
@@ -1,12 +1,13 @@
package io.ebeaninternal.dbmigration;
import io.ebeaninternal.dbmigration.model.MigrationVersion;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.ebean.migration.MigrationVersion;
/**
* Utility to determine the last sql migration version and next version.
*/
@@ -59,10 +60,7 @@ class LastMigration {
}
private static boolean includeSqlFile(String lowerFileName) {
if (lowerFileName.startsWith("r") || lowerFileName.startsWith("i") || !lowerFileName.endsWith(SQL)) {
return false;
}
return true;
return !lowerFileName.startsWith("r") && !lowerFileName.startsWith("i") && lowerFileName.endsWith(SQL);
}
private static boolean includeModelFile(String lowerFileName) {
@@ -62,14 +62,14 @@ public class BaseTableDdl implements TableDdl {
* Used to check that indexes on foreign keys should be skipped as a unique index on the columns
* already exists.
*/
protected IndexSet indexSet = new IndexSet();
protected final IndexSet indexSet = new IndexSet();
/**
* Used when unique constraints specifically for OneToOne can't be created normally (MsSqlServer).
*/
protected List<Column> externalUnique = new ArrayList<>();
protected final List<Column> externalUnique = new ArrayList<>();
protected List<UniqueConstraint> externalCompoundUnique = new ArrayList<>();
protected final List<UniqueConstraint> externalCompoundUnique = new ArrayList<>();
// counters used when constraint names are truncated due to maximum length
// and these counters are used to keep the constraint name unique
@@ -82,9 +82,9 @@ public class BaseTableDdl implements TableDdl {
* Base tables that have associated history tables that need their triggers/functions regenerated as
* columns have been added, removed, included or excluded.
*/
protected Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
protected final Map<String, HistoryTableUpdate> regenerateHistoryTriggers = new LinkedHashMap<>();
private boolean strictMode;
private final boolean strictMode;
private final HistorySupport historySupport;
@@ -134,7 +134,7 @@ public class BaseTableDdl implements TableDdl {
if (defaultValue == null) {
handleStrictError(tableName, columnName);
}
before = Arrays.asList(platformDdl.getUpdateNullWithDefault());
before = Collections.singletonList(platformDdl.getUpdateNullWithDefault());
} else {
before = getScriptsForPlatform(alter.getBefore(), platformDdl.getPlatform().getName());
}
@@ -840,6 +840,7 @@ public class BaseTableDdl implements TableDdl {
/**
* This is mysql specific - alter all the base attributes of the column together.
* Will be called, if there is a type, dbdefault or notnull change.
*/
protected void alterColumnBaseAttributes(DdlWrite writer, AlterColumn alter) throws IOException {
@@ -30,10 +30,7 @@ public class HanaTableDdl extends BaseTableDdl {
@Override
protected void alterColumnDefaultValue(DdlWrite writer, AlterColumn alter) throws IOException {
String ddl = platformDdl.alterColumnBaseAttributes(alter);
if (hasValue(ddl)) {
writer.apply().append(ddl).endOfStatement();
}
// done in alterColumnBaseAttributes
}
@Override
@@ -112,7 +112,9 @@ public class MySqlDdl extends PlatformDdl {
@Override
public String alterColumnBaseAttributes(AlterColumn alter) {
if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
if (alter.getType() == null && alter.isNotnull() == null) {
// No type change or notNull change
// defaultValue change already handled in alterColumnDefaultValue
return null;
}
String tableName = alter.getTableName();
@@ -149,7 +149,9 @@ public class SqlServerDdl extends PlatformDdl {
@Override
public String alterColumnBaseAttributes(AlterColumn alter) {
if (DdlHelp.isDropDefault(alter.getDefaultValue())) {
if (alter.getType() == null && alter.isNotnull() == null) {
// No type change or notNull change
// defaultValue change already handled in alterColumnDefaultValue
return null;
}
String tableName = alter.getTableName();
@@ -150,7 +150,7 @@ public class CurrentModel {
List<DdlScript> ddlScript = extraDdl.getDdlScript();
for (DdlScript script : ddlScript) {
if (script.isInit() && ExtraDdlXmlReader.matchPlatform(server.getDatabasePlatform().getName(), script.getPlatforms())) {
ddl.append(prefix + script.getName()).append('\n');
ddl.append(prefix).append(script.getName()).append('\n');
ddl.append(script.getValue());
}
}
@@ -8,6 +8,7 @@ import io.ebeaninternal.dbmigration.migration.DdlScript;
import io.ebeaninternal.server.deploy.DbMigrationInfo;
import java.util.List;
import java.util.Objects;
/**
* A column in the logical model.
@@ -309,7 +310,7 @@ public class MColumn {
}
protected static boolean different(String val1, String val2) {
return (val1 == null) ? val2 != null : !val1.equals(val2);
return !Objects.equals(val1, val2);
}
private boolean hasValue(String val) {
@@ -769,7 +769,7 @@ public class MTable {
nullableColumns.add(columnName);
}
}
uniq.setNullableColumns(nullableColumns.toArray(new String[nullableColumns.size()]));
uniq.setNullableColumns(nullableColumns.toArray(new String[0]));
}
}
@@ -3,6 +3,8 @@ package io.ebeaninternal.dbmigration.model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.ebean.migration.MigrationVersion;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
@@ -1,5 +1,6 @@
package io.ebeaninternal.dbmigration.model;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.dbmigration.migration.Migration;
import io.ebeaninternal.dbmigration.migrationreader.MigrationXmlReader;
@@ -1,211 +0,0 @@
package io.ebeaninternal.dbmigration.model;
import java.util.Arrays;
import java.util.regex.Pattern;
/**
* The version of a migration used so that migrations are processed in order.
*/
public class MigrationVersion implements Comparable<MigrationVersion> {
private static final Pattern SECTION_SPLITTER = Pattern.compile("[\\.-]");
private static final int[] REPEAT_ORDERING = {Integer.MAX_VALUE};
private static final boolean[] REPEAT_UNDERSCORES = {false};
/**
* The raw version text.
*/
private final String raw;
/**
* The ordering parts.
*/
private final int[] ordering;
private final boolean[] underscores;
private final String comment;
/**
* Construct for "repeatable" version.
*/
private MigrationVersion(String raw, String comment) {
this.raw = raw;
this.comment = comment;
this.ordering = REPEAT_ORDERING;
this.underscores = REPEAT_UNDERSCORES;
}
/**
* Construct for "normal" version.
*/
private MigrationVersion(String raw, int[] ordering, boolean[] underscores, String comment) {
this.raw = raw;
this.ordering = ordering;
this.underscores = underscores;
this.comment = comment;
}
/**
* Return true if this is a "repeatable" version.
*/
public boolean isRepeatable() {
// Clarification: The comparison here is intended to compare object references and not the content of the arrays.
// This is a kind of shortcut to see if some configuration is in place that results in the use of something other than the default.
return ordering == REPEAT_ORDERING;
}
/**
* Return the full version.
*/
public String getFull() {
return raw;
}
@Override
public String toString() {
return raw;
}
/**
* Return the version comment.
*/
public String getComment() {
return comment;
}
/**
* Return the version in raw form.
*/
public String getRaw() {
return raw;
}
/**
* Return the trimmed version excluding version comment and un-parsable string.
*/
public String asString() {
return formattedVersion(false, false);
}
/**
* Return the trimmed version with any underscores replaced with '.'
*/
public String normalised() {
return formattedVersion(true, false);
}
/**
* Return the next version based on this version.
*/
public String nextVersion() {
return formattedVersion(false, true);
}
/**
* Returns the version part of the string.
* <p>
* Normalised means always use '.' delimiters (no underscores).
* NextVersion means bump/increase the last version number by 1.
*/
private String formattedVersion(boolean normalised, boolean nextVersion) {
// Clarification: The comparison here is intended to compare object references and not the content of the arrays.
// This is a kind of shortcut to see if some configuration is in place that results in the use of something other than the default.
if (ordering == REPEAT_ORDERING) {
return "R";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ordering.length; i++) {
if (i < ordering.length - 1) {
sb.append(ordering[i]);
if (normalised) {
sb.append('.');
} else {
sb.append(underscores[i] ? '_' : '.');
}
} else {
sb.append((nextVersion) ? ordering[i] + 1 : ordering[i]);
}
}
return sb.toString();
}
@Override
public int compareTo(MigrationVersion other) {
int otherLength = other.ordering.length;
for (int i = 0; i < ordering.length; i++) {
if (i >= otherLength) {
// considered greater
return 1;
}
if (ordering[i] != other.ordering[i]) {
return (ordering[i] > other.ordering[i]) ? 1 : -1;
}
}
return comment.compareTo(other.comment);
}
/**
* Parse the raw version string and just return the leading version number;
*/
public static String trim(String raw) {
return parse(raw).asString();
}
/**
* Parse the raw version string into a MigrationVersion.
*/
public static MigrationVersion parse(String raw) {
if (raw.startsWith("V") || raw.startsWith("v")) {
raw = raw.substring(1);
}
String comment = "";
String value = raw;
int commentStart = raw.indexOf("__");
if (commentStart > -1) {
// trim off the trailing comment
comment = raw.substring(commentStart + 2);
value = value.substring(0, commentStart);
}
value = value.replace('_', '.');
String[] sections = SECTION_SPLITTER.split(value);
if ("r".equalsIgnoreCase(sections[0])) {
// a "repeatable" version (does not have a version number)
return new MigrationVersion(raw, comment);
}
boolean[] underscores = new boolean[sections.length];
int[] ordering = new int[sections.length];
int delimiterPos = 0;
int stopIndex = 0;
for (int i = 0; i < sections.length; i++) {
try {
ordering[i] = Integer.parseInt(sections[i]);
stopIndex++;
delimiterPos += sections[i].length();
underscores[i] = (delimiterPos < raw.length() - 1 && raw.charAt(delimiterPos) == '_');
delimiterPos++;
} catch (NumberFormatException e) {
// stop parsing
break;
}
}
int[] actualOrder = Arrays.copyOf(ordering, stopIndex);
boolean[] actualUnderscores = Arrays.copyOf(underscores, stopIndex);
return new MigrationVersion(raw, actualOrder, actualUnderscores, comment);
}
}
@@ -1,5 +1,6 @@
package io.ebeaninternal.dbmigration.model;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.DdlHelp;
import io.ebeaninternal.dbmigration.ddlgeneration.platform.SplitColumns;
import io.ebeaninternal.dbmigration.migration.AddColumn;
@@ -1,5 +1,6 @@
package io.ebeaninternal.dbmigration.model;
import io.ebean.migration.MigrationVersion;
import io.ebeaninternal.dbmigration.migration.ChangeSet;
import io.ebeaninternal.dbmigration.migration.ChangeSetType;
import io.ebeaninternal.dbmigration.migration.DropColumn;
@@ -181,7 +181,7 @@ public class DJsonService implements SpiJsonService {
if (modifyAware) {
return ((ModifyAwareList<T>) list).asSet();
} else {
return new LinkedHashSet<T>(list);
return new LinkedHashSet<>(list);
}
}
@@ -36,14 +36,18 @@ public class ModifyAwareList<E> implements List<E>, ModifyAwareOwner {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ModifyAwareList)) return false;
ModifyAwareList<?> that = (ModifyAwareList<?>) o;
return Objects.equals(list, that.list);
if (o instanceof ModifyAwareList) {
ModifyAwareList<?> that = (ModifyAwareList<?>) o;
return Objects.equals(list, that.list);
}
if (!(o instanceof List)) return false;
List<?> that = (List<?>) o;
return Objects.equals(list, that);
}
@Override
public int hashCode() {
return Objects.hash(list);
return list.hashCode();
}
@Override
@@ -38,14 +38,18 @@ public class ModifyAwareMap<K, V> implements Map<K, V>, ModifyAwareOwner {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ModifyAwareMap)) return false;
ModifyAwareMap<?, ?> that = (ModifyAwareMap<?, ?>) o;
return Objects.equals(map, that.map);
if (o instanceof ModifyAwareMap) {
ModifyAwareMap<?,?> that = (ModifyAwareMap<?,?>) o;
return Objects.equals(map, that.map);
}
if (!(o instanceof Map)) return false;
Map<?,?> that = (Map<?,?>) o;
return Objects.equals(map, that);
}
@Override
public int hashCode() {
return Objects.hash(map);
return map.hashCode();
}
@Override
@@ -55,14 +55,18 @@ public class ModifyAwareSet<E> implements Set<E>, ModifyAwareOwner {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ModifyAwareSet)) return false;
ModifyAwareSet<?> that = (ModifyAwareSet<?>) o;
return Objects.equals(set, that.set);
if (o instanceof ModifyAwareSet) {
ModifyAwareSet<?> that = (ModifyAwareSet<?>) o;
return Objects.equals(set, that.set);
}
if (!(o instanceof Set)) return false;
Set<?> that = (Set<?>) o;
return Objects.equals(set, that);
}
@Override
public int hashCode() {
return Objects.hash(set);
return set.hashCode();
}
@Override
@@ -11,7 +11,7 @@ import java.util.List;
*/
public class AutoTuneCollection {
List<Entry> entries = new ArrayList<>();
final List<Entry> entries = new ArrayList<>();
public Entry add(ObjectGraphOrigin origin, OrmQueryDetail detail, String sourceQuery) {
Entry entry = new Entry(origin, detail, sourceQuery);
@@ -28,13 +28,10 @@ public class CacheChangeSet {
private final Map<ManyKey, ManyChange> manyChangeMap = new HashMap<>();
private final long modificationTimestamp;
/**
* Construct specifying if we also need to process invalidation for entities based on views.
*/
public CacheChangeSet(long modificationTimestamp) {
this.modificationTimestamp = modificationTimestamp;
public CacheChangeSet() {
}
/**
@@ -86,6 +83,7 @@ public class CacheChangeSet {
*/
public void addClearQuery(BeanDescriptor<?> descriptor) {
queryCaches.add(descriptor);
touchedTables.add(descriptor.getBaseTable());
}
/**
@@ -172,13 +170,6 @@ public class CacheChangeSet {
return manyChangeMap.computeIfAbsent(key, ManyChange::new);
}
/**
* Return the modification timestamp for these changes.
*/
public long modificationTimestamp() {
return modificationTimestamp;
}
/**
* Changes for a specific many property.
*/
@@ -8,7 +8,7 @@ import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.api.SpiSqlBinding;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.server.lib.util.Str;
import io.ebeaninternal.server.lib.Str;
import io.ebeaninternal.server.persist.Binder;
import io.ebeaninternal.server.persist.TrimLogSql;
import io.ebeaninternal.server.util.BindParamsParser;
@@ -78,6 +78,15 @@ public abstract class BeanRequest {
}
}
/**
* Clear the transaction from the thread local for implicit transactions.
*/
public void clearTransIfRequired() {
if (createdTransaction) {
ebeanServer.clearServerTransaction();
}
}
/**
* Return the server processing the request. Made available for
* BeanController and BeanFinder.
@@ -91,17 +91,13 @@ public class DefaultBackgroundExecutor implements SpiBackgroundExecutor {
if (map == null) {
return schedulePool.schedule(c, delay, unit);
} else {
return schedulePool.schedule(new Callable<V>() {
@Override
public V call() throws Exception {
MDC.setContextMap(map);
try {
return c.call();
} finally {
MDC.clear();
}
return schedulePool.schedule(() -> {
MDC.setContextMap(map);
try {
return c.call();
} finally {
MDC.clear();
}
}, delay, unit);
}
}
@@ -55,10 +55,7 @@ public class DefaultCallStackFactory implements CallStackFactory {
if (element.getClassName().startsWith(IO_EBEAN)) {
return true;
}
if (element.getMethodName().startsWith("_ebean_")) {
return true;
}
return false;
return element.getMethodName().startsWith("_ebean_");
}
private CallStack createCallStack(StackTraceElement[] finalTrace) {
@@ -102,7 +102,7 @@ import io.ebeaninternal.server.query.LimitOffsetPagedList;
import io.ebeaninternal.server.query.QueryFutureIds;
import io.ebeaninternal.server.query.QueryFutureList;
import io.ebeaninternal.server.query.QueryFutureRowCount;
import io.ebeaninternal.server.query.dto.DtoQueryEngine;
import io.ebeaninternal.server.query.DtoQueryEngine;
import io.ebeaninternal.server.querydefn.DefaultDtoQuery;
import io.ebeaninternal.server.querydefn.DefaultOrmQuery;
import io.ebeaninternal.server.querydefn.DefaultOrmUpdate;
@@ -160,7 +160,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
/**
* Clock to use for WhenModified and WhenCreated.
*/
private ClockService clockService;
private final ClockService clockService;
private final CallStackFactory callStackFactory;
@@ -658,10 +658,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
* </p>
*/
@Override
@SuppressWarnings("unchecked")
public <T> T createEntityBean(Class<T> type) {
BeanDescriptor<T> desc = getBeanDescriptor(type);
return (T) desc.createEntityBean(true);
return getBeanDescriptor(type).createBean();
}
/**
@@ -2235,6 +2233,8 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
} catch (RuntimeException e) {
wrap.endIfCreated();
throw e;
} finally {
wrap.clearIfCreated();
}
}
@@ -2254,6 +2254,11 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return new ObtainedTransactionImplicit(trans, this);
}
@Override
public void clearServerTransaction() {
transactionManager.clearServerTransaction();
}
@Override
public SpiTransaction beginServerTransaction() {
return transactionManager.beginServerTransaction();
@@ -7,7 +7,7 @@ import io.ebeaninternal.server.dto.DtoColumn;
import io.ebeaninternal.server.dto.DtoMappingRequest;
import io.ebeaninternal.server.dto.DtoQueryPlan;
import io.ebeaninternal.server.persist.Binder;
import io.ebeaninternal.server.query.dto.DtoQueryEngine;
import io.ebeaninternal.server.query.DtoQueryEngine;
import io.ebeaninternal.server.type.DataReader;
import io.ebeaninternal.server.type.RsetDataReader;
@@ -65,7 +65,7 @@ import io.ebeaninternal.server.persist.platform.PostgresMultiValueBind;
import io.ebeaninternal.server.query.CQueryEngine;
import io.ebeaninternal.server.query.DefaultOrmQueryEngine;
import io.ebeaninternal.server.query.DefaultRelationalQueryEngine;
import io.ebeaninternal.server.query.dto.DtoQueryEngine;
import io.ebeaninternal.server.query.DtoQueryEngine;
import io.ebeaninternal.server.readaudit.DefaultReadAuditLogger;
import io.ebeaninternal.server.readaudit.DefaultReadAuditPrepare;
import io.ebeaninternal.server.text.json.DJsonContext;
@@ -169,7 +169,7 @@ public class InternalConfiguration {
this.online = online;
this.serverConfig = serverConfig;
this.clockService = new ClockService(serverConfig.getClock());
this.tableModState = new TableModState(clockService);
this.tableModState = new TableModState();
this.logManager = initLogManager();
this.docStoreFactory = initDocStoreFactory(serverConfig.service(DocStoreFactory.class));
this.jsonFactory = serverConfig.getJsonFactory();
@@ -328,12 +328,10 @@ public class InternalConfiguration {
private MultiValueBind createMultiValueBind(Platform platform) {
// only Postgres at this stage
switch (platform) {
case POSTGRES:
return new PostgresMultiValueBind();
default:
return new MultiValueBind();
if (platform == Platform.POSTGRES) {
return new PostgresMultiValueBind();
}
return new MultiValueBind();
}
public SpiJsonContext createJsonContext(SpiEbeanServer server) {
@@ -41,4 +41,7 @@ class ObtainedTransaction {
// do nothing
}
public void clearIfCreated() {
// do nothing
}
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.core;
import io.ebean.EbeanServer;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiTransaction;
/**
@@ -11,12 +11,12 @@ import io.ebeaninternal.api.SpiTransaction;
*/
final class ObtainedTransactionImplicit extends ObtainedTransaction {
private final EbeanServer server;
private final SpiEbeanServer server;
/**
* Wrap the transaction indicating if it was just created.
*/
ObtainedTransactionImplicit(SpiTransaction t, EbeanServer server) {
ObtainedTransactionImplicit(SpiTransaction t, SpiEbeanServer server) {
super(t);
this.server = server;
}
@@ -31,4 +31,9 @@ final class ObtainedTransactionImplicit extends ObtainedTransaction {
server.endTransaction();
}
@Override
public void clearIfCreated() {
server.clearServerTransaction();
}
}
@@ -350,6 +350,10 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
public void endTransIfRequired() {
if (createdTransaction && transaction.isActive()) {
transaction.commit();
if (query.getType().isUpdate()) {
// for implicit update/delete queries clear the thread local
ebeanServer.clearServerTransaction();
}
}
}
@@ -692,9 +696,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
public void putToQueryCache(Object result) {
// use transaction start where as query statement start would be better at READ_COMMITTED
long asOfTimestamp = transaction.getStartMillis();
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, asOfTimestamp));
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.getStartNanoTime()));
}
/**
@@ -24,7 +24,7 @@ public abstract class PersistRequest extends BeanRequest implements BatchPostExe
DELETE_PERMANENT(EVT_DELETE_PERMANENT),
UPDATESQL(EVT_UPDATESQL),
CALLABLESQL(EVT_CALLABLESQL);
String profileEventId;
final String profileEventId;
Type(String profileEventId) {
this.profileEventId = profileEventId;
@@ -85,7 +85,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
private DocStoreMode docStoreMode;
private ConcurrencyMode concurrencyMode;
private final ConcurrencyMode concurrencyMode;
/**
* The unique id used for logging summary.
@@ -223,6 +223,12 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
beanDescriptor.setDraftDirty(entityBean, true);
}
this.dirty = intercept.isDirty();
}
/**
* Init generated properties for soft delete (as it's an update).
*/
public void initForSoftDelete() {
initGeneratedProperties();
}
@@ -1320,10 +1326,8 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
*/
public void docStorePersist() {
idValue = beanDescriptor.getId(entityBean);
switch (type) {
case UPDATE:
dirtyProperties = intercept.getDirtyProperties();
break;
if (type == Type.UPDATE) {
dirtyProperties = intercept.getDirtyProperties();
}
// processing now so set IGNORE (unlike DB + DocStore processing with post-commit)
docStoreMode = DocStoreMode.IGNORE;
@@ -1370,6 +1374,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Set the request flags indicating this is an insert.
*/
public void flagInsert() {
initGeneratedProperties();
if (intercept.isNew()) {
flags = Flags.setInsertNormal(flags);
} else {
@@ -1381,6 +1386,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
* Unset the request insert flag indicating this is an update.
*/
public void flagUpdate() {
initGeneratedProperties();
if (intercept.isLoaded()) {
flags = Flags.setUpdateNormal(flags);
} else {
@@ -3,7 +3,7 @@ package io.ebeaninternal.server.core;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiSqlUpdate;
import io.ebeaninternal.api.SpiTransaction;
import io.ebeaninternal.server.lib.util.Str;
import io.ebeaninternal.server.lib.Str;
import io.ebeaninternal.server.persist.BatchControl;
import io.ebeaninternal.server.persist.PersistExecute;
import io.ebeaninternal.server.persist.TrimLogSql;
@@ -29,7 +29,7 @@ public final class PersistRequestUpdateSql extends PersistRequest {
private boolean addBatch;
private boolean forceNoBatch;
private final boolean forceNoBatch;
private boolean batchThisRequest;
@@ -100,7 +100,7 @@ public final class RelationalQueryRequest extends AbstractSqlQueryRequest {
for (int i = 1; i < columnsPlusOne; i++) {
propNames.add(metaData.getColumnLabel(i));
}
return propNames.toArray(new String[propNames.size()]);
return propNames.toArray(new String[0]);
}
/**
@@ -235,7 +235,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
/**
* Map of BeanProperty Linked so as to preserve order.
*/
protected final LinkedHashMap<String, BeanProperty> propMap;
private final LinkedHashMap<String, BeanProperty> propMap;
/**
* Map of DB column to property path (for nativeSql mapping).
@@ -252,7 +252,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
*/
final Class<T> beanType;
protected final Class<?> rootBeanType;
final Class<?> rootBeanType;
/**
* This is not sent to a remote client.
@@ -287,11 +287,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
*/
private final ChangeLogFilter changeLogFilter;
/**
* The table joins for this bean.
*/
private final TableJoin[] derivedTableJoins;
/**
* Inheritance information. Server side only.
*/
@@ -374,7 +369,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
* All non transient properties excluding the id properties.
*/
private final BeanProperty[] propertiesNonTransient;
protected final BeanProperty[] propertiesIndex;
final BeanProperty[] propertiesIndex;
private final BeanProperty[] propertiesGenInsert;
private final BeanProperty[] propertiesGenUpdate;
private final List<BeanProperty[]> propertiesUnique = new ArrayList<>();
@@ -423,7 +418,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
private final BeanDescriptorDraftHelp<T> draftHelp;
private final BeanDescriptorCacheHelp<T> cacheHelp;
final BeanDescriptorJsonHelp<T> jsonHelp;
private final BeanDescriptorJsonHelp<T> jsonHelp;
private DocStoreBeanAdapter<T> docStoreAdapter;
private DocumentMapping docMapping;
private boolean docStoreEmbeddedInvalidation;
@@ -529,8 +524,6 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
this.propertiesGenInsert = listHelper.getGeneratedInsert();
this.propertiesGenUpdate = listHelper.getGeneratedUpdate();
this.derivedTableJoins = listHelper.getTableJoin();
boolean noRelationships = propertiesOne.length + propertiesMany.length == 0;
this.cacheSharableBeans = noRelationships && deploy.getCacheOptions().isReadOnly();
@@ -655,7 +648,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
/**
* Return true if this is an abstract type.
*/
public boolean isAbstractType() {
boolean isAbstractType() {
return abstractType;
}
@@ -689,7 +682,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
* as they are used to get the imported and exported properties.
* </p>
*/
public void initialiseId(BeanDescriptorInitContext initContext) {
void initialiseId(BeanDescriptorInitContext initContext) {
if (logger.isTraceEnabled()) {
logger.trace("BeanDescriptor initialise " + fullName);
@@ -783,7 +776,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
/**
* Perform last initialisation for the descriptor.
*/
public void initLast() {
void initLast() {
for (BeanProperty prop : propertiesNonTransient) {
if (prop.isUnique()) {
@@ -825,7 +818,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
* Initialise the document mapping.
*/
@SuppressWarnings("unchecked")
public void initialiseDocMapping() {
void initialiseDocMapping() {
for (BeanPropertyAssocMany<?> many : propertiesMany) {
many.initialisePostTarget();
}
@@ -840,7 +833,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
cacheHelp.deriveNotifyFlags();
}
public void initInheritInfo() {
void initInheritInfo() {
if (inheritInfo != null) {
// need to check every BeanDescriptor in the inheritance hierarchy
if (saveRecurseSkippable) {
@@ -894,7 +887,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
/**
* Return the ReadAuditPrepare for preparing read audit events prior to logging.
*/
public ReadAuditPrepare getReadAuditPrepare() {
private ReadAuditPrepare getReadAuditPrepare() {
return ebeanServer.getReadAuditPrepare();
}
@@ -980,7 +973,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
/**
* Populate the diff for inserts with flattened non-null property values.
*/
protected void jsonWriteForInsert(SpiJsonWriter jsonWriter, EntityBean newBean) throws IOException {
void jsonWriteForInsert(SpiJsonWriter jsonWriter, EntityBean newBean) throws IOException {
jsonWriter.writeStartObject();
for (BeanProperty prop : propertiesBaseScalar) {
prop.jsonWriteForInsert(jsonWriter, newBean);
@@ -1057,7 +1050,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
elDeployCache.put(fkey.getName(), fkey);
}
public void initialiseFkeys() {
void initialiseFkeys() {
for (BeanPropertyAssocOne<?> aPropertiesOneImported : propertiesOneImported) {
if (!aPropertiesOneImported.isFormula()) {
aPropertiesOneImported.addFkey();
@@ -1915,18 +1908,19 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
beanPostConstructListener.autowire(bean); // calls all registered listeners
beanPostConstructListener.postConstruct(bean); // calls first the @PostConstruct method and then the listeners
}
if (unloadProperties.length > 0) {
if (isNew) {
if (beanPostConstructListener != null) {
beanPostConstructListener.postCreate(bean);
// if bean is not new, postLoad will be executed later in the bean's lifecycle
}
// do not unload properties for new beans!
} else if (unloadProperties.length > 0) {
// 'unload' any properties initialised in the default constructor
EntityBeanIntercept ebi = bean._ebean_getIntercept();
for (int unloadProperty : unloadProperties) {
ebi.setPropertyUnloaded(unloadProperty);
}
}
if (beanPostConstructListener != null && isNew) {
beanPostConstructListener.postCreate(bean);
// if bean is not new, postLoad will be executed later in the bean's lifecycle
}
return bean;
} catch (Exception ex) {
@@ -2575,7 +2569,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType {
*/
private STreeProperty findSqlTreeFormula(String formula, String path) {
String key = formula + "-" + path;
return dynamicProperty.computeIfAbsent(key, (fullKey) -> new FormulaPropertyPath(this, formula, path).build());
return dynamicProperty.computeIfAbsent(key, (fullKey) -> FormulaPropertyPath.create(this, formula, path));
}
/**
@@ -908,13 +908,11 @@ final class BeanDescriptorCacheHelp<T> {
if (noCaching) {
return;
}
changeSet.addInvalidate(desc);
changeSet.addClearQuery(desc);
// inserts don't invalidate the bean cache
if (tableIUD.isUpdateOrDelete()) {
changeSet.addClearBean(desc);
}
// any change invalidates the query cache
changeSet.addClearQuery(desc);
// any change invalidates the collection IDs cache
for (BeanPropertyAssocOne<?> imported : propertiesOneImported) {
imported.cacheClear(changeSet);
@@ -39,7 +39,7 @@ public final class BeanDescriptorDraftHelp<T> {
}
}
return list.toArray(new BeanProperty[list.size()]);
return list.toArray(new BeanProperty[0]);
}
/**
@@ -815,7 +815,6 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
return new BeanTable(beanTable, this);
}
@SuppressWarnings({"unchecked", "rawtypes"})
private void readEntityRelationships() {
// We only perform 'circular' checks etc after we have
@@ -1650,7 +1649,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
return changeLogListener;
}
public void addPrimaryKeyJoin(DeployBeanPropertyAssocOne<?> prop) {
private void addPrimaryKeyJoin(DeployBeanPropertyAssocOne<?> prop) {
String baseTable = prop.getDesc().getBaseTable();
DeployTableJoin inverse = prop.getTableJoin().createInverse(baseTable);
@@ -142,7 +142,21 @@ class BeanLifecycleAdapterFactory {
* Utility method to covert List of Method into array (because we care about performance here).
*/
static Method[] toArray(List<Method> methodList) {
return methodList.toArray(new Method[methodList.size()]);
return methodList.toArray(new Method[0]);
}
static RuntimeException unwrapException(ReflectiveOperationException e) {
if (e instanceof InvocationTargetException) {
Throwable targetException = ((InvocationTargetException)e).getTargetException();
if (targetException instanceof RuntimeException) {
// return unchecked exceptions
return (RuntimeException) targetException;
} else {
// wrap checked exceptions
return new PersistenceException("Error invoking lifecycle method", targetException);
}
}
return new PersistenceException("Error invoking lifecycle method", e);
}
/**
@@ -192,7 +206,7 @@ class BeanLifecycleAdapterFactory {
try {
method.invoke(bean);
} catch (InvocationTargetException | IllegalAccessException e) {
throw new PersistenceException("Error invoking lifecycle method", e);
throw unwrapException(e);
}
}
@@ -268,7 +282,7 @@ class BeanLifecycleAdapterFactory {
try {
method.invoke(bean);
} catch (InvocationTargetException | IllegalAccessException e) {
throw new PersistenceException("Error invoking lifecycle method", e);
throw unwrapException(e);
}
}
@@ -301,7 +315,7 @@ class BeanLifecycleAdapterFactory {
try {
method.invoke(bean);
} catch (InvocationTargetException | IllegalAccessException e) {
throw new PersistenceException("Error invoking lifecycle method", e);
throw unwrapException(e);
}
}
@@ -107,6 +107,7 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
/**
* Copy constructor for ManyToOne inside Embeddable.
*/
@SuppressWarnings("unchecked")
public BeanPropertyAssoc(BeanPropertyAssoc source, BeanPropertyOverride override) {
super(source, override);
foreignKey = source.foreignKey;
@@ -79,7 +79,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
/**
* Descriptor for the 'target' when the property maps to an element collection.
*/
BeanDescriptor<T> elementDescriptor;
final BeanDescriptor<T> elementDescriptor;
/**
* Order by used when fetch joining the associated many.
@@ -683,7 +683,7 @@ public class BeanPropertyAssocMany<T> extends BeanPropertyAssoc<T> implements ST
}
}
return list.toArray(new ExportedProperty[list.size()]);
return list.toArray(new ExportedProperty[0]);
}
/**
@@ -23,6 +23,7 @@ import io.ebeaninternal.server.query.SqlBeanLoad;
import io.ebeaninternal.server.query.SqlJoinType;
import io.ebeaninternal.server.type.DataReader;
import io.ebeaninternal.server.type.ScalarDataReader;
import io.ebeaninternal.server.type.ScalarType;
import javax.persistence.PersistenceException;
import java.io.IOException;
@@ -465,6 +466,10 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
return targetDescriptor.getIdProperty();
}
public ScalarType getIdScalarType() {
return targetDescriptor.getIdProperty().scalarType;
}
/**
* Return the Id values from the given bean.
*/
@@ -577,7 +582,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
}
}
return list.toArray(new ExportedProperty[list.size()]);
return list.toArray(new ExportedProperty[0]);
}
/**
@@ -764,10 +769,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
writeJson.writeNullField(name);
} else {
if (writeJson.isParentBean(value)) {
// bi-directional and already rendered parent
} else {
if (!writeJson.isParentBean(value)) {
// Hmmm, not writing complex non-entity bean
if (value instanceof EntityBean) {
writeJson.beginAssocOne(name, bean);
@@ -8,6 +8,7 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
*/
public class BeanPropertyIdClass extends BeanPropertyAssocOne {
@SuppressWarnings("unchecked")
public BeanPropertyIdClass(BeanDescriptorMap owner, BeanDescriptor descriptor, DeployBeanPropertyAssocOne deploy) {
super(owner, descriptor, deploy);
}
@@ -44,7 +44,7 @@ public class ChainedBeanPersistController implements BeanPersistController {
*/
public ChainedBeanPersistController(List<BeanPersistController> list) {
this.list = list;
BeanPersistController[] c = list.toArray(new BeanPersistController[list.size()]);
BeanPersistController[] c = list.toArray(new BeanPersistController[0]);
Arrays.sort(c, SORTER);
this.chain = c;
}
@@ -185,7 +185,7 @@ public class ChainedBeanPersistController implements BeanPersistController {
int i1 = o1.getExecutionOrder();
int i2 = o2.getExecutionOrder();
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
return Integer.compare(i1, i2);
}
}
@@ -50,7 +50,7 @@ public class ChainedBeanPersistListener implements BeanPersistListener {
*/
public ChainedBeanPersistListener(List<BeanPersistListener> list) {
this.list = list;
this.chain = list.toArray(new BeanPersistListener[list.size()]);
this.chain = list.toArray(new BeanPersistListener[0]);
}
/**
@@ -19,7 +19,7 @@ public class ChainedBeanPostConstructListener implements BeanPostConstructListen
*/
public ChainedBeanPostConstructListener(List<BeanPostConstructListener> list) {
this.list = list;
this.chain = list.toArray(new BeanPostConstructListener[list.size()]);
this.chain = list.toArray(new BeanPostConstructListener[0]);
}
/**
@@ -19,7 +19,7 @@ public class ChainedBeanPostLoad implements BeanPostLoad {
*/
public ChainedBeanPostLoad(List<BeanPostLoad> list) {
this.list = list;
this.chain = list.toArray(new BeanPostLoad[list.size()]);
this.chain = list.toArray(new BeanPostLoad[0]);
}
/**
@@ -24,7 +24,7 @@ public class ChainedBeanQueryAdapter implements BeanQueryAdapter {
*/
public ChainedBeanQueryAdapter(List<BeanQueryAdapter> list) {
this.list = list;
BeanQueryAdapter[] c = list.toArray(new BeanQueryAdapter[list.size()]);
BeanQueryAdapter[] c = list.toArray(new BeanQueryAdapter[0]);
Arrays.sort(c, SORTER);
this.chain = c;
}
@@ -89,10 +89,7 @@ public class ChainedBeanQueryAdapter implements BeanQueryAdapter {
@Override
public int compare(BeanQueryAdapter o1, BeanQueryAdapter o2) {
int i1 = o1.getExecutionOrder();
int i2 = o2.getExecutionOrder();
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
return Integer.compare(o1.getExecutionOrder(), o2.getExecutionOrder());
}
}
@@ -4,7 +4,7 @@ import io.ebeaninternal.api.SpiCacheRegion;
class DCacheRegionNone implements SpiCacheRegion {
static SpiCacheRegion INSTANCE = new DCacheRegionNone();
static final SpiCacheRegion INSTANCE = new DCacheRegionNone();
@Override
public String getName() {
@@ -31,13 +31,7 @@ public class DeployPropertyParserMap extends DeployParser {
@Override
public String getDeployWord(String expression) {
String deployExpr = map.get(expression);
if (deployExpr == null) {
return null;
} else {
return deployExpr;
}
return map.get(expression);
}
}
@@ -27,17 +27,19 @@ public final class DeployUpdateParser extends DeployParser {
public String convertWord() {
String dbWord = getDeployWord(word);
if (dbWord != null) {
return dbWord;
}
// maybe tableAlias.propertyName
return convertSubword(0, word, null);
return convertSubword(word);
}
private String convertSubword(int start, String currentWord, StringBuilder localBuffer) {
while (true) {
private String convertSubword(String currentWord) {
int start = 0;
StringBuilder localBuffer = null;
while (true) {
int dotPos = currentWord.indexOf('.', start);
if (start == 0 && dotPos == -1) {
return currentWord;
@@ -63,15 +65,11 @@ public final class DeployUpdateParser extends DeployParser {
start = dotPos + 1;
String remainder = currentWord.substring(start, currentWord.length());
//String dbWord = deployMap.get(remainder.toLowerCase());
String dbWord = getDeployWord(remainder);
if (dbWord != null) {
// we have found a match for the remainder
localBuffer.append(dbWord);
return localBuffer.toString();
} else {
//
}
}
}
@@ -84,11 +82,7 @@ public final class DeployUpdateParser extends DeployParser {
}
ElPropertyDeploy elProp = beanDescriptor.getElPropertyDeploy(expression);
if (elProp != null) {
return elProp.getDbColumn();
} else {
return null;
}
return elProp != null ? elProp.getDbColumn() : null;
}
}
@@ -16,7 +16,7 @@ class DetermineAggPath {
// a top level aggregation (so here we need to exclude Id property)
return null;
}
return path.getManyPath(0, desc);
return path.getManyPath(desc);
}
static Path paths(String aggregation) {
@@ -82,9 +82,9 @@ class DetermineAggPath {
}
}
String getManyPath(int pos, DeployBeanDescriptor<?> desc) {
String getManyPath(DeployBeanDescriptor<?> desc) {
int pos = 0;
while (true) {
String path = paths[pos];
DeployBeanProperty details = desc.getBeanProperty(path);
if (details instanceof DeployBeanPropertyAssocMany<?>) {
@@ -92,8 +92,7 @@ class DetermineAggPath {
} else if (details instanceof DeployBeanPropertyAssocOne<?>) {
DeployBeanPropertyAssocOne<?> one = (DeployBeanPropertyAssocOne<?>) details;
DeployBeanDescriptor<?> targetDesc = one.getTargetDeploy();
desc = targetDesc;
desc = one.getTargetDeploy();
pos = pos + 1;
continue;
}
@@ -16,7 +16,7 @@ class DynamicPropertyAggregationFormula extends DynamicPropertyBase {
private final boolean aggregate;
private final BeanProperty asTarget;
final BeanProperty asTarget;
private final String alias;
@@ -0,0 +1,33 @@
package io.ebeaninternal.server.deploy;
import io.ebeaninternal.server.query.SqlBeanLoad;
public class DynamicPropertyAggregationFormulaMTO extends DynamicPropertyAggregationFormula {
private final BeanPropertyAssocOne prop;
DynamicPropertyAggregationFormulaMTO(BeanPropertyAssocOne prop, String name, String parsedFormula, boolean aggregate, BeanProperty asTarget, String alias) {
super(name, prop.getIdScalarType(), parsedFormula, aggregate, asTarget, alias);
this.prop = prop;
}
@Override
public boolean isAggregationManyToOne() {
return true;
}
@Override
public void load(SqlBeanLoad sqlBeanLoad) {
Object value;
try {
value = prop.read(sqlBeanLoad.ctx());
} catch (Exception e) {
sqlBeanLoad.ctx().handleLoadError(fullName, e);
return;
}
if (asTarget != null) {
sqlBeanLoad.load(asTarget, value);
}
}
}
@@ -11,7 +11,7 @@ class ElementEntityBean implements EntityBean {
private Object[] data;
private EntityBeanIntercept intercept;
private final EntityBeanIntercept intercept;
ElementEntityBean(String[] properties) {
this.properties = properties;
@@ -15,7 +15,7 @@ class ElementHelpList implements ElementHelp {
private static class Collector implements ElementCollector {
private List<Object> list = new ArrayList<>();
private final List<Object> list = new ArrayList<>();
@Override
public void addElement(Object element) {
@@ -15,7 +15,7 @@ class ElementHelpMap implements ElementHelp {
private static class Collector implements ElementCollector {
private Map<Object, Object> map = new LinkedHashMap<>();
private final Map<Object, Object> map = new LinkedHashMap<>();
@Override
public void addElement(Object element) {
@@ -15,7 +15,7 @@ class ElementHelpSet implements ElementHelp {
private static class Collector implements ElementCollector {
private Set<Object> set = new LinkedHashSet<>();
private final Set<Object> set = new LinkedHashSet<>();
@Override
public void addElement(Object element) {
@@ -6,7 +6,7 @@ import io.ebeaninternal.server.type.ScalarType;
import java.sql.Types;
class FormulaPropertyPath {
final class FormulaPropertyPath {
private static final String[] AGG_FUNCTIONS = {"count", "max", "min", "avg", "sum"};
@@ -20,17 +20,22 @@ class FormulaPropertyPath {
private final String internalExpression;
private final String path;
private final ElPropertyDeploy firstProp;
private final String parsedAggregation;
private boolean countDistinct;
private String cast;
private String alias;
static STreeProperty create(BeanDescriptor<?> descriptor, String formula, String path) {
return new FormulaPropertyPath(descriptor, formula, path).build();
}
FormulaPropertyPath(BeanDescriptor<?> descriptor, String formula, String path) {
this.descriptor = descriptor;
this.formula = formula;
this.path = path;
int openBracket = formula.indexOf('(');
int closeBracket = formula.lastIndexOf(')');
@@ -38,13 +43,21 @@ class FormulaPropertyPath {
throw new IllegalStateException("Unable to parse formula [" + formula + "]");
}
outerFunction = formula.substring(0, openBracket).trim();
internalExpression = trimDistinct(formula.substring(openBracket+1, closeBracket));
internalExpression = trimDistinct(formula.substring(openBracket + 1, closeBracket));
if (closeBracket < formula.length() -1) {
if (closeBracket < formula.length() - 1) {
// ::CastType as foo
String suffix = formula.substring(closeBracket+1).trim();
parseSuffix(suffix);
parseSuffix(formula.substring(closeBracket + 1).trim());
}
DeployPropertyParser parser = descriptor.parser().setCatchFirst(true);
String parsed = parser.parse(internalExpression);
if (path != null) {
// fetch("machineStats", "sum(hours), sum(totalKms)")
parsed = parsed.replace("${}", "${" + path + "}");
}
this.parsedAggregation = buildFormula(parsed);
this.firstProp = parser.getFirstProp();
}
private void parseSuffix(String suffix) {
@@ -93,42 +106,50 @@ class FormulaPropertyPath {
STreeProperty build() {
DeployPropertyParser parser = descriptor.parser().setCatchFirst(true);
String parsed = parser.parse(internalExpression);
if (path != null) {
// fetch("machineStats", "sum(hours), sum(totalKms)")
parsed = parsed.replace("${}", "${" + path + "}");
}
ElPropertyDeploy firstProp = parser.getFirstProp();
ScalarType<?> scalarType;
if (cast != null) {
scalarType = descriptor.getScalarType(cast);
ScalarType<?> scalarType = descriptor.getScalarType(cast);
if (scalarType == null) {
throw new IllegalStateException("Unable to find scalarType for cast of ["+cast+"] on formula [" + formula + "] for type " + descriptor);
}
} else if (isCount()) {
scalarType = descriptor.getScalarType(Types.BIGINT);
} else if (isConcat()) {
scalarType = descriptor.getScalarType(Types.VARCHAR);
} else {
// determine scalarType based on first property found by parser
if (firstProp != null) {
scalarType = firstProp.getBeanProperty().getScalarType();
} else {
throw new IllegalStateException("unable to determine scalarType of formula [" + formula + "] for type " + descriptor + " - maybe use a cast like ::String ?");
throw new IllegalStateException("Unable to find scalarType for cast of [" + cast + "] on formula [" + formula + "] for type " + descriptor);
}
return create(scalarType);
}
if (isCount()) {
return create(descriptor.getScalarType(Types.BIGINT));
}
if (isConcat()) {
return create(descriptor.getScalarType(Types.VARCHAR));
}
if (firstProp == null) {
throw new IllegalStateException("unable to determine scalarType of formula [" + formula + "] for type " + descriptor + " - maybe use a cast like ::String ?");
}
String logicalName = (alias == null) ? internalExpression : alias;
BeanProperty targetProperty = descriptor._findBeanProperty(logicalName);
String parsedAggregation = buildFormula(parsed);
return new DynamicPropertyAggregationFormula(logicalName, scalarType, parsedAggregation, isAggregate(), targetProperty, alias);
// determine scalarType based on first property found by parser
final BeanProperty property = firstProp.getBeanProperty();
if (!property.isAssocId()) {
return create(property.getScalarType());
} else {
return createManyToOne(property);
}
}
private DynamicPropertyAggregationFormula create(ScalarType<?> scalarType) {
String logicalName = logicalName();
return new DynamicPropertyAggregationFormula(logicalName, scalarType, parsedAggregation, isAggregate(), target(logicalName), alias);
}
private DynamicPropertyAggregationFormula createManyToOne(BeanProperty property) {
String logicalName = logicalName();
return new DynamicPropertyAggregationFormulaMTO((BeanPropertyAssocOne) property, logicalName, parsedAggregation, isAggregate(), target(logicalName), alias);
}
private BeanProperty target(String logicalName) {
return descriptor._findBeanProperty(logicalName);
}
private String logicalName() {
return (alias == null) ? internalExpression : alias;
}
private boolean isAggregate() {
@@ -346,19 +346,20 @@ public final class IdBinderEmbedded implements IdBinder {
public Object read(DbReadContext ctx) throws SQLException {
EntityBean embId = idDesc.createEntityBean();
boolean notNull = true;
boolean nullValue = true;
for (BeanProperty prop : props) {
Object value = prop.readSet(ctx, embId);
if (value == null) {
notNull = false;
Object value = prop.read(ctx);
if (value != null) {
prop.setValue(embId, value);
nullValue = false;
}
}
if (notNull) {
return embId;
} else {
if (nullValue) {
return null;
} else {
return embId;
}
}
@@ -78,7 +78,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
*/
public static ImportedIdSimple[] sort(List<ImportedIdSimple> list) {
ImportedIdSimple[] importedIds = list.toArray(new ImportedIdSimple[list.size()]);
ImportedIdSimple[] importedIds = list.toArray(new ImportedIdSimple[0]);
// sort into the same order as the BeanProperties
Arrays.sort(importedIds, COMPARATOR);
@@ -100,7 +100,7 @@ public final class ImportedIdSimple implements ImportedId, Comparable<ImportedId
@Override
public int compareTo(ImportedIdSimple other) {
return (position < other.position ? -1 : (position == other.position ? 0 : 1));
return Integer.compare(position, other.position);
}
@Override
@@ -561,7 +561,7 @@ public class DeployBeanDescriptor<T> {
if (indexDefinitions == null) {
return null;
} else {
return indexDefinitions.toArray(new IndexDefinition[indexDefinitions.size()]);
return indexDefinitions.toArray(new IndexDefinition[0]);
}
}
@@ -1267,6 +1267,7 @@ public class DeployBeanDescriptor<T> {
/**
* Returns the jackson annotated class, if jackson is present.
*/
@SuppressWarnings("unchecked")
public Object /*AnnotatedClass*/ getJacksonAnnotatedClass() {
if (jacksonAnnotatedClass == null) {
jacksonAnnotatedClass = new DeployBeanObtainJackson(serverConfig, beanType).obtain();
@@ -249,7 +249,7 @@ public class DeployBeanProperty {
/**
* Wrap the ScalarType using a ScalarTypeConverter.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({"unchecked"})
private ScalarType<?> wrapScalarType(Class<?> propertyType, ScalarType<?> scalarType, ScalarTypeConverter<?, ?> typeConverter) {
if (typeConverter == null) {
return scalarType;
@@ -71,7 +71,7 @@ public class DeployBeanPropertyLists {
private final BeanPropertyAssocOne<?> unidirectional;
private final BeanProperty orderColumn;
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({"unchecked"})
public DeployBeanPropertyLists(BeanDescriptorMap owner, BeanDescriptor<?> desc, DeployBeanDescriptor<?> deploy) {
this.desc = desc;
@@ -284,7 +284,7 @@ public class DeployBeanPropertyLists {
* properties).
*/
public BeanProperty[] getBaseScalar() {
return baseScalar.toArray(new BeanProperty[baseScalar.size()]);
return baseScalar.toArray(new BeanProperty[0]);
}
public BeanProperty getId() {
@@ -292,11 +292,11 @@ public class DeployBeanPropertyLists {
}
public BeanProperty[] getNonTransients() {
return nonTransients.toArray(new BeanProperty[nonTransients.size()]);
return nonTransients.toArray(new BeanProperty[0]);
}
public BeanProperty[] getTransients() {
return transients.toArray(new BeanProperty[transients.size()]);
return transients.toArray(new BeanProperty[0]);
}
public BeanProperty getVersionProperty() {
@@ -304,23 +304,23 @@ public class DeployBeanPropertyLists {
}
public BeanProperty[] getLocal() {
return local.toArray(new BeanProperty[local.size()]);
return local.toArray(new BeanProperty[0]);
}
public BeanProperty[] getMutable() {
return mutable.toArray(new BeanProperty[mutable.size()]);
return mutable.toArray(new BeanProperty[0]);
}
public BeanPropertyAssocOne<?>[] getEmbedded() {
return embedded.toArray(new BeanPropertyAssocOne[embedded.size()]);
return embedded.toArray(new BeanPropertyAssocOne[0]);
}
public BeanPropertyAssocOne<?>[] getOneImported() {
return onesImported.toArray(new BeanPropertyAssocOne[onesImported.size()]);
return onesImported.toArray(new BeanPropertyAssocOne[0]);
}
public BeanPropertyAssocOne<?>[] getOnes() {
return ones.toArray(new BeanPropertyAssocOne[ones.size()]);
return ones.toArray(new BeanPropertyAssocOne[0]);
}
public BeanPropertyAssocOne<?>[] getOneExportedSave() {
@@ -340,11 +340,11 @@ public class DeployBeanPropertyLists {
}
public BeanProperty[] getNonMany() {
return nonManys.toArray(new BeanProperty[nonManys.size()]);
return nonManys.toArray(new BeanProperty[0]);
}
public BeanPropertyAssocMany<?>[] getMany() {
return manys.toArray(new BeanPropertyAssocMany[manys.size()]);
return manys.toArray(new BeanPropertyAssocMany[0]);
}
public BeanPropertyAssocMany<?>[] getManySave() {
@@ -397,7 +397,7 @@ public class DeployBeanPropertyLists {
list.add(prop);
}
}
return list.toArray(new BeanProperty[list.size()]);
return list.toArray(new BeanProperty[0]);
}
/**
@@ -412,7 +412,7 @@ public class DeployBeanPropertyLists {
list.add(prop);
}
}
return list.toArray(new BeanProperty[list.size()]);
return list.toArray(new BeanProperty[0]);
}
/**
@@ -443,7 +443,7 @@ public class DeployBeanPropertyLists {
}
}
return (BeanPropertyAssocOne[]) list.toArray(new BeanPropertyAssocOne[list.size()]);
return (BeanPropertyAssocOne[]) list.toArray(new BeanPropertyAssocOne[0]);
}
private BeanPropertyAssocMany<?>[] getMany2Many() {
@@ -454,7 +454,7 @@ public class DeployBeanPropertyLists {
}
}
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[0]);
}
private BeanPropertyAssocMany<?>[] getMany(Mode mode) {
@@ -476,7 +476,7 @@ public class DeployBeanPropertyLists {
}
}
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[list.size()]);
return (BeanPropertyAssocMany[]) list.toArray(new BeanPropertyAssocMany[0]);
}
@SuppressWarnings({"unchecked", "rawtypes"})

Some files were not shown because too many files have changed in this diff Show More