diff --git a/ebean-api/pom.xml b/ebean-api/pom.xml
index 4150e1cb3..c5f36193b 100644
--- a/ebean-api/pom.xml
+++ b/ebean-api/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean api
diff --git a/ebean-autotune/pom.xml b/ebean-autotune/pom.xml
index 5892fda8e..b50be9b0d 100644
--- a/ebean-autotune/pom.xml
+++ b/ebean-autotune/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
@@ -26,7 +26,7 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
diff --git a/ebean-autotune/src/test/java/io/ebeaninternal/server/autotune/service/ProfileOriginTest.java b/ebean-autotune/src/test/java/io/ebeaninternal/server/autotune/service/ProfileOriginTest.java
index 4bc86f6b4..ec0a09596 100644
--- a/ebean-autotune/src/test/java/io/ebeaninternal/server/autotune/service/ProfileOriginTest.java
+++ b/ebean-autotune/src/test/java/io/ebeaninternal/server/autotune/service/ProfileOriginTest.java
@@ -30,7 +30,7 @@ public class ProfileOriginTest extends BaseTestCase {
OrmQueryDetail detail = po.buildDetail(desc);
- assertThat(detail.asString().trim()).isEqualTo("fetch customer (name)");
+ assertThat(detail.asStringDebug().trim()).isEqualTo("fetch customer (name)");
}
@Test
@@ -49,7 +49,7 @@ public class ProfileOriginTest extends BaseTestCase {
OrmQueryDetail detail = po.buildDetail(desc);
- assertThat(detail.asString()).isEqualTo("select (orderDate) fetch customer (name)");
+ assertThat(detail.asStringDebug()).isEqualTo("select (orderDate) fetch customer (name)");
}
@Test
@@ -67,7 +67,7 @@ public class ProfileOriginTest extends BaseTestCase {
OrmQueryDetail detail = po.buildDetail(desc);
- assertThat(detail.asString().trim()).isEqualTo("select (orderDate,customer)");
+ assertThat(detail.asStringDebug().trim()).isEqualTo("select (orderDate,customer)");
}
@Test
@@ -90,7 +90,7 @@ public class ProfileOriginTest extends BaseTestCase {
OrmQueryDetail detail = po.buildDetail(desc);
- assertThat(detail.asString()).isEqualTo("select (orderDate) fetch customer (billingAddress)");
+ assertThat(detail.asStringDebug()).isEqualTo("select (orderDate) fetch customer (billingAddress)");
}
@@ -119,7 +119,7 @@ public class ProfileOriginTest extends BaseTestCase {
po.collectUsageInfo(c);
OrmQueryDetail detail = po.buildDetail(desc);
- assertThat(detail.asString()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
+ assertThat(detail.asStringDebug()).isEqualTo("fetch customer (name,note) fetch customer.billingAddress (line1)");
}
private NodeUsageCollector node(String path) {
diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml
index b3b611006..6a18b3017 100644
--- a/ebean-bom/pom.xml
+++ b/ebean-bom/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean bom
@@ -81,88 +81,88 @@
io.ebean
ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-core-type
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-ddl-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-externalmapping-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-externalmapping-xml
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-autotune
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-querybean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
querybean-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
kotlin-querybean-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
ebean-test
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
io.ebean
ebean-postgis
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-redis
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
diff --git a/ebean-core-type/pom.xml b/ebean-core-type/pom.xml
index 18e8f5bb8..50d80ce17 100644
--- a/ebean-core-type/pom.xml
+++ b/ebean-core-type/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean-core-type
@@ -21,7 +21,7 @@
io.ebean
ebean-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml
index 1c5a407b8..082cb17aa 100644
--- a/ebean-core/pom.xml
+++ b/ebean-core/pom.xml
@@ -3,7 +3,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean-core
@@ -92,19 +92,19 @@
io.ebean
ebean-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-core-type
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-externalmapping-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java
index 91c949a0f..b3346562b 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocManys.java
@@ -5,7 +5,6 @@ import io.ebean.annotation.FetchPreference;
import io.ebean.annotation.HistoryExclude;
import io.ebean.annotation.Where;
import io.ebean.bean.BeanCollection.ModifyListenMode;
-import io.ebean.config.BeanNotRegisteredException;
import io.ebean.config.NamingConvention;
import io.ebean.config.TableName;
import io.ebean.core.type.ScalarType;
@@ -140,15 +139,15 @@ class AnnotationAssocManys extends AnnotationAssoc {
JoinTable joinTable = get(prop, JoinTable.class);
if (joinTable != null) {
if (prop.isManyToMany()) {
- // expected this
readJoinTable(joinTable, prop);
-
} else {
// OneToMany with @JoinTable
prop.setO2mJoinTable();
readJoinTable(joinTable, prop);
manyToManyDefaultJoins(prop);
}
+ } else if (prop.isManyToMany()) {
+ checkSelfManyToMany(prop);
}
if (prop.getMappedBy() != null) {
@@ -181,6 +180,12 @@ class AnnotationAssocManys extends AnnotationAssoc {
}
}
+ private void checkSelfManyToMany(DeployBeanPropertyAssocMany> prop) {
+ if (prop.getTargetType().equals(descriptor.getBeanType())) {
+ throw new IllegalStateException("@ManyToMany mapping for " + prop.getFullBeanName() + " requires explicit @JoinTable with joinColumns & inverseJoinColumns. Refer issue #2157");
+ }
+ }
+
@SuppressWarnings("unchecked")
private void readElementCollection(DeployBeanPropertyAssocMany> prop, ElementCollection elementCollection) {
@@ -430,7 +435,6 @@ class AnnotationAssocManys extends AnnotationAssoc {
}
private void readToMany(ManyToMany propAnn, DeployBeanPropertyAssocMany> manyProp) {
-
manyProp.setMappedBy(propAnn.mappedBy());
manyProp.setFetchType(propAnn.fetch());
setCascadeTypes(propAnn.cascade(), manyProp.getCascadeInfo());
@@ -442,7 +446,6 @@ class AnnotationAssocManys extends AnnotationAssoc {
}
private void readToOne(OneToMany propAnn, DeployBeanPropertyAssocMany> manyProp) {
-
manyProp.setMappedBy(propAnn.mappedBy());
manyProp.setFetchType(propAnn.fetch());
setCascadeTypes(propAnn.cascade(), manyProp.getCascadeInfo());
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
index 961684be5..ef58d99f6 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/DefaultOrmQuery.java
@@ -1136,81 +1136,81 @@ public class DefaultOrmQuery implements SpiQuery {
private String planDescription() {
StringBuilder sb = new StringBuilder(300);
if (type != null) {
- sb.append("t:").append(type.ordinal());
+ sb.append(type.ordinal());
}
if (useDocStore) {
- sb.append(",ds:");
+ sb.append("/ds");
}
if (beanDescriptor.getDiscValue() != null) {
- sb.append(",disc:").append(beanDescriptor.getDiscValue());
+ sb.append("/dv").append(beanDescriptor.getDiscValue());
}
if (temporalMode != SpiQuery.TemporalMode.CURRENT) {
- sb.append(",temp:").append(temporalMode.ordinal());
+ sb.append("/tm").append(temporalMode.ordinal());
if (versionsStart != null) {
- sb.append(",vb:");
+ sb.append("v");
}
}
if (forUpdate != null) {
- sb.append(",forUpd:").append(forUpdate.ordinal());
+ sb.append("/fu").append(forUpdate.ordinal());
if (lockType != null) {
- sb.append(",lt:").append(lockType.ordinal());
+ sb.append("t").append(lockType.ordinal());
}
}
if (id != null) {
- sb.append(",id:");
+ sb.append("/id");
}
if (manualId) {
- sb.append(",manId:");
+ sb.append("/md");
}
if (distinct) {
- sb.append(",dist:");
+ sb.append("/dt");
}
if (allowLoadErrors) {
- sb.append(",allowLoadErrors:");
+ sb.append("/ae");
}
if (disableLazyLoading) {
- sb.append(",disLazy:");
+ sb.append("/dl");
}
if (baseTable != null) {
- sb.append(",baseTable:").append(baseTable);
+ sb.append("/bt").append(baseTable);
}
if (rootTableAlias != null) {
- sb.append(",root:").append(rootTableAlias);
+ sb.append("/ra").append(rootTableAlias);
}
if (orderBy != null) {
- sb.append(",orderBy:").append(orderBy.toStringFormat());
+ sb.append("/ob").append(orderBy.toStringFormat());
}
if (m2mIncludeJoin != null) {
- sb.append(",m2m:").append(m2mIncludeJoin.getTable());
+ sb.append("/m2").append(m2mIncludeJoin.getTable());
}
if (mapKey != null) {
- sb.append(",mapKey:").append(mapKey);
+ sb.append("/mk").append(mapKey);
}
if (countDistinctOrder != null) {
- sb.append(",countDistOrd:").append(countDistinctOrder.name());
+ sb.append("/cd").append(countDistinctOrder.name());
}
if (detail != null) {
- sb.append(" detail[");
+ sb.append("/d[");
detail.queryPlanHash(sb);
sb.append("]");
}
if (bindParams != null) {
- sb.append(" bindParams[");
+ sb.append("/b[");
bindParams.buildQueryPlanHash(sb);
sb.append("]");
}
if (whereExpressions != null) {
- sb.append(" where[");
+ sb.append("/w[");
whereExpressions.queryPlanHash(sb);
sb.append("]");
}
if (havingExpressions != null) {
- sb.append(" having[");
+ sb.append("/h[");
havingExpressions.queryPlanHash(sb);
sb.append("]");
}
if (updateProperties != null) {
- sb.append(" update[");
+ sb.append("/u[");
updateProperties.buildQueryPlanHash(sb);
sb.append("]");
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java
index b36daaf58..b8837111e 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryDetail.java
@@ -106,15 +106,10 @@ public class OrmQueryDetail implements Serializable {
return p1 == null ? p2 == null : p1.isSameByAutoTune(p2);
}
- @Override
- public String toString() {
- return asString();
- }
-
/**
* Return the detail in string form.
*/
- public String asString() {
+ public String asStringDebug() {
StringBuilder sb = new StringBuilder();
if (!baseProps.isEmpty()) {
baseProps.asStringDebug("select ", sb);
@@ -150,7 +145,7 @@ public class OrmQueryDetail implements Serializable {
* Set the base query properties to be empty.
*/
public void setEmptyBase() {
- this.baseProps = new OrmQueryProperties(null, new LinkedHashSet<>());
+ this.baseProps = new OrmQueryProperties(null, Collections.emptySet());
}
/**
@@ -316,7 +311,7 @@ public class OrmQueryDetail implements Serializable {
if (addId) {
parentProp = new OrmQueryProperties(parentPath, assocOne.getTargetIdProperty());
} else {
- parentProp = new OrmQueryProperties(parentPath, new LinkedHashSet<>());
+ parentProp = new OrmQueryProperties(parentPath, Collections.emptySet());
}
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java
index c083eb3d5..3a9ac8e33 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPlanKey.java
@@ -29,7 +29,7 @@ class OrmQueryPlanKey implements CQueryPlanKey {
@Override
public CQueryPlanKey withDeleteByIds() {
- return new OrmQueryPlanKey(description + ":deleteByIds", 0, 0, null);
+ return new OrmQueryPlanKey(description + "/deleteByIds", 0, 0, null);
}
@Override
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java
index e7c416390..02b3afbac 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/querydefn/OrmQueryPropertiesParser.java
@@ -3,8 +3,8 @@ package io.ebeaninternal.server.querydefn;
import io.ebean.FetchConfig;
import io.ebeaninternal.server.util.DSelectColumnsParser;
-import java.util.LinkedHashSet;
-import java.util.List;
+import java.util.Iterator;
+import java.util.Set;
/**
* Parses the path properties string.
@@ -22,9 +22,9 @@ class OrmQueryPropertiesParser {
final boolean cache;
final FetchConfig fetchConfig;
final String properties;
- final LinkedHashSet included;
+ final Set included;
- Response(boolean readOnly, boolean cache, int queryFetchBatch, int lazyFetchBatch, String properties, LinkedHashSet included) {
+ Response(boolean readOnly, boolean cache, int queryFetchBatch, int lazyFetchBatch, String properties, Set included) {
this.readOnly = readOnly;
this.cache = cache;
this.properties = properties;
@@ -55,9 +55,7 @@ class OrmQueryPropertiesParser {
return new OrmQueryPropertiesParser(rawProperties).parse();
}
- private String inputProperties;
-
- private String outputProperties = "";
+ private final String inputProperties;
private boolean allProperties;
private boolean readOnly;
private boolean cache;
@@ -72,124 +70,61 @@ class OrmQueryPropertiesParser {
* Parse the raw string properties input.
*/
private Response parse() {
-
if (inputProperties == null || inputProperties.isEmpty()) {
return EMPTY;
}
- int pos = inputProperties.indexOf("+readonly");
- if (pos > -1) {
- inputProperties = inputProperties.replace("+readonly", "");
- readOnly = true;
- }
- pos = inputProperties.indexOf("+cache");
- if (pos > -1) {
- inputProperties = inputProperties.replace("+cache", "");
- cache = true;
- }
- pos = inputProperties.indexOf("+query");
- if (pos > -1) {
- queryFetchBatch = parseBatchHint(pos, "+query");
- }
- pos = inputProperties.indexOf("+lazy");
- if (pos > -1) {
- lazyFetchBatch = parseBatchHint(pos, "+lazy");
- }
-
- LinkedHashSet included = parseIncluded();
- String properties = (allProperties) ? "*" : outputProperties;
- return new Response(readOnly, cache, queryFetchBatch, lazyFetchBatch, properties, included);
- }
-
- /**
- * Parse the include separating by comma or semicolon.
- */
- private LinkedHashSet parseIncluded() {
-
- inputProperties = inputProperties.trim();
- if (inputProperties.isEmpty()) {
- // default properties
- return null;
- }
if (inputProperties.equals("*")) {
// explicit all properties
allProperties = true;
- return null;
+ return new Response(readOnly, cache, queryFetchBatch, lazyFetchBatch, "*", null);
}
-
- List res = splitRawSelect(inputProperties);
-
- StringBuilder sb = new StringBuilder(70);
- LinkedHashSet propertySet = new LinkedHashSet<>(res.size() * 2);
-
- int count = 0;
- String temp;
- for (String re : res) {
- temp = re.trim();
- if (!temp.isEmpty()) {
- if (count > 0) {
- sb.append(",");
- }
- sb.append(temp);
- propertySet.add(temp);
- count++;
+ boolean hints = false;
+ Set fields = splitRawSelect(inputProperties);
+ final Iterator iterator = fields.iterator();
+ while (iterator.hasNext()) {
+ String val = iterator.next();
+ if (val.startsWith("+")) {
+ hints = true;
+ iterator.remove();
+ parseHint(val);
+ } else if (val.equals("*")) {
+ allProperties = true;
}
}
-
- if (propertySet.isEmpty()) {
- // default properties
- return null;
+ String properties = allProperties ? "*" : hints ? String.join(",", fields) : inputProperties;
+ if (fields.isEmpty()) {
+ fields = null;
}
+ return new Response(readOnly, cache, queryFetchBatch, lazyFetchBatch, properties, fields);
+ }
- if (propertySet.contains("*")) {
- // explicit all properties
- allProperties = true;
- return null;
+ private void parseHint(String val) {
+ if (val.equals("+readonly")) {
+ readOnly = true;
+ } else if (val.equals("+cache")) {
+ cache = true;
+ } else if (val.startsWith("+query")) {
+ queryFetchBatch = parseBatch(val);
+ } else if (val.startsWith("+lazy")) {
+ lazyFetchBatch = parseBatch(val);
}
+ }
- // partial properties
- outputProperties = sb.toString();
- return propertySet;
+ private int parseBatch(String val) {
+ if (val.endsWith(")")) {
+ int start = val.lastIndexOf('(');
+ if (start > 0) {
+ return Integer.parseInt(val.substring(start + 1, val.length() - 1));
+ }
+ }
+ return 0;
}
/**
* Split allowing 'dynamic function based properties'.
*/
- private List splitRawSelect(String inputProperties) {
+ private Set splitRawSelect(String inputProperties) {
return DSelectColumnsParser.parse(inputProperties);
}
- private int parseBatchHint(int pos, String option) {
-
- int startPos = pos + option.length();
- int endPos = findEndPos(startPos, inputProperties);
- if (endPos == -1) {
- inputProperties = inputProperties.replace(option, "");
- return 0;
-
- } else {
-
- String batchParam = inputProperties.substring(startPos + 1, endPos);
-
- if (endPos + 1 >= inputProperties.length()) {
- inputProperties = inputProperties.substring(0, pos);
- } else {
- inputProperties = inputProperties.substring(0, pos) + inputProperties.substring(endPos + 1);
- }
- return Integer.parseInt(batchParam);
- }
- }
-
- private int findEndPos(int pos, String props) {
-
- if (pos < props.length()) {
- if (props.charAt(pos) == '(') {
- int endPara = props.indexOf(')', pos + 1);
- if (endPara == -1) {
- throw new RuntimeException("Error could not find ')' in " + props + " after position " + pos);
- }
- return endPara;
- }
- }
- return -1;
- }
}
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java
index 2ee3b354d..74c02badd 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/rawsql/DRawSqlColumnsParser.java
@@ -6,6 +6,7 @@ import io.ebeaninternal.server.util.DSelectColumnsParser;
import javax.persistence.PersistenceException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.regex.Pattern;
/**
@@ -28,11 +29,8 @@ final class DRawSqlColumnsParser {
}
private ColumnMapping parse() {
-
- List columnList = DSelectColumnsParser.parse(sqlSelect);
-
+ Set columnList = DSelectColumnsParser.parse(sqlSelect);
List columns = new ArrayList<>(columnList.size());
-
for (String rawColumn : columnList) {
columns.add(parseColumn(rawColumn));
}
@@ -40,7 +38,6 @@ final class DRawSqlColumnsParser {
}
private ColumnMapping.Column parseColumn(String colInfo) {
-
String[] split = COLINFO_SPLIT.split(colInfo);
if (split.length > 1) {
ArrayList tmp = new ArrayList<>(split.length);
diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java b/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java
index c172f92b2..b4ec33a67 100644
--- a/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java
+++ b/ebean-core/src/main/java/io/ebeaninternal/server/util/DSelectColumnsParser.java
@@ -1,7 +1,7 @@
package io.ebeaninternal.server.util;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
/**
* Splits a select clause into 'logical columns' taking into account functions and quotes.
@@ -14,7 +14,7 @@ public final class DSelectColumnsParser {
private int pos;
- public static List parse(String sqlSelect) {
+ public static Set parse(String sqlSelect) {
return new DSelectColumnsParser(sqlSelect).parse();
}
@@ -23,9 +23,8 @@ public final class DSelectColumnsParser {
this.end = selectClause.length();
}
- private List parse() {
-
- ArrayList columns = new ArrayList<>();
+ private Set parse() {
+ LinkedHashSet columns = new LinkedHashSet<>();
while (pos <= end) {
columns.add(nextColumnInfo());
}
diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/util/DSelectColumnsParserTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/util/DSelectColumnsParserTest.java
index 0b30e225c..cc9234925 100644
--- a/ebean-core/src/test/java/io/ebeaninternal/server/util/DSelectColumnsParserTest.java
+++ b/ebean-core/src/test/java/io/ebeaninternal/server/util/DSelectColumnsParserTest.java
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.util;
import org.junit.Test;
-import java.util.List;
+import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
@@ -11,49 +11,49 @@ public class DSelectColumnsParserTest {
@Test
public void parse() {
- List cols = DSelectColumnsParser.parse("a,MD5(id::text) as b,c");
+ Set cols = DSelectColumnsParser.parse("a,MD5(id::text) as b,c");
assertThat(cols).containsExactly("a", "MD5(id::text) as b", "c");
}
@Test
public void whitespace_is_trimmed() {
- List cols = DSelectColumnsParser.parse("a , MD5(id::text) as b , c ");
+ Set cols = DSelectColumnsParser.parse("a , MD5(id::text) as b , c ");
assertThat(cols).containsExactly("a", "MD5(id::text) as b", "c");
}
@Test
public void nestedFunctions() {
- List cols = DSelectColumnsParser.parse("a , concat(id,'sd',inner(foo)) as b , c ");
+ Set cols = DSelectColumnsParser.parse("a , concat(id,'sd',inner(foo)) as b , c ");
assertThat(cols).containsExactly("a", "concat(id,'sd',inner(foo)) as b", "c");
}
@Test
public void basic() {
- List cols = DSelectColumnsParser.parse("name , status , billingAddress ");
+ Set cols = DSelectColumnsParser.parse("name , status , billingAddress ");
assertThat(cols).containsExactly("name", "status", "billingAddress");
}
@Test
public void basic_noWhitespace() {
- List cols = DSelectColumnsParser.parse("a,b,c");
+ Set cols = DSelectColumnsParser.parse("a,b,c");
assertThat(cols).containsExactly("a", "b", "c");
}
@Test
public void formula_noWhitespace() {
- List cols = DSelectColumnsParser.parse("a,concat(x,y),c");
+ Set cols = DSelectColumnsParser.parse("a,concat(x,y),c");
assertThat(cols).containsExactly("a", "concat(x,y)", "c");
}
@Test
public void with_logicalCast_andAsAlias() {
- List cols = DSelectColumnsParser.parse("name , concat(status,'-end')::String as fullName , billingAddress ");
+ Set cols = DSelectColumnsParser.parse("name , concat(status,'-end')::String as fullName , billingAddress ");
assertThat(cols).containsExactly("name", "concat(status,'-end')::String as fullName", "billingAddress");
}
diff --git a/ebean-core/src/test/java/org/tests/batchload/TestQueryJoin.java b/ebean-core/src/test/java/org/tests/batchload/TestQueryJoin.java
index 1cbe7fd48..81bac2193 100644
--- a/ebean-core/src/test/java/org/tests/batchload/TestQueryJoin.java
+++ b/ebean-core/src/test/java/org/tests/batchload/TestQueryJoin.java
@@ -28,7 +28,7 @@ public class TestQueryJoin extends BaseTestCase {
Query query = Ebean.find(Order.class).select("status")
// .join("details","+query(10)")
- .fetch("customer", "+lazy(10) name, status").fetch("customer.contacts").order().asc("id");
+ .fetch("customer", "+lazy(10), name, status").fetch("customer.contacts").order().asc("id");
// .join("customer.billingAddress");
List list = query.findList();
diff --git a/ebean-core/src/test/java/org/tests/model/interfaces/SelfManyMany.java b/ebean-core/src/test/java/org/tests/model/interfaces/SelfManyMany.java
new file mode 100644
index 000000000..6cfc52193
--- /dev/null
+++ b/ebean-core/src/test/java/org/tests/model/interfaces/SelfManyMany.java
@@ -0,0 +1,40 @@
+package org.tests.model.interfaces;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import java.util.List;
+
+@Entity
+public class SelfManyMany {
+
+ @Id
+ private long id;
+
+ private final String name;
+
+ @ManyToMany
+ // requires explicit @JoinTable
+ @JoinTable(name = "self_many_bridge",
+ joinColumns = @JoinColumn(name = "self_1_id"),
+ inverseJoinColumns = @JoinColumn(name = "self_2_id"))
+ private List related;
+
+ public SelfManyMany(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List getRelated() {
+ return related;
+ }
+}
diff --git a/ebean-core/src/test/java/org/tests/model/interfaces/TestSelfMany.java b/ebean-core/src/test/java/org/tests/model/interfaces/TestSelfMany.java
new file mode 100644
index 000000000..e12c47cfd
--- /dev/null
+++ b/ebean-core/src/test/java/org/tests/model/interfaces/TestSelfMany.java
@@ -0,0 +1,15 @@
+package org.tests.model.interfaces;
+
+import io.ebean.BaseTestCase;
+import io.ebean.DB;
+import org.junit.Test;
+
+public class TestSelfMany extends BaseTestCase {
+
+ @Test
+ public void self_manyToMany() {
+
+ SelfManyMany m = new SelfManyMany("1");
+ DB.save(m);
+ }
+}
diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml
index c6039a3ca..c343386bf 100644
--- a/ebean-ddl-generator/pom.xml
+++ b/ebean-ddl-generator/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean ddl generation
@@ -29,14 +29,14 @@
io.ebean
ebean-core-type
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
diff --git a/ebean-externalmapping-api/pom.xml b/ebean-externalmapping-api/pom.xml
index b7229936c..fd23c73a2 100644
--- a/ebean-externalmapping-api/pom.xml
+++ b/ebean-externalmapping-api/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean external mapping api
diff --git a/ebean-externalmapping-xml/pom.xml b/ebean-externalmapping-xml/pom.xml
index 7364bff24..806a215df 100644
--- a/ebean-externalmapping-xml/pom.xml
+++ b/ebean-externalmapping-xml/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
@@ -33,7 +33,7 @@
io.ebean
ebean-externalmapping-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
@@ -59,14 +59,14 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
io.ebean
ebean-ddl-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
diff --git a/ebean-postgis/pom.xml b/ebean-postgis/pom.xml
index 1240f27fe..a6a88a75f 100644
--- a/ebean-postgis/pom.xml
+++ b/ebean-postgis/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean postgis
@@ -24,7 +24,7 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
@@ -75,7 +75,7 @@
io.ebean
ebean-test
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
diff --git a/ebean-querybean/pom.xml b/ebean-querybean/pom.xml
index 3cd58500d..edcd84379 100644
--- a/ebean-querybean/pom.xml
+++ b/ebean-querybean/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
@@ -27,7 +27,7 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
@@ -67,14 +67,14 @@
io.ebean
ebean-ddl-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
io.ebean
querybean-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
diff --git a/ebean-redis/pom.xml b/ebean-redis/pom.xml
index 35d45e38a..e76555b30 100644
--- a/ebean-redis/pom.xml
+++ b/ebean-redis/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean-redis
@@ -22,35 +22,35 @@
io.ebean
ebean-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
ebean-querybean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
io.ebean
querybean-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
io.ebean
ebean-test
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml
index 0c3632dd5..6809737df 100644
--- a/ebean-test/pom.xml
+++ b/ebean-test/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
@@ -43,14 +43,14 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
provided
io.ebean
ebean-ddl-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
diff --git a/ebean/pom.xml b/ebean/pom.xml
index 5732d2910..9cc0b0a60 100644
--- a/ebean/pom.xml
+++ b/ebean/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
ebean composite
@@ -22,34 +22,20 @@
io.ebean
ebean-api
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
io.ebean
ebean-querybean
- 12.6.7-SNAPSHOT
-
-
-
-
- io.ebean
- ebean-ddl-generator
- 12.6.7-SNAPSHOT
-
-
-
-
- io.ebean
- ebean-autotune
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
diff --git a/kotlin-querybean-generator/pom.xml b/kotlin-querybean-generator/pom.xml
index 5d6336d29..7e37844df 100644
--- a/kotlin-querybean-generator/pom.xml
+++ b/kotlin-querybean-generator/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
kotlin querybean generator
@@ -29,7 +29,7 @@
io.ebean
ebean-querybean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
@@ -43,7 +43,7 @@
io.ebean
ebean-core
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
@@ -64,7 +64,7 @@
io.ebean
ebean-ddl-generator
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
test
diff --git a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
index 8524a59f9..ee21711d2 100644
--- a/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
+++ b/kotlin-querybean-generator/src/main/java/io/ebean/querybean/generator/SimpleQueryBeanWriter.java
@@ -8,6 +8,9 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -42,6 +45,23 @@ class SimpleQueryBeanWriter {
"kotlin.Char"
};
+ // These are special classes under Kotlin, and are auto-imported, same as
+ // java.lang under Java
+ private static final Set kotlinBlackListedImports = Collections.unmodifiableSet(
+ new HashSet<>(
+ Arrays.asList(
+ "java.util.ArrayList",
+ "java.util.HashMap",
+ "java.util.HashSet",
+ "java.util.LinkedHashMap",
+ "java.util.LinkedHashSet",
+ "java.util.List",
+ "java.util.Map",
+ "java.util.Set"
+ )
+ )
+ );
+
private final Set importTypes = new TreeSet<>();
private final List properties = new ArrayList<>();
@@ -158,6 +178,7 @@ class SimpleQueryBeanWriter {
importTypes.add(kotlinTypes[i]);
}
}
+ importTypes.removeAll(kotlinBlackListedImports);
}
private boolean isEntity() {
diff --git a/pom.xml b/pom.xml
index c9e885454..6222be793 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
io.ebean
ebean-parent
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
pom
ebean parent
diff --git a/querybean-generator/pom.xml b/querybean-generator/pom.xml
index 52c966bea..adee59843 100644
--- a/querybean-generator/pom.xml
+++ b/querybean-generator/pom.xml
@@ -4,7 +4,7 @@
ebean-parent
io.ebean
- 12.6.7-SNAPSHOT
+ 12.6.8-SNAPSHOT
querybean generator