mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
92
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5d9a897ae | ||
|
|
ddf200ffdd | ||
|
|
7fa5e2aa8c | ||
|
|
8bfae9deef | ||
|
|
e6c9f151c1 | ||
|
|
30a0935300 | ||
|
|
b4182d4519 | ||
|
|
93cc0399f1 | ||
|
|
5404dab5a3 | ||
|
|
d70da1d805 | ||
|
|
2225d5b7e8 | ||
|
|
270369bd65 | ||
|
|
a932d61a94 | ||
|
|
24b08663af | ||
|
|
bb6c9c84ba | ||
|
|
a1e185b0f6 | ||
|
|
e2a467ca5a | ||
|
|
4b28933298 | ||
|
|
6077acf134 | ||
|
|
8a4ffd21ab | ||
|
|
d1314124af | ||
|
|
36f018b6aa | ||
|
|
87ccb6e333 | ||
|
|
3432c365f6 | ||
|
|
b7d5aa344f | ||
|
|
7e768623e4 | ||
|
|
73ab2ee1fe | ||
|
|
122fed448c | ||
|
|
6e52bee91f | ||
|
|
cc26afad13 | ||
|
|
bf20449fb5 | ||
|
|
6af5fae8e9 | ||
|
|
e26a38ecaa | ||
|
|
1cdf68f1c0 | ||
|
|
2923dd1d96 | ||
|
|
9067508e1d | ||
|
|
385cc76e34 | ||
|
|
c14cb4b85e | ||
|
|
52644647e4 | ||
|
|
3bf9dd6743 | ||
|
|
aececa2199 | ||
|
|
b4e22a4ca7 | ||
|
|
9b8b4414c4 | ||
|
|
b8fd2c7a02 | ||
|
|
a94f5d74ca | ||
|
|
3829613c37 | ||
|
|
0762eaf0ab | ||
|
|
7fbdab6220 | ||
|
|
cf4d45befb | ||
|
|
dcd81a857d | ||
|
|
0cac723eac | ||
|
|
c6ba4d8155 | ||
|
|
201958f38c | ||
|
|
9326c9c79e | ||
|
|
1042fdb280 | ||
|
|
197056dbc5 | ||
|
|
895b5ee4ff | ||
|
|
c839fe6520 | ||
|
|
2678f85506 | ||
|
|
2b1b4af7a2 | ||
|
|
4218b8a2e8 | ||
|
|
fe7d73a4a4 | ||
|
|
81e86b07e3 | ||
|
|
910c04e373 | ||
|
|
205f1f5e89 | ||
|
|
a1a6d2b725 | ||
|
|
30da589ea0 | ||
|
|
c66e9547e1 | ||
|
|
73990e3fb7 | ||
|
|
f7920de3c2 | ||
|
|
3dd5069f5a | ||
|
|
1d363776ec | ||
|
|
c512eb564d | ||
|
|
7f332e91ff | ||
|
|
8e9d644bc6 | ||
|
|
fa5ce9cbba | ||
|
|
b7905daeb5 | ||
|
|
9da7c9468e | ||
|
|
9eee224e03 | ||
|
|
906d5f04ad | ||
|
|
654c3f7f67 | ||
|
|
c61e6b04a2 | ||
|
|
f893653090 | ||
|
|
579c1efcf6 | ||
|
|
662f9cdeb3 | ||
|
|
b4782425f8 | ||
|
|
2648423930 | ||
|
|
b62cea5073 | ||
|
|
c10ad11b8b | ||
|
|
4aa8a0dc63 | ||
|
|
e4569f9362 | ||
|
|
ed83bababc |
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
custom: https://ebean.io/sponsors
|
||||
@@ -3,6 +3,7 @@ sudo: required
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- openjdk11
|
||||
|
||||
git:
|
||||
depth: 3
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+33
@@ -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
Reference in New Issue
Block a user