mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d432854b82 | ||
|
|
93582c8ea3 | ||
|
|
520d35b1d6 | ||
|
|
8ca3599cbf | ||
|
|
283ae74219 | ||
|
|
cebd3f92a4 | ||
|
|
4b2481d3ea | ||
|
|
f1f2a416d3 | ||
|
|
74dd97a55f | ||
|
|
3f04f7f363 | ||
|
|
800f854a12 | ||
|
|
bef9e6d54f | ||
|
|
0e4c0ae6c3 | ||
|
|
a0ea9887df | ||
|
|
0413c22e6e | ||
|
|
989ae44a6d | ||
|
|
100d314e63 | ||
|
|
dbf4e99187 | ||
|
|
7b8a85106c | ||
|
|
58c5f01e2b | ||
|
|
bc74d35651 | ||
|
|
a1f95bf25e | ||
|
|
c454e1f8a7 | ||
|
|
5a3669e1db | ||
|
|
7a2e0b3695 | ||
|
|
ce6d6269cd | ||
|
|
7d800b7080 | ||
|
|
136154e247 |
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>10.3.1</version>
|
||||
<version>10.3.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>ebean</name>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-10.3.1</tag>
|
||||
<tag>ebean-10.3.2</tag>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
@@ -67,7 +67,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-dbmigration</artifactId>
|
||||
<version>10.1.8</version>
|
||||
<version>10.1.9</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -130,7 +130,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4.1212.jre7</version>
|
||||
<version>9.4.1212</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-agent</artifactId>
|
||||
<version>10.1.7</version>
|
||||
<version>10.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
<plugin>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-maven-plugin</artifactId>
|
||||
<version>10.1.7</version>
|
||||
<version>10.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>test</id>
|
||||
|
||||
@@ -10,6 +10,7 @@ import javax.persistence.PessimisticLockException;
|
||||
* </p>
|
||||
*/
|
||||
public class AcquireLockException extends PessimisticLockException {
|
||||
private static final long serialVersionUID = -8585962352965876691L;
|
||||
|
||||
/**
|
||||
* Create with a message and cause.
|
||||
|
||||
@@ -6,6 +6,7 @@ import javax.persistence.PersistenceException;
|
||||
* Thrown when a foreign key constraint is enforced.
|
||||
*/
|
||||
public class DataIntegrityException extends PersistenceException {
|
||||
private static final long serialVersionUID = -6740171949170180970L;
|
||||
|
||||
/**
|
||||
* Create with a message and cause.
|
||||
|
||||
@@ -4,6 +4,7 @@ package io.ebean;
|
||||
* Thrown when a duplicate is attempted on a unique constraint.
|
||||
*/
|
||||
public class DuplicateKeyException extends DataIntegrityException {
|
||||
private static final long serialVersionUID = -4771932723285724817L;
|
||||
|
||||
/**
|
||||
* Create with a message and cause.
|
||||
|
||||
@@ -7,7 +7,6 @@ import io.ebean.search.TextQueryString;
|
||||
import io.ebean.search.TextSimple;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -308,9 +307,9 @@ public interface ExpressionFactory {
|
||||
Expression idIn(Object... idValues);
|
||||
|
||||
/**
|
||||
* Id IN a list of Id values.
|
||||
* Id IN a collection of Id values.
|
||||
*/
|
||||
Expression idIn(List<?> idList);
|
||||
Expression idIn(Collection<?> idCollection);
|
||||
|
||||
/**
|
||||
* All Equal - Map containing property names and their values.
|
||||
|
||||
@@ -836,9 +836,9 @@ public interface ExpressionList<T> {
|
||||
ExpressionList<T> idIn(Object... idValues);
|
||||
|
||||
/**
|
||||
* Id IN a list of id values.
|
||||
* Id IN a collection of id values.
|
||||
*/
|
||||
ExpressionList<T> idIn(List<?> idValues);
|
||||
ExpressionList<T> idIn(Collection<?> idValues);
|
||||
|
||||
/**
|
||||
* Id Equal to - ID property is equal to the value.
|
||||
|
||||
@@ -6,22 +6,22 @@ package io.ebean;
|
||||
public enum LikeType {
|
||||
|
||||
/**
|
||||
* You need to put in your own wildcards.
|
||||
* You need to put in your own wildcards - no escaping is performed.
|
||||
*/
|
||||
RAW,
|
||||
|
||||
/**
|
||||
* The % wildcard is added to the end of the search word.
|
||||
* The % wildcard is added to the end of the search word and search word is escaped.
|
||||
*/
|
||||
STARTS_WITH,
|
||||
|
||||
/**
|
||||
* The % wildcard is added to the beginning of the search word.
|
||||
* The % wildcard is added to the beginning of the search word and search word is escaped.
|
||||
*/
|
||||
ENDS_WITH,
|
||||
|
||||
/**
|
||||
* The % wildcard is added to the beginning and end of the search word.
|
||||
* The % wildcard is added to the beginning and end of the search word and search word is escaped.
|
||||
*/
|
||||
CONTAINS,
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ public interface Transaction extends AutoCloseable {
|
||||
/**
|
||||
* Synonym for end() to support AutoClosable.
|
||||
*/
|
||||
@Override
|
||||
void close();
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,8 +47,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
protected ModifyHolder<E> modifyHolder;
|
||||
|
||||
protected ModifyListenMode modifyListenMode;
|
||||
protected boolean modifyAddListening;
|
||||
protected boolean modifyRemoveListening;
|
||||
|
||||
protected boolean modifyListening;
|
||||
|
||||
/**
|
||||
@@ -148,9 +147,7 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
public void setModifyListening(ModifyListenMode mode) {
|
||||
|
||||
this.modifyListenMode = mode;
|
||||
this.modifyAddListening = ModifyListenMode.ALL.equals(mode);
|
||||
this.modifyRemoveListening = modifyAddListening || ModifyListenMode.REMOVALS.equals(mode);
|
||||
this.modifyListening = modifyRemoveListening || modifyAddListening;
|
||||
this.modifyListening = mode != null && ModifyListenMode.NONE != mode;
|
||||
if (modifyListening) {
|
||||
// lose any existing modifications
|
||||
modifyHolder = null;
|
||||
@@ -173,14 +170,14 @@ abstract class AbstractBeanCollection<E> implements BeanCollection<E> {
|
||||
|
||||
@Override
|
||||
public void modifyAddition(E bean) {
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
getModifyHolder().modifyAddition(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyRemoval(Object bean) {
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
getModifyHolder().modifyRemoval(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public void add(int index, E element) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
modifyAddition(element);
|
||||
}
|
||||
list.add(index, element);
|
||||
@@ -247,7 +247,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean add(E o) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
if (list.add(o)) {
|
||||
modifyAddition(o);
|
||||
return true;
|
||||
@@ -262,7 +262,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
// all elements in c are added (no contains checking)
|
||||
getModifyHolder().modifyAdditionAll(c);
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
// all elements in c are added (no contains checking)
|
||||
getModifyHolder().modifyAdditionAll(c);
|
||||
}
|
||||
@@ -286,7 +286,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
// TODO: when clear() and not initialised could be more clever
|
||||
// and fetch just the Id's
|
||||
initClear();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
for (E aList : list) {
|
||||
getModifyHolder().modifyRemoval(aList);
|
||||
}
|
||||
@@ -380,7 +380,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public E remove(int index) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
E o = list.remove(index);
|
||||
modifyRemoval(o);
|
||||
return o;
|
||||
@@ -392,7 +392,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean remove(Object o) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
boolean isRemove = list.remove(o);
|
||||
if (isRemove) {
|
||||
modifyRemoval(o);
|
||||
@@ -406,7 +406,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean removeAll(Collection<?> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
for (Object bean : beans) {
|
||||
if (list.remove(bean)) {
|
||||
@@ -424,7 +424,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
public boolean retainAll(Collection<?> retainBeans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
Iterator<E> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
|
||||
@@ -211,7 +211,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
public void clear() {
|
||||
checkReadOnly();
|
||||
initClear();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
// add all beans to the removal list
|
||||
for (E bean : map.values()) {
|
||||
modifyRemoval(bean);
|
||||
@@ -313,7 +313,7 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
public E remove(Object key) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
E o = map.remove(key);
|
||||
modifyRemoval(o);
|
||||
return o;
|
||||
|
||||
@@ -210,7 +210,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public boolean add(E o) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
if (set.add(o)) {
|
||||
modifyAddition(o);
|
||||
return true;
|
||||
@@ -225,7 +225,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public boolean addAll(Collection<? extends E> addCollection) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyAddListening) {
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
for (E bean : addCollection) {
|
||||
if (set.add(bean)) {
|
||||
@@ -243,7 +243,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public void clear() {
|
||||
checkReadOnly();
|
||||
initClear();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
for (E bean : set) {
|
||||
modifyRemoval(bean);
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public boolean remove(Object o) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
if (set.remove(o)) {
|
||||
modifyRemoval(o);
|
||||
return true;
|
||||
@@ -299,7 +299,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public boolean removeAll(Collection<?> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
for (Object bean : beans) {
|
||||
if (set.remove(bean)) {
|
||||
@@ -316,7 +316,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
public boolean retainAll(Collection<?> beans) {
|
||||
checkReadOnly();
|
||||
init();
|
||||
if (modifyRemoveListening) {
|
||||
if (modifyListening) {
|
||||
boolean changed = false;
|
||||
Iterator<?> it = set.iterator();
|
||||
while (it.hasNext()) {
|
||||
|
||||
@@ -44,21 +44,29 @@ class ModifyHolder<E> implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean undoDeletion(E bean) {
|
||||
return (bean != null) && modifyDeletions.remove(bean);
|
||||
}
|
||||
|
||||
void modifyAddition(E bean) {
|
||||
if (bean != null) {
|
||||
// If it is to delete then just remove the deletion
|
||||
if (!modifyDeletions.remove(bean)) {
|
||||
if (!undoDeletion(bean)) {
|
||||
// Insert
|
||||
modifyAdditions.add(bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean undoAddition(Object bean) {
|
||||
return (bean != null) && modifyAdditions.remove(bean);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void modifyRemoval(Object bean) {
|
||||
if (bean != null) {
|
||||
// If it is to be added then just remove the addition
|
||||
if (!modifyAdditions.remove(bean)) {
|
||||
if (!undoAddition(bean)) {
|
||||
modifyDeletions.add((E) bean);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Configuration for the DB migration processing.
|
||||
@@ -443,7 +444,7 @@ public class DbMigrationConfig {
|
||||
/**
|
||||
* Create the MigrationRunner to run migrations if necessary.
|
||||
*/
|
||||
public MigrationRunner createRunner(ClassLoader classLoader) {
|
||||
public MigrationRunner createRunner(ClassLoader classLoader, Properties properties) {
|
||||
|
||||
MigrationConfig runnerConfig = new MigrationConfig();
|
||||
runnerConfig.setMetaTable(metaTable);
|
||||
@@ -454,6 +455,9 @@ public class DbMigrationConfig {
|
||||
runnerConfig.setDbUsername(getDbUsername());
|
||||
runnerConfig.setDbPassword(getDbPassword());
|
||||
runnerConfig.setClassLoader(classLoader);
|
||||
if (properties != null) {
|
||||
runnerConfig.load(properties);
|
||||
}
|
||||
return new MigrationRunner(runnerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
package io.ebean.config;
|
||||
|
||||
/**
|
||||
* Matches the functionality of javax.persistence.AttributeConverter
|
||||
* <p>
|
||||
* In general AttributeConverter should be used in preference to this
|
||||
* ScalarTypeConverter as it is JPA standard and offers the same functionality.
|
||||
* </p>
|
||||
* <p>
|
||||
* For Ebean we will look to deprecate this interface in preference to AttributeConverter.
|
||||
* </p>
|
||||
* <p>
|
||||
* Used to convert between a value object and a known scalar type. The value
|
||||
* object is the logical type used in your application and the scalar type is
|
||||
* the value used to persist than to the DB.
|
||||
* </p>
|
||||
* <p>
|
||||
* The Value object should be immutable and scalar (aka not compound) and
|
||||
* converts to and from a known scalar type which Ebean will use to persist the
|
||||
* value.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is an easier alternative to implementing the
|
||||
* io.ebean.server.type.ScalarType interface.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that Ebean will automatically try to detect Immutable Scalar Value
|
||||
* Objects and automatically support them via reflection. This however would not
|
||||
* be appropriate when the logical type is different from the type you wish to
|
||||
* use for persistence - for example, if the logical type was long and you
|
||||
* wanted to use java.sql.Timestamp for persistence. In this case you would want
|
||||
* to implement this interface rather than let Ebean automatically support that
|
||||
* type via reflection.
|
||||
* </p>
|
||||
*
|
||||
* @param <B> The value object type.
|
||||
* @param <S> The scalar object type that is used to persist the value object.
|
||||
|
||||
@@ -2755,7 +2755,7 @@ public class ServerConfig {
|
||||
*/
|
||||
public DataSource runDbMigration(DataSource dataSource) {
|
||||
if (migrationConfig.isRunMigration()) {
|
||||
MigrationRunner runner = migrationConfig.createRunner(getClassLoadConfig().getClassLoader());
|
||||
MigrationRunner runner = migrationConfig.createRunner(getClassLoadConfig().getClassLoader(), properties);
|
||||
runner.run(dataSource);
|
||||
}
|
||||
return dataSource;
|
||||
|
||||
@@ -174,6 +174,8 @@ public class DatabasePlatform {
|
||||
protected boolean supportsNativeIlike;
|
||||
|
||||
protected SqlExceptionTranslator exceptionTranslator = new SqlCodeTranslator();
|
||||
|
||||
protected char[] specialLikeCharacters = { '%', '_' };
|
||||
|
||||
/**
|
||||
* Instantiates a new database platform.
|
||||
@@ -617,4 +619,37 @@ public class DatabasePlatform {
|
||||
logger.error("Error closing resultSet", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the like string for this DB-Platform
|
||||
*/
|
||||
public String escapeLikeString(String value) {
|
||||
StringBuilder sb = null;
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char ch = value.charAt(i);
|
||||
boolean escaped = false;
|
||||
for (char escapeChar: specialLikeCharacters) {
|
||||
if (ch == escapeChar) {
|
||||
if (sb == null) {
|
||||
sb = new StringBuilder(value.substring(0, i));
|
||||
}
|
||||
escapeLikeCharacter(escapeChar, sb);
|
||||
escaped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!escaped && sb != null) {
|
||||
sb.append(ch);
|
||||
}
|
||||
}
|
||||
if (sb == null) {
|
||||
return value;
|
||||
} else {
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
protected void escapeLikeCharacter(char ch, StringBuilder sb) {
|
||||
sb.append('\\').append(ch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,10 +40,6 @@ public class H2Platform extends DatabasePlatform {
|
||||
this.dbIdentity.setSupportsSequence(true);
|
||||
this.dbIdentity.setSupportsIdentity(true);
|
||||
|
||||
// like ? escape'' not working in the latest version H2 so just using no
|
||||
// escape clause for now noting that backslash is an escape char for like in H2
|
||||
this.likeClause = "like ?";
|
||||
|
||||
dbTypeMap.put(DbType.UUID, new DbPlatformType("uuid", false));
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
super();
|
||||
this.platform = Platform.MYSQL;
|
||||
this.useExtraTransactionOnIterateSecondaryQueries = true;
|
||||
this.likeClause = "like ? escape''";
|
||||
this.selectCountWithAlias = true;
|
||||
this.dbEncrypt = new MySqlDbEncrypt();
|
||||
this.platformDdl = new MySqlDdl(this);
|
||||
|
||||
@@ -28,7 +28,6 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
super();
|
||||
this.platform = Platform.POSTGRES;
|
||||
this.supportsNativeIlike = true;
|
||||
this.likeClause = "like ? escape''";
|
||||
this.selectCountWithAlias = true;
|
||||
this.blobDbType = Types.LONGVARBINARY;
|
||||
this.clobDbType = Types.VARCHAR;
|
||||
|
||||
@@ -41,6 +41,8 @@ public class SqlServerPlatform extends DatabasePlatform {
|
||||
|
||||
this.openQuote = "[";
|
||||
this.closeQuote = "]";
|
||||
this.specialLikeCharacters = new char[] { '%', '_', '[' };
|
||||
this.likeClause = "like ? COLLATE Latin1_General_BIN";
|
||||
|
||||
booleanDbType = Types.INTEGER;
|
||||
dbTypeMap.put(DbType.BOOLEAN, new DbPlatformType("bit default 0"));
|
||||
@@ -63,4 +65,9 @@ public class SqlServerPlatform extends DatabasePlatform {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void escapeLikeCharacter(char ch, StringBuilder sb) {
|
||||
sb.append('[').append(ch).append(']');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -101,4 +101,11 @@ public class MySqlDdl extends PlatformDdl {
|
||||
apply.append(" comment='").append(tableComment).append("'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add table comment as a separate statement (from the create table statement).
|
||||
*/
|
||||
@Override
|
||||
public void addTableComment(DdlBuffer apply, String tableName, String tableComment) throws IOException {
|
||||
apply.append(String.format("alter table %s comment = '%s'", tableName, tableComment)).endOfStatement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,12 @@ public class EJson {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
return ((ModifyAwareList) list).asSet();
|
||||
|
||||
if (modifyAware) {
|
||||
return ((ModifyAwareList) list).asSet();
|
||||
} else {
|
||||
return new LinkedHashSet<>(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@ public class CamelCaseHelper {
|
||||
|
||||
String[] vals = underscore.split("_");
|
||||
if (vals.length == 1) {
|
||||
return underscore;
|
||||
return isUpperCase(underscore) ? underscore.toLowerCase() : underscore;
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
@@ -29,4 +29,13 @@ public class CamelCaseHelper {
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static boolean isUpperCase(String underscore) {
|
||||
for (int i = 0; i < underscore.length(); i++) {
|
||||
if (Character.isLowerCase(underscore.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,4 +65,9 @@ public interface SpiExpressionRequest {
|
||||
* Append a DB Like clause.
|
||||
*/
|
||||
void appendLike();
|
||||
|
||||
/**
|
||||
* Escapes a string to use it as exact match in Like clause.
|
||||
*/
|
||||
String escapeLikeString(String value);
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ public interface SpiQuery<T> extends Query<T> {
|
||||
/**
|
||||
* Return the ForUpdate mode.
|
||||
*/
|
||||
@Override
|
||||
ForUpdate getForUpdateMode();
|
||||
|
||||
/**
|
||||
|
||||
@@ -96,6 +96,14 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
public String getDBLikeClause() {
|
||||
return ebeanServer.getDatabasePlatform().getLikeClause();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database platform escaped like string.
|
||||
*/
|
||||
@Override
|
||||
public String escapeLikeString(String value) {
|
||||
return ebeanServer.getDatabasePlatform().escapeLikeString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeSecondaryQueries(boolean forEach) {
|
||||
|
||||
@@ -985,6 +985,7 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
|
||||
docStoreUpdates.queueIndex(beanDescriptor.getDocStoreQueueId(), idValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,11 @@ public interface SpiOrmQueryRequest<T> extends DocQueryRequest<T> {
|
||||
* Return the Database platform like clause.
|
||||
*/
|
||||
String getDBLikeClause();
|
||||
|
||||
/**
|
||||
* Escapes a string to use it as exact match in Like clause.
|
||||
*/
|
||||
String escapeLikeString(String value);
|
||||
|
||||
/**
|
||||
* Mark the underlying transaction as not being query only.
|
||||
|
||||
@@ -16,8 +16,10 @@ public enum ManyType {
|
||||
|
||||
private final boolean map;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final Class<? extends Collection> type;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
ManyType(boolean map, Class<? extends Collection> type) {
|
||||
this.map = map;
|
||||
this.type = type;
|
||||
@@ -31,6 +33,7 @@ public enum ManyType {
|
||||
* Returns List.class or Set.class and null for Map.
|
||||
* Not intended to be called for maps.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Class<? extends Collection> getCollectionType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ public class GeneratedCounter implements GeneratedProperty {
|
||||
@Override
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean, long now) {
|
||||
Number currVal = (Number) prop.getValue(bean);
|
||||
if (currVal == null) {
|
||||
throw new IllegalStateException("version property has been set to null on bean: " + bean);
|
||||
}
|
||||
Integer nextVal = currVal.intValue() + 1;
|
||||
return BasicTypeConverter.convert(nextVal, numberType);
|
||||
}
|
||||
|
||||
+5
-2
@@ -25,8 +25,11 @@ public class GeneratedCounterInteger implements GeneratedProperty {
|
||||
*/
|
||||
@Override
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean, long now) {
|
||||
Integer i = (Integer) prop.getValue(bean);
|
||||
return i + 1;
|
||||
Integer val = (Integer) prop.getValue(bean);
|
||||
if (val == null) {
|
||||
throw new IllegalStateException("version property has been set to null on bean: " + bean);
|
||||
}
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+5
-2
@@ -25,8 +25,11 @@ public class GeneratedCounterLong implements GeneratedProperty {
|
||||
*/
|
||||
@Override
|
||||
public Object getUpdateValue(BeanProperty prop, EntityBean bean, long now) {
|
||||
Long i = (Long) prop.getValue(bean);
|
||||
return i + 1;
|
||||
Long val = (Long) prop.getValue(bean);
|
||||
if (val == null) {
|
||||
throw new IllegalStateException("version property has been set to null on bean: " + bean);
|
||||
}
|
||||
return val + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -172,6 +172,9 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
if (!idInExpandedForm) {
|
||||
return getIdInValueExpr(size);
|
||||
}
|
||||
@@ -199,7 +202,9 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
|
||||
@Override
|
||||
public String getIdInValueExpr(int size) {
|
||||
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (!idInExpandedForm) {
|
||||
|
||||
@@ -130,6 +130,9 @@ public final class IdBinderSimple implements IdBinder {
|
||||
|
||||
@Override
|
||||
public String getIdInValueExpr(int size) {
|
||||
if (size <= 0) {
|
||||
throw new IndexOutOfBoundsException("The size must be at least 1");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(2 * size + 10);
|
||||
sb.append(" in");
|
||||
sb.append(" (?");
|
||||
|
||||
@@ -18,7 +18,6 @@ import io.ebeaninternal.api.SpiQuery;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -448,11 +447,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Id IN a list of id values.
|
||||
* Id IN a collection of id values.
|
||||
*/
|
||||
@Override
|
||||
public Expression idIn(List<?> idList) {
|
||||
return new IdInExpression(idList);
|
||||
public Expression idIn(Collection<?> idCollection) {
|
||||
return new IdInExpression(idCollection);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -770,8 +770,8 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> idIn(List<?> idList) {
|
||||
add(expr.idIn(idList));
|
||||
public ExpressionList<T> idIn(Collection<?> idCollection) {
|
||||
add(expr.idIn(idCollection));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,11 @@ public class DefaultExpressionRequest implements SpiExpressionRequest {
|
||||
sql.append(" ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeLikeString(String value) {
|
||||
return queryRequest.escapeLikeString(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the parameter index and returns that value.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ import io.ebean.search.TextQueryString;
|
||||
import io.ebean.search.TextSimple;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public interface DocQueryContext {
|
||||
/**
|
||||
* Write an Id in expression.
|
||||
*/
|
||||
void writeIds(List<?> idList) throws IOException;
|
||||
void writeIds(Collection<?> idCollection) throws IOException;
|
||||
|
||||
/**
|
||||
* Write an Id equals expression.
|
||||
|
||||
@@ -10,6 +10,8 @@ import io.ebean.Query;
|
||||
import io.ebeaninternal.api.SpiExpressionList;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -95,7 +97,7 @@ public class FilterExpressionList<T> extends DefaultExpressionList<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> idIn(List<?> idValues) {
|
||||
public ExpressionList<T> idIn(Collection<?> idValues) {
|
||||
throw new PersistenceException(notAllowedMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,17 +9,18 @@ import io.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import io.ebeaninternal.server.deploy.id.IdBinder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Slightly redundant as Query.setId() ultimately also does the same job.
|
||||
*/
|
||||
public class IdInExpression extends NonPrepareExpression {
|
||||
|
||||
private final List<?> idList;
|
||||
private final Collection<?> idCollection;
|
||||
|
||||
public IdInExpression(List<?> idList) {
|
||||
this.idList = idList;
|
||||
public IdInExpression(Collection<?> idCollection) {
|
||||
this.idCollection = idCollection;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,7 +34,7 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
context.writeIds(idList);
|
||||
context.writeIds(idCollection);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,8 +51,8 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
|
||||
IdBinder idBinder = descriptor.getIdBinder();
|
||||
|
||||
for (Object anIdList : idList) {
|
||||
idBinder.addIdInBindValue(request, anIdList);
|
||||
for (Object id : idCollection) {
|
||||
idBinder.addIdInBindValue(request, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,10 +64,13 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
DefaultExpressionRequest r = (DefaultExpressionRequest) request;
|
||||
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
|
||||
IdBinder idBinder = descriptor.getIdBinder();
|
||||
|
||||
request.append(descriptor.getIdBinder().getBindIdInSql(null));
|
||||
String inClause = idBinder.getIdInValueExpr(idList.size());
|
||||
request.append(inClause);
|
||||
if (idCollection.size() == 0) {
|
||||
request.append("1=0"); // append false for this stage
|
||||
} else {
|
||||
request.append(descriptor.getIdBinder().getBindIdInSql(null));
|
||||
String inClause = idBinder.getIdInValueExpr(idCollection.size());
|
||||
request.append(inClause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,10 +79,13 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
DefaultExpressionRequest r = (DefaultExpressionRequest) request;
|
||||
BeanDescriptor<?> descriptor = r.getBeanDescriptor();
|
||||
IdBinder idBinder = descriptor.getIdBinder();
|
||||
|
||||
request.append(descriptor.getIdBinderInLHSSql());
|
||||
String inClause = idBinder.getIdInValueExpr(idList.size());
|
||||
request.append(inClause);
|
||||
if (idCollection.size() == 0) {
|
||||
request.append("1=0"); // append false for this stage
|
||||
} else {
|
||||
request.append(descriptor.getIdBinderInLHSSql());
|
||||
String inClause = idBinder.getIdInValueExpr(idCollection.size());
|
||||
request.append(inClause);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,13 +93,13 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(IdInExpression.class).add(idList.size());
|
||||
builder.bind(idList.size());
|
||||
builder.add(IdInExpression.class).add(idCollection.size());
|
||||
builder.bind(idCollection.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryBindHash() {
|
||||
return idList.hashCode();
|
||||
return idCollection.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,17 +109,19 @@ public class IdInExpression extends NonPrepareExpression {
|
||||
}
|
||||
|
||||
IdInExpression that = (IdInExpression) other;
|
||||
return this.idList.size() == that.idList.size();
|
||||
return this.idCollection.size() == that.idCollection.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
IdInExpression that = (IdInExpression) other;
|
||||
if (this.idList.size() != that.idList.size()) {
|
||||
if (this.idCollection.size() != that.idCollection.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < idList.size(); i++) {
|
||||
if (!idList.get(i).equals(that.idList.get(i))) {
|
||||
Iterator<?> it = that.idCollection.iterator();
|
||||
for (Object id1 : idCollection) {
|
||||
Object id2 = it.next();
|
||||
if (!id1.equals(id2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> idIn(List<?> idValues) {
|
||||
public ExpressionList<T> idIn(Collection<?> idValues) {
|
||||
return exprList.idIn(idValues);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,7 @@ class LikeExpression extends AbstractValueExpression {
|
||||
String encryptKey = prop.getBeanProperty().getEncryptKey().getStringValue();
|
||||
request.addBindEncryptKey(encryptKey);
|
||||
}
|
||||
|
||||
String bindValue = getValue(strValue(), caseInsensitive, type);
|
||||
String bindValue = getValue(strValue(), caseInsensitive, type, request);
|
||||
request.addBindValue(bindValue);
|
||||
}
|
||||
|
||||
@@ -92,13 +91,15 @@ class LikeExpression extends AbstractValueExpression {
|
||||
return strValue().equals(that.strValue());
|
||||
}
|
||||
|
||||
private static String getValue(String value, boolean caseInsensitive, LikeType type) {
|
||||
private static String getValue(String value, boolean caseInsensitive, LikeType type, SpiExpressionRequest request) {
|
||||
if (caseInsensitive) {
|
||||
value = value.toLowerCase();
|
||||
}
|
||||
if (type == LikeType.RAW) {
|
||||
return value;
|
||||
}
|
||||
value = request.escapeLikeString(value);
|
||||
switch (type) {
|
||||
case RAW:
|
||||
return value;
|
||||
case STARTS_WITH:
|
||||
return value + "%";
|
||||
case ENDS_WITH:
|
||||
|
||||
@@ -7,7 +7,8 @@ import java.sql.SQLException;
|
||||
* Holds the first SQLException found when executing a JDBC batch.
|
||||
*/
|
||||
public class BatchedSqlException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -4374631080253580648L;
|
||||
|
||||
private SQLException cause;
|
||||
|
||||
BatchedSqlException(String message, SQLException cause) {
|
||||
|
||||
@@ -135,6 +135,10 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
pathMap = createPathMap(prefix, desc);
|
||||
}
|
||||
|
||||
protected boolean isRoot() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScalarType<?> getSingleAttributeScalarType() {
|
||||
if (properties == null || properties.length == 0) {
|
||||
@@ -316,6 +320,10 @@ class SqlTreeNodeBean implements SqlTreeNode {
|
||||
aChildren.load(ctx, localBean, contextBean);
|
||||
}
|
||||
|
||||
if (queryMode.equals(Mode.LAZYLOAD_MANY) && isRoot()) {
|
||||
return contextBean;
|
||||
}
|
||||
|
||||
if (!lazyLoadMany && localBean != null) {
|
||||
ctx.setCurrentPrefix(prefix, pathMap);
|
||||
if (readId && !temporalVersions) {
|
||||
|
||||
@@ -25,6 +25,11 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean {
|
||||
this.includeJoin = includeJoin;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRoot() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the property columns to the buffer.
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ public class DJsonScalar {
|
||||
this.typeManager = typeManager;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void write(JsonGenerator gen, Object value) throws IOException {
|
||||
|
||||
if (value instanceof String) {
|
||||
|
||||
@@ -198,7 +198,7 @@ public class ReadJson {
|
||||
* If there is a JsonReadBeanVisitor registered to the current path then
|
||||
* call it's visit method with the bean and unmappedProperties.
|
||||
*/
|
||||
@SuppressWarnings(value = "unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void beanVisitor(Object bean, Map<String, Object> unmappedProperties) {
|
||||
if (visitorMap != null) {
|
||||
JsonReadBeanVisitor visitor = visitorMap.get(pathStack.peekWithNull());
|
||||
|
||||
@@ -646,6 +646,7 @@ public class JdbcTransaction implements SpiTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceException translate(String message, SQLException cause) {
|
||||
if (manager != null) {
|
||||
return manager.translate(message, cause);
|
||||
|
||||
@@ -28,11 +28,6 @@ public class JtaTransactionManager implements ExternalTransactionManager {
|
||||
|
||||
private static final String EBEAN_TXN_RESOURCE = "EBEAN_TXN_RESOURCE";
|
||||
|
||||
/**
|
||||
* The data source.
|
||||
*/
|
||||
private DataSource dataSource;
|
||||
|
||||
/**
|
||||
* The Ebean transaction manager.
|
||||
*/
|
||||
@@ -59,10 +54,16 @@ public class JtaTransactionManager implements ExternalTransactionManager {
|
||||
// the public API and hence the Object type and casting here
|
||||
|
||||
this.transactionManager = (TransactionManager) txnMgr;
|
||||
this.dataSource = transactionManager.getDataSource();
|
||||
this.serverName = transactionManager.getServerName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current dataSource taking into account multi-tenancy.
|
||||
*/
|
||||
private DataSource dataSource() {
|
||||
return transactionManager.getDataSource();
|
||||
}
|
||||
|
||||
private TransactionSynchronizationRegistry getSyncRegistry() {
|
||||
try {
|
||||
InitialContext ctx = new InitialContext();
|
||||
@@ -121,7 +122,7 @@ public class JtaTransactionManager implements ExternalTransactionManager {
|
||||
|
||||
// "wrap" it in a Ebean specific JtaTransaction
|
||||
String txnId = String.valueOf(System.currentTimeMillis());
|
||||
JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource, transactionManager);
|
||||
JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource(), transactionManager);
|
||||
|
||||
// create and register transaction listener
|
||||
JtaTxnListener txnListener = createJtaTxnListener(newTrans);
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.UUID;
|
||||
/**
|
||||
* Type mapped for DB ARRAY type (Postgres only effectively).
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ScalarTypeArrayList extends ScalarTypeJsonCollection<List> implements ScalarTypeArray {
|
||||
|
||||
private static ScalarTypeArrayList UUID = new ScalarTypeArrayList("uuid", DocPropertyType.UUID, ArrayElementConverter.UUID);
|
||||
@@ -75,6 +76,7 @@ public class ScalarTypeArrayList extends ScalarTypeJsonCollection<List> implemen
|
||||
/**
|
||||
* Return the DB column definition for DDL generation.
|
||||
*/
|
||||
@Override
|
||||
public String getDbColumnDefn() {
|
||||
return arrayType + "[]";
|
||||
}
|
||||
|
||||
@@ -48,11 +48,13 @@ class ScalarTypeArrayListH2 extends ScalarTypeArrayList {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private ScalarTypeArrayListH2(String arrayType, DocPropertyType docPropertyType, ArrayElementConverter converter) {
|
||||
super(arrayType, docPropertyType, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void bind(DataBind bind, List value) throws SQLException {
|
||||
if (value == null) {
|
||||
bind.setNull(Types.ARRAY);
|
||||
|
||||
@@ -75,6 +75,7 @@ public class ScalarTypeArraySet extends ScalarTypeJsonCollection<Set> implements
|
||||
/**
|
||||
* Return the DB column definition for DDL generation.
|
||||
*/
|
||||
@Override
|
||||
public String getDbColumnDefn() {
|
||||
return arrayType + "[]";
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public class ScalarTypeJsonList {
|
||||
/**
|
||||
* Base class for List handling.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private abstract static class Base extends ScalarTypeJsonCollection<List> {
|
||||
|
||||
public Base(int dbType, DocPropertyType docType) {
|
||||
@@ -135,6 +136,7 @@ public class ScalarTypeJsonList {
|
||||
this.pgType = pgType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void bind(DataBind bind, List value) throws SQLException {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.Map;
|
||||
/**
|
||||
* Type which maps Map<String,Object> to various DB types (Clob, Varchar, Blob) in JSON format.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public abstract class ScalarTypeJsonMap extends ScalarTypeBase<Map> {
|
||||
|
||||
private static final ScalarTypeJsonMap CLOB = new ScalarTypeJsonMap.Clob();
|
||||
|
||||
@@ -17,6 +17,7 @@ public abstract class ScalarTypeJsonMapPostgres extends ScalarTypeJsonMap {
|
||||
this.postgresType = postgresType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void bind(DataBind bind, Map value) throws SQLException {
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public class ScalarTypeJsonObjectMapper {
|
||||
/**
|
||||
* Type for Sets wrapping the ObjectMapper Set as a ModifyAwareSet.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static class OmSet extends Base<Set> {
|
||||
|
||||
public OmSet(ObjectMapper objectMapper, Type type, int dbType, String pgType, DocPropertyType docType) {
|
||||
@@ -84,6 +85,7 @@ public class ScalarTypeJsonObjectMapper {
|
||||
/**
|
||||
* Type for Lists wrapping the ObjectMapper List as a ModifyAwareList.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static class OmList extends Base<List> {
|
||||
|
||||
public OmList(ObjectMapper objectMapper, Type type, int dbType, String pgType, DocPropertyType docType) {
|
||||
@@ -101,6 +103,7 @@ public class ScalarTypeJsonObjectMapper {
|
||||
/**
|
||||
* Type for Map wrapping the ObjectMapper Map as a ModifyAwareMap.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static class OmMap extends Base<Map> {
|
||||
|
||||
public OmMap(ObjectMapper objectMapper, Type type, int dbType, String pgType) {
|
||||
|
||||
@@ -64,6 +64,7 @@ public class ScalarTypeJsonSet {
|
||||
/**
|
||||
* Base class for List handling.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private abstract static class Base extends ScalarTypeJsonCollection<Set> {
|
||||
|
||||
public Base(int dbType, DocPropertyType docPropertyType) {
|
||||
@@ -142,6 +143,7 @@ public class ScalarTypeJsonSet {
|
||||
this.pgType = pgType;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void bind(DataBind bind, Set value) throws SQLException {
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebean.DRawSqlColumnsParser;
|
||||
import io.ebean.RawSql.ColumnMapping;
|
||||
import io.ebean.RawSql.ColumnMapping.Column;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -12,9 +14,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BeanListTest {
|
||||
|
||||
Object object1 = new Object();
|
||||
Object object2 = new Object();
|
||||
Object object3 = new Object();
|
||||
private Object object1 = new Object();
|
||||
private Object object2 = new Object();
|
||||
private Object object3 = new Object();
|
||||
|
||||
@NotNull
|
||||
private List<Object> all() {
|
||||
@@ -33,6 +35,30 @@ public class BeanListTest {
|
||||
return some;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_setModifyListening_null() throws Exception {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(null);
|
||||
|
||||
// act
|
||||
list.addAll(all());
|
||||
|
||||
assertThat(list.getModifyAdditions()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_setModifyListening_none() throws Exception {
|
||||
|
||||
BeanList<Object> list = new BeanList<>();
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.NONE);
|
||||
|
||||
// act
|
||||
list.addAll(all());
|
||||
|
||||
assertThat(list.getModifyAdditions()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
|
||||
@@ -67,6 +93,47 @@ public class BeanListTest {
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_removals_DeleteThenAddBack_expect_noChange() throws Exception {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(some());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
|
||||
// act
|
||||
list.remove(object2);
|
||||
assertThat(list.getModifyRemovals()).isNotEmpty();
|
||||
list.add(object2);
|
||||
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_sort_whenAll_expect_noChange() throws Exception {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.ALL);
|
||||
|
||||
// act
|
||||
Collections.sort(list, Comparator.comparingInt(Object::hashCode));
|
||||
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_sort_whenRemovals_expect_noChange() throws Exception {
|
||||
|
||||
BeanList<Object> list = new BeanList<>(all());
|
||||
list.setModifyListening(BeanCollection.ModifyListenMode.REMOVALS);
|
||||
|
||||
// act
|
||||
Collections.sort(list, Comparator.comparingInt(Object::hashCode));
|
||||
|
||||
assertThat(list.getModifyRemovals()).isEmpty();
|
||||
assertThat(list.getModifyAdditions()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd_given_someAlreadyIn() throws Exception {
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.ebean.dbmigration.ddlgeneration.platform;
|
||||
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebean.config.dbplatform.mysql.MySqlPlatform;
|
||||
import io.ebean.config.dbplatform.oracle.OraclePlatform;
|
||||
import io.ebean.dbmigration.ddlgeneration.DdlWrite;
|
||||
import io.ebean.dbmigration.ddlgeneration.Helper;
|
||||
@@ -93,6 +94,23 @@ public class BaseTableDdlTest {
|
||||
assertThat(ddl).contains("comment on table mytab is 'my comment'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddTableComment_mysql() throws IOException {
|
||||
|
||||
BaseTableDdl ddlGen = new BaseTableDdl(serverConfig, new MySqlPlatform().getPlatformDdl());
|
||||
|
||||
DdlWrite write = new DdlWrite();
|
||||
|
||||
AddTableComment addTableComment = new AddTableComment();
|
||||
addTableComment.setName("mytab");
|
||||
addTableComment.setComment("my comment");
|
||||
|
||||
ddlGen.generate(write, addTableComment);
|
||||
|
||||
String ddl = write.apply().getBuffer();
|
||||
assertThat(ddl).contains("alter table mytab comment = 'my comment'");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenerate() throws Exception {
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.io.StringReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -301,4 +302,13 @@ public class EJsonTests {
|
||||
assertTrue(modAware.isMarkedDirty());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseSet_when_not_modifyAware() throws IOException {
|
||||
|
||||
String jsonInput = "[{\"name\":\"rob\",\"age\":12},{\"name\":\"jim\",\"age\":42}]";
|
||||
|
||||
Set set = EJson.parseSet(jsonInput, false);
|
||||
assertTrue(set instanceof LinkedHashSet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class CamelCaseHelperTest {
|
||||
assertEquals(CamelCaseHelper.toCamelFromUnderscore("helloThere"), "helloThere");
|
||||
assertEquals(CamelCaseHelper.toCamelFromUnderscore("helloThereJim"), "helloThereJim");
|
||||
assertEquals(CamelCaseHelper.toCamelFromUnderscore("hello"), "hello");
|
||||
assertEquals(CamelCaseHelper.toCamelFromUnderscore("HELLO"), "HELLO");
|
||||
assertEquals(CamelCaseHelper.toCamelFromUnderscore("HELLO"), "hello");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package io.ebeaninternal.server.deploy.generatedproperty;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.bean.EntityBean;
|
||||
import io.ebeaninternal.server.deploy.BeanProperty;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class GeneratedCounterLongTest extends BaseTestCase {
|
||||
|
||||
private GeneratedCounterLong counter = new GeneratedCounterLong();
|
||||
|
||||
private BeanProperty version = getBeanDescriptor(Customer.class).getBeanProperty("version");
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void when_null_expect_IllegalStateException() throws Exception {
|
||||
|
||||
Customer customer = new Customer();
|
||||
counter.getUpdateValue(version, (EntityBean)customer, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void when_set_expect_incremented() throws Exception {
|
||||
|
||||
Customer customer = new Customer();
|
||||
customer.setVersion(7L);
|
||||
Object value = counter.getUpdateValue(version, (EntityBean) customer, System.currentTimeMillis());
|
||||
|
||||
assertThat(value).isEqualTo(8L);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,4 +78,9 @@ public class TDSpiExpressionRequest implements SpiExpressionRequest {
|
||||
public void appendLike() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeLikeString(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.ebeaninternal.server.text.json;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.config.dbplatform.DatabasePlatform;
|
||||
import io.ebean.config.dbplatform.h2.H2Platform;
|
||||
import io.ebeaninternal.server.core.bootup.BootupClasses;
|
||||
import io.ebeaninternal.server.type.DefaultTypeManager;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.tests.cache;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.BeanState;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.Transaction;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.L2CachedLazyDirtFlagResetBean;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestL2DirtyFlagOnLazyLoad extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void dirtyFlag_reset_after_lazy() {
|
||||
|
||||
//PREPARE
|
||||
Transaction tx0 = Ebean.beginTransaction();
|
||||
L2CachedLazyDirtFlagResetBean bean = new L2CachedLazyDirtFlagResetBean();
|
||||
bean.setName("findById");
|
||||
Ebean.save(bean);
|
||||
//bean.save();
|
||||
tx0.commit();
|
||||
|
||||
// clearAll() caches via the ServerCacheManager ...
|
||||
// Clear all the caches on the default/primary EbeanServer
|
||||
server().getServerCacheManager().clearAll();
|
||||
|
||||
//TEST
|
||||
Transaction tx1 = Ebean.beginTransaction();
|
||||
// load (and dont touch any related entity)
|
||||
L2CachedLazyDirtFlagResetBean bean1 = Ebean.find(L2CachedLazyDirtFlagResetBean.class, bean.getId());
|
||||
tx1.commit();
|
||||
|
||||
|
||||
Transaction tx2 = Ebean.beginTransaction();
|
||||
// load (and modify)
|
||||
|
||||
L2CachedLazyDirtFlagResetBean bean2 = Ebean.find(L2CachedLazyDirtFlagResetBean.class, bean.getId());
|
||||
assertNotNull(bean2);
|
||||
assertEquals("findById", bean2.getName());
|
||||
bean2.setName("something");
|
||||
BeanState beanState = Ebean.getBeanState(bean2);
|
||||
assertTrue(beanState.isDirty());
|
||||
//bean2.getChildren().size();
|
||||
bean2.someRichObjectMethod();
|
||||
assertTrue(beanState.isDirty());
|
||||
|
||||
Ebean.update(bean2);
|
||||
tx2.commit();
|
||||
|
||||
Transaction tx3 = Ebean.beginTransaction();
|
||||
// validation
|
||||
|
||||
L2CachedLazyDirtFlagResetBean bean3 = Ebean.find(L2CachedLazyDirtFlagResetBean.class, bean.getId());
|
||||
assertEquals("something", bean3.getName());
|
||||
|
||||
tx3.rollback();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import java.util.List;
|
||||
@CacheBeanTuning(maxSecsToLive = 45)
|
||||
@Entity
|
||||
public class Article extends BasicDomain {
|
||||
private static final long serialVersionUID = -7181090513848918784L;
|
||||
|
||||
String name;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.Set;
|
||||
@Inheritance
|
||||
@DiscriminatorValue("C")
|
||||
public class Car extends Vehicle {
|
||||
private static final long serialVersionUID = -65427345082456523L;
|
||||
|
||||
public enum Size {
|
||||
SMALL("S"),
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import io.ebean.annotation.Cache;
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Cached bean for testing caching implementation.
|
||||
*/
|
||||
@Cache
|
||||
@Entity
|
||||
@Table(name = "l2_cached_lazy_dirt_flag_reset_bean")
|
||||
public class L2CachedLazyDirtFlagResetBean {
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String name;
|
||||
|
||||
public List<L2CachedLazyDirtFlagResetBeanChild> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
|
||||
List<L2CachedLazyDirtFlagResetBeanChild> children;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Long> someRichObjectMethod() {
|
||||
List<Long> result = new ArrayList<Long>();
|
||||
if(this.children != null) {
|
||||
for (L2CachedLazyDirtFlagResetBeanChild relation : this.children) {
|
||||
result.add(relation.getId());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "l2_cached_lazy_dirt_flag_reset_bean_child")
|
||||
public class L2CachedLazyDirtFlagResetBeanChild {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
@ManyToOne
|
||||
@Column(nullable = false)
|
||||
L2CachedLazyDirtFlagResetBean parent;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
public class OEngine {
|
||||
public class OEngine implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
public class OGearBox {
|
||||
public class OGearBox implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.DiscriminatorColumn;
|
||||
import javax.persistence.DiscriminatorType;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
@@ -11,7 +13,8 @@ import javax.persistence.Inheritance;
|
||||
@Inheritance
|
||||
@DiscriminatorColumn(name = "my_type", length = 3, discriminatorType = DiscriminatorType.INTEGER)
|
||||
@DiscriminatorValue("1")
|
||||
public class TIntRoot {
|
||||
public class TIntRoot implements Serializable {
|
||||
private static final long serialVersionUID = -7057502590435806504L;
|
||||
|
||||
@Id
|
||||
Integer id;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.tests.model.basic;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@MappedSuperclass
|
||||
public class TMappedSuper2 {
|
||||
public class TMappedSuper2 implements Serializable {
|
||||
private static final long serialVersionUID = 325282672490816821L;
|
||||
|
||||
String something;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import javax.persistence.ManyToOne;
|
||||
@Inheritance
|
||||
@DiscriminatorValue("T")
|
||||
public class Truck extends Vehicle {
|
||||
private static final long serialVersionUID = 9195535931523211134L;
|
||||
|
||||
public enum Size {
|
||||
SMALL("S"),
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.persistence.Inheritance;
|
||||
@Inheritance
|
||||
@DiscriminatorValue("O")
|
||||
public class CInhOne extends CInhRoot {
|
||||
private static final long serialVersionUID = -3933815364935720317L;
|
||||
|
||||
private String driver;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import javax.persistence.Inheritance;
|
||||
@Inheritance
|
||||
@DiscriminatorColumn(length = 3)
|
||||
public abstract class CInhRoot extends BasicDomain {
|
||||
private static final long serialVersionUID = -4673953370819311120L;
|
||||
|
||||
private String licenseNumber;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.persistence.Inheritance;
|
||||
@Inheritance
|
||||
@DiscriminatorValue("T")
|
||||
public class CInhTwo extends CInhRoot {
|
||||
private static final long serialVersionUID = -8528396890675473212L;
|
||||
|
||||
private String action;
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class OCompany extends BasicDomain {
|
||||
|
||||
private static final long serialVersionUID = 6733591692223352686L;
|
||||
|
||||
@Column(length = 50, unique = true)
|
||||
public String corpId;
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import javax.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class ORoadShowMsg extends BasicDomain {
|
||||
|
||||
private static final long serialVersionUID = -1555123312818834212L;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL, optional = false)
|
||||
@JoinColumn()//(name = "corp_id", nullable = false, referencedColumnName = "corp_id")
|
||||
public OCompany company;
|
||||
|
||||
@@ -3,10 +3,12 @@ package org.tests.model.selfref;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
@MappedSuperclass
|
||||
public abstract class BaseResourceFile {
|
||||
public abstract class BaseResourceFile implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.tests.query.other;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestLikeEscaping extends BaseTestCase {
|
||||
|
||||
|
||||
@Test
|
||||
public void testLikeEscaping() {
|
||||
ResetBasicData.reset();
|
||||
// Mysql, PgSql, H2 special chars: "_" "%"
|
||||
// MsSql special chars: "_" "%" "[" AND different Quoting!
|
||||
Ebean.save(ResetBasicData.createCustomer("Paul % Percentage", "*Star", "[none]", 0, null));
|
||||
Ebean.save(ResetBasicData.createCustomer("(none)", "More * Star", "[none]", 0, null));
|
||||
|
||||
Ebean.save(ResetBasicData.createCustomer("Paul %% Doublepercentage", "|Pipeway", "[other]", 1, null));
|
||||
Ebean.save(ResetBasicData.createCustomer("_Udo Underscore", "|Pipeway", "[other]", 1, null));
|
||||
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().contains("name", "Paul %%").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("name", "_").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("name", "_u").findCount()
|
||||
).isEqualTo(0);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().istartsWith("name", "_U").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "|p").findCount()
|
||||
).isEqualTo(0);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "|P").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().endsWith("billingAddress.line1", "]").findCount()
|
||||
).isEqualTo(4);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().endsWith("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().contains("billingAddress.line1", "[none]").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().contains("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(2);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().startsWith("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(1);
|
||||
|
||||
assertThat(Ebean.find(Customer.class)
|
||||
.where().endsWith("shippingAddress.line1", "*").findCount()
|
||||
).isEqualTo(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -60,6 +60,21 @@ public class TestRawSqlOrmQuery extends BaseTestCase {
|
||||
Assert.assertNotNull(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_upperCaseSql() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
RawSql rawSql = RawSqlBuilder.parse("select id, NAME from O_CUSTOMER ").create();
|
||||
|
||||
Query<Customer> query = Ebean.find(Customer.class);
|
||||
query.setRawSql(rawSql);
|
||||
query.where().ilike("name", "r%");
|
||||
|
||||
List<Customer> list = query.findList();
|
||||
Assert.assertNotNull(list);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstRowsMaxRows() throws InterruptedException, ExecutionException {
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.tests.sp.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
@@ -7,7 +9,8 @@ import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Version;
|
||||
|
||||
@MappedSuperclass
|
||||
public abstract class IdEntity {
|
||||
public abstract class IdEntity implements Serializable {
|
||||
private static final long serialVersionUID = 7804145008732783678L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE)
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<!--<logger name="io.ebean.cache.QUERY" level="TRACE"/>-->
|
||||
<!--<logger name="io.ebean.cache.BEAN" level="TRACE"/>-->
|
||||
<!--<logger name="io.ebean.cache.NATKEY" level="TRACE"/>-->
|
||||
<!--<logger name="io.ebean.cache.COLL" level="DEBUG"/>-->
|
||||
<!--<logger name="io.ebean.cache.COLL" level="TRACE"/>-->
|
||||
|
||||
<!--<logger name="org.avaje.classpath" level="INFO"/>-->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user