Compare commits

..
13 Commits
Author SHA1 Message Date
Rob Bygrave 77383f4d29 Version 14.6.0 2024-09-17 22:23:13 +12:00
Rob Bygrave 29fcbbfe97 Bump ebean-agent to 14.6.0 2024-09-17 22:09:44 +12:00
Rob BygraveandGitHub d9e0a35efb Merge pull request #3481 from ebean-orm/feature/boostrap-service
Use io.ebean.service.BootstrapService as common marker interface for service loading bootstrapped services
2024-09-17 22:03:52 +12:00
Rob BygraveandGitHub 0c01ecbac7 Merge pull request #3478 from ebean-orm/feature/3462
#3462 Add Paging as alternative to maxRows + firstRow + orderBy
2024-09-17 22:03:13 +12:00
Rob BygraveandGitHub 5095583cc8 Merge pull request #3473 from ebean-orm/feature/3455-query-beans-improvement
#3455 - Improve query beans such that filterMany() expressions are only on ToMany relationships
2024-09-17 22:02:40 +12:00
Rob Bygrave 92f04a2353 Use io.ebean.service.BootstrapService as common marker interface for service loading bootstrapped services 2024-09-17 21:58:19 +12:00
Rob BygraveandGitHub acbce35182 Merge pull request #3480 from ebean-orm/feature/emptylist
Change EmptyPagedList to be deprecated from public use
2024-09-16 21:07:40 +12:00
Rob Bygrave d6165f4b17 Change EmptyPagedList to be deprecated from public use
This should never have been public really
2024-09-16 20:58:40 +12:00
Rob Bygrave 95656360a9 Mark OrderBy constructors as deprecated
The plan is to migrate OrderBy into an interface
2024-09-15 19:21:17 +12:00
Rob Bygrave 65d7df5488 #3462 Add Paging as alternative to maxRows + firstRow + orderBy
Paging is an alternative to specifying the maxRows + firstRow + orderBy on a query.

Example:
```java

    var orderBy = OrderBy.of("lastName desc nulls first, firstName asc");
    var paging = Paging.of(0, 100, orderBy);

    DB.find(Contact.class)
      .setPaging(paging)
      .where().startsWith("lastName", "foo")
      .findList();
```
2024-09-12 22:54:35 +12:00
Rob Bygrave 12648cd37d Fix test TestQueryFilterMany 2024-09-12 20:31:37 +12:00
Rob Bygrave a2e66bcb89 #3455 - Improve query beans such that filterMany() expressions are only on ToMany relationships
Use protected helper methods on TQAssocBean for the filterMany() methods generated onto AssocMany beans.
2024-09-10 00:24:41 +12:00
Rob Bygrave 4d79815779 #3455 - Improve query beans such that filterMany() expressions are only on ToMany relationships
Changes the query bean code generation for "Associated beans" to have separate AssocOne and AssocMany for *ToOne and *ToMany relationships.

Moves the filterMany() expressions such that they are only available on the *ToMany relationships.
2024-09-09 23:26:13 +12:00
94 changed files with 886 additions and 517 deletions
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-net-postgis-types</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -41,7 +41,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -60,13 +60,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>composites</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean api</name>
@@ -0,0 +1,50 @@
package io.ebean;
final class DPaging implements Paging {
static final Paging NONE = new DPaging(0, 0, null);
static Paging build(int pgIndex, int pgSize, OrderBy<?> orderBy) {
return new DPaging(pgIndex, pgSize, orderBy);
}
static Paging build(int pgIndex, int pgSize) {
return new DPaging(pgIndex, pgSize, null);
}
private final int pageNumber;
private final int pageSize;
private final OrderBy<?> orderBy;
DPaging(int pageNumber, int pageSize, OrderBy<?> orderBy) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.orderBy = orderBy;
}
@Override
public int pageIndex() {
return pageNumber;
}
@Override
public int pageSize() {
return pageSize;
}
@Override
public OrderBy<?> orderBy() {
return orderBy;
}
@Override
public Paging withPage(int pageNumber) {
return new DPaging(pageNumber, pageSize, orderBy);
}
@Override
public Paging withOrderBy(String orderByClause) {
return new DPaging(pageNumber, pageSize, OrderBy.of(orderByClause));
}
}
@@ -5,8 +5,6 @@ import io.ebean.service.SpiContainer;
import io.ebean.service.SpiContainerFactory;
import jakarta.persistence.PersistenceException;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -157,10 +155,10 @@ public final class DatabaseFactory {
* Create the container instance using the configuration.
*/
private static SpiContainer createContainer(ContainerConfig containerConfig) {
Iterator<SpiContainerFactory> factories = ServiceLoader.load(SpiContainerFactory.class).iterator();
if (factories.hasNext()) {
return factories.next().create(containerConfig);
SpiContainerFactory factory = XBootstrapService.containerFactory();
if (factory == null) {
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
}
throw new IllegalStateException("Service loader didn't find a SpiContainerFactory?");
return factory.create(containerConfig);
}
}
@@ -5,6 +5,8 @@ import java.util.List;
import java.util.concurrent.Future;
/**
* @deprecated migrate to using {@link PagedList#emptyList()} only.
* <p>
* An empty PagedList.
* <p>
* For use in application code when we need to return a PagedList but don't want to
@@ -17,7 +19,8 @@ import java.util.concurrent.Future;
*
* }</pre>
*/
public class EmptyPagedList<T> implements PagedList<T> {
@Deprecated(forRemoval = true)
public final class EmptyPagedList<T> implements PagedList<T> {
@Override
public void loadCount() {
@@ -84,7 +84,7 @@ public interface FetchGroup<T> {
* @return The FetchGroup with the given select clause
*/
static <T> FetchGroup<T> of(Class<T> cls, String select) {
return XServiceProvider.fetchGroupOf(cls, select);
return XBootstrapService.fetchGroupOf(cls, select);
}
/**
@@ -108,14 +108,14 @@ public interface FetchGroup<T> {
* @return The FetchGroupBuilder with the given select clause which we will add fetch clauses to
*/
static <T> FetchGroupBuilder<T> of(Class<T> cls) {
return XServiceProvider.fetchGroupOf(cls);
return XBootstrapService.fetchGroupOf(cls);
}
/**
* Return a query to be used by query beans for constructing FetchGroup.
*/
static <T> SpiFetchGroupQuery<T> queryFor(Class<T> beanType) {
return XServiceProvider.fetchGroupQueryFor(beanType);
return XBootstrapService.fetchGroupQueryFor(beanType);
}
}
+23 -11
View File
@@ -8,13 +8,11 @@ import java.util.Objects;
/**
* Represents an Order By for a Query.
* <p>
* Is a ordered list of OrderBy.Property objects each specifying a property and
* Is an ordered list of OrderBy.Property objects each specifying a property and
* whether it is ascending or descending order.
* </p>
* <p>
* Typically you will not construct an OrderBy yourself but use one that exists
* Typically, you will not construct an OrderBy yourself but use one that exists
* on the Query object.
* </p>
*/
public class OrderBy<T> implements Serializable {
@@ -25,8 +23,22 @@ public class OrderBy<T> implements Serializable {
private final List<Property> list;
/**
* Create an OrderBy parsing the given order by clause.
* <p>
* The order by clause follows SQL order by clause with comma's between each
* property and optionally "asc" or "desc" to represent ascending or
* descending order respectively.
*/
public static <P> OrderBy<P> of(String orderByClause) {
return new OrderBy<>(orderByClause);
}
/**
* @deprecated This method will be removed from public API.
* <p>
* Create an empty OrderBy with no associated query.
*/
@Deprecated(forRemoval = true)
public OrderBy() {
this.list = new ArrayList<>(3);
}
@@ -36,20 +48,17 @@ public class OrderBy<T> implements Serializable {
}
/**
* Create an orderBy parsing the order by clause.
* <p>
* The order by clause follows SQL order by clause with comma's between each
* property and optionally "asc" or "desc" to represent ascending or
* descending order respectively.
* </p>
* @deprecated migrate to {@link OrderBy#of(String)}.
*/
@Deprecated(forRemoval = true)
public OrderBy(String orderByClause) {
this(null, orderByClause);
}
/**
* Construct with a given query and order by clause.
* @deprecated This method will be removed from public API.
*/
@Deprecated(forRemoval = true)
public OrderBy(Query<T> query, String orderByClause) {
this.query = query;
this.list = new ArrayList<>(3);
@@ -110,8 +119,11 @@ public class OrderBy<T> implements Serializable {
}
/**
* @deprecated This method will become internal only API.
* <p>
* Return a copy of this OrderBy with the path trimmed.
*/
@Deprecated(forRemoval = true)
public OrderBy<T> copyWithTrim(String path) {
List<Property> newList = new ArrayList<>(list.size());
for (Property aList : list) {
@@ -0,0 +1,90 @@
package io.ebean;
import io.avaje.lang.Nullable;
/**
* Used to specify Paging on a Query as an alternative to setting each of the
* maxRows, firstRow and orderBy clause via:
* {@link Query#setMaxRows(int)} + {@link Query#setFirstRow(int)} + {@link Query#setOrderBy(OrderBy)}.
* <p>
* Example use:
*
* <pre>{@code
*
* var orderBy = OrderBy.of("lastName desc nulls first, firstName asc");
* var paging = Paging.of(0, 100, orderBy);
*
* new QCustomer()
* .name.isNotNull()
* .setPaging(paging)
* .findList();
*
* }</pre>
*/
public interface Paging {
/**
* Create a Paging with the given page index size and orderBy.
*
* @param pageIndex the page index starting from zero
* @param pageSize the page size (effectively max rows)
* @param orderBy order by for the query result
*/
static Paging of(int pageIndex, int pageSize, @Nullable OrderBy<?> orderBy) {
return DPaging.build(pageIndex, pageSize, orderBy);
}
/**
* Create a Paging with a raw order by clause.
*
* @param pageIndex the page index starting from zero
* @param pageSize the page size (effectively max rows)
* @param orderByClause raw order by clause for ordering the query result
*/
static Paging of(int pageIndex, int pageSize, @Nullable String orderByClause) {
return of(pageIndex, pageSize, OrderBy.of(orderByClause));
}
/**
* Create a Paging that will use the id property for ordering.
*
* @param pageIndex the page index starting from zero
* @param pageSize the page size (effectively max rows)
*/
static Paging of(int pageIndex, int pageSize) {
return DPaging.build(pageIndex, pageSize);
}
/**
* Return a Paging that will not apply any pagination to a query.
*/
static Paging ofNone() {
return DPaging.NONE;
}
/**
* Return the page index.
*/
int pageIndex();
/**
* Return the page size.
*/
int pageSize();
/**
* Return the order by.
*/
OrderBy<?> orderBy();
/**
* Return a Paging using the given page index.
*/
Paging withPage(int pageIndex);
/**
* Return a Paging using the given order by clause.
*/
Paging withOrderBy(String orderByClause);
}
@@ -13,21 +13,21 @@ public interface ProfileLocation {
* Create and return a new ProfileLocation.
*/
static ProfileLocation create() {
return XServiceProvider.profileLocationFactory().create();
return XBootstrapService.profileLocationFactory().create();
}
/**
* Create and return a new ProfileLocation with line number.
*/
static ProfileLocation createWithLine() {
return XServiceProvider.profileLocationFactory().createWithLine();
return XBootstrapService.profileLocationFactory().createWithLine();
}
/**
* Create and return a new ProfileLocation with a given lineNumber and label.
*/
static ProfileLocation create(String label) {
return XServiceProvider.profileLocationFactory().create(label);
return XBootstrapService.profileLocationFactory().create(label);
}
/**
@@ -324,6 +324,8 @@ public interface QueryBuilder<SELF, T> extends QueryBuilderProjection<SELF, T> {
*/
SELF setMaxRows(int maxRows);
SELF setPaging(Paging paging);
/**
* Set RawSql to use for this query.
*/
@@ -22,14 +22,14 @@ public interface RawSqlBuilder {
* resultSet.
*/
static RawSql resultSet(ResultSet resultSet, String... propertyNames) {
return XServiceProvider.rawSql().resultSet(resultSet, propertyNames);
return XBootstrapService.rawSql().resultSet(resultSet, propertyNames);
}
/**
* Create and return a SqlRow based on the resultSet with dbTrueValue and binaryOptimizedUUID options.
*/
static SqlRow sqlRow(ResultSet resultSet, final String dbTrueValue, boolean binaryOptimizedUUID) throws SQLException {
return XServiceProvider.rawSql().sqlRow(resultSet, dbTrueValue, binaryOptimizedUUID);
return XBootstrapService.rawSql().sqlRow(resultSet, dbTrueValue, binaryOptimizedUUID);
}
/**
@@ -38,7 +38,7 @@ public interface RawSqlBuilder {
* this query.
*/
static RawSqlBuilder unparsed(String sql) {
return XServiceProvider.rawSql().unparsed(sql);
return XBootstrapService.rawSql().unparsed(sql);
}
/**
@@ -55,7 +55,7 @@ public interface RawSqlBuilder {
* </p>
*/
static RawSqlBuilder parse(String sql) {
return XServiceProvider.rawSql().parsed(sql);
return XBootstrapService.rawSql().parsed(sql);
}
/**
@@ -0,0 +1,95 @@
package io.ebean;
import io.ebean.metric.MetricFactory;
import io.ebean.service.*;
import java.util.ServiceLoader;
/**
* Bootstrap internal services.
*/
public final class XBootstrapService {
private static final SpiContainerFactory containerFactory;
private static final SpiRawSqlService rawSqlService;
private static final SpiProfileLocationFactory profileLocationFactory;
private static final SpiFetchGroupService fetchGroupService;
private static final MetricFactory metricFactory;
private static final SpiJsonService jsonService;
static {
SpiContainerFactory _factory = null;
SpiRawSqlService _raw = null;
SpiProfileLocationFactory _profile = null;
SpiFetchGroupService _fetch = null;
MetricFactory _metric = null;
SpiJsonService _json = null;
for (BootstrapService extension : ServiceLoader.load(BootstrapService.class)) {
if (extension instanceof SpiContainerFactory) {
_factory = (SpiContainerFactory)extension;
} else if (extension instanceof SpiRawSqlService) {
_raw = (SpiRawSqlService)extension;
} else if (extension instanceof SpiProfileLocationFactory) {
_profile = (SpiProfileLocationFactory)extension;
} else if (extension instanceof SpiFetchGroupService) {
_fetch = (SpiFetchGroupService)extension;
} else if (extension instanceof MetricFactory) {
_metric = (MetricFactory)extension;
} else if (extension instanceof SpiJsonService) {
_json = (SpiJsonService)extension;
}
}
containerFactory = _factory;
rawSqlService = _raw;
profileLocationFactory = _profile;
fetchGroupService = _fetch;
metricFactory = _metric;
jsonService = _json;
}
/**
* Return the MetricFactory found in boostrap service loading.
*/
public static MetricFactory metricFactory() {
return metricFactory;
}
/**
* Return the SpiJsonService found in boostrap service loading.
*/
public static SpiJsonService jsonService() {
return jsonService;
}
static SpiContainerFactory containerFactory() {
return containerFactory;
}
static SpiRawSqlService rawSql() {
return rawSqlService;
}
static SpiProfileLocationFactory profileLocationFactory() {
return profileLocationFactory;
}
/**
* Return the FetchGroup with the given select clause.
*/
static <T> FetchGroup<T> fetchGroupOf(Class<T> cls, String select) {
return fetchGroupService.of(cls, select);
}
/**
* Return the FetchGroupBuilder with the given select clause.
*/
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
return fetchGroupService.of(cls);
}
/**
* Return the FetchGroup Query for building fetch groups via query beans.
*/
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
return fetchGroupService.queryFor(cls);
}
}
@@ -1,76 +0,0 @@
package io.ebean;
import io.ebean.service.SpiFetchGroupQuery;
import io.ebean.service.SpiFetchGroupService;
import io.ebean.service.SpiProfileLocationFactory;
import io.ebean.service.SpiRawSqlService;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Lookup internal services.
*/
final class XServiceProvider {
private static SpiRawSqlService rawSqlService = initRawSql();
private static SpiProfileLocationFactory profileLocationFactory = initProfileLocation();
private static SpiFetchGroupService fetchGroupService = initSpiFetchGroupService();
private static SpiFetchGroupService initSpiFetchGroupService() {
return loadFirstService(SpiFetchGroupService.class);
}
private static SpiRawSqlService initRawSql() {
return loadFirstService(SpiRawSqlService.class);
}
private static SpiProfileLocationFactory initProfileLocation() {
return loadFirstService(SpiProfileLocationFactory.class);
}
private static <T> T loadFirstService(Class<T> cls) {
Iterator<T> loader = ServiceLoader.load(cls).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("No service implementation found for " + cls);
}
/**
* Return the RawSqlService implementation.
*/
static SpiRawSqlService rawSql() {
return rawSqlService;
}
/**
* Return the RawSqlService implementation.
*/
static SpiProfileLocationFactory profileLocationFactory() {
return profileLocationFactory;
}
/**
* Return the FetchGroup with the given select clause.
*/
static <T> FetchGroup<T> fetchGroupOf(Class<T> cls, String select) {
return fetchGroupService.of(cls, select);
}
/**
* Return the FetchGroupBuilder with the given select clause.
*/
static <T> FetchGroupBuilder<T> fetchGroupOf(Class<T> cls) {
return fetchGroupService.of(cls);
}
/**
* Return the FetchGroup Query for building fetch groups via query beans.
*/
static <T> SpiFetchGroupQuery<T> fetchGroupQueryFor(Class<T> cls) {
return fetchGroupService.queryFor(cls);
}
}
@@ -1,17 +1,19 @@
package io.ebean.metric;
import io.ebean.ProfileLocation;
import io.ebean.XBootstrapService;
import io.ebean.service.BootstrapService;
/**
* Factory to create timed metric counters.
*/
public interface MetricFactory {
public interface MetricFactory extends BootstrapService {
/**
* Return the factory instance.
*/
static MetricFactory get() {
return MetricServiceProvider.get();
return XBootstrapService.metricFactory();
}
/**
@@ -1,28 +0,0 @@
package io.ebean.metric;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Lookup MetricFactory service.
*/
final class MetricServiceProvider {
private static final MetricFactory metricFactory = init();
private static MetricFactory init() {
Iterator<MetricFactory> loader = ServiceLoader.load(MetricFactory.class).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("MetricFactory not service loaded?");
}
/**
* Return the MetricFactory implementation.
*/
static MetricFactory get() {
return metricFactory;
}
}
@@ -0,0 +1,7 @@
package io.ebean.service;
/**
* Marker interface for internal services loaded at startup.
*/
public interface BootstrapService {
}
@@ -5,7 +5,7 @@ import io.ebean.config.ContainerConfig;
/**
* Provides shutdown of the entire container.
*/
public interface SpiContainerFactory {
public interface SpiContainerFactory extends BootstrapService {
/**
* Create the Container that builds EbeanServer instances.
@@ -6,7 +6,7 @@ import io.ebean.FetchGroupBuilder;
/**
* Service that parses FetchGroup expressions.
*/
public interface SpiFetchGroupService {
public interface SpiFetchGroupService extends BootstrapService {
/**
* Return the FetchGroup with the given select clause.
@@ -17,7 +17,7 @@ import java.util.Set;
*
* Supports converting between JSON content and simple java Maps/Lists.
*/
public interface SpiJsonService {
public interface SpiJsonService extends BootstrapService {
/**
* Write the nested Map/List as json.
@@ -5,7 +5,7 @@ import io.ebean.ProfileLocation;
/**
* Factory for creating profile locations.
*/
public interface SpiProfileLocationFactory {
public interface SpiProfileLocationFactory extends BootstrapService {
/**
* Create a profile location.
@@ -10,7 +10,7 @@ import java.sql.SQLException;
/**
* Service provided by Ebean for parsing and column mapping raw SQL queries.
*/
public interface SpiRawSqlService {
public interface SpiRawSqlService extends BootstrapService {
/**
* Create based on a JDBC ResultSet.
@@ -3,16 +3,15 @@ package io.ebean.text.json;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.ebean.XBootstrapService;
import io.ebean.service.SpiJsonService;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
/**
@@ -20,16 +19,7 @@ import java.util.Set;
*/
public class EJson {
private static SpiJsonService plugin = init();
private static SpiJsonService init() {
Iterator<SpiJsonService> loader = ServiceLoader.load(SpiJsonService.class).iterator();
if (loader.hasNext()) {
return loader.next();
}
throw new IllegalStateException("No service implementation found for SpiJsonService?");
}
private static final SpiJsonService plugin = XBootstrapService.jsonService();
/**
* Write the nested Map/List as json.
+1 -6
View File
@@ -1,13 +1,8 @@
module io.ebean.api {
uses io.ebean.config.AutoConfigure;
uses io.ebean.config.dbplatform.DatabasePlatformProvider;
uses io.ebean.datasource.DataSourceAlertFactory;
uses io.ebean.metric.MetricFactory;
uses io.ebean.service.SpiContainerFactory;
uses io.ebean.service.SpiRawSqlService;
uses io.ebean.service.SpiProfileLocationFactory;
uses io.ebean.service.SpiFetchGroupService;
uses io.ebean.service.BootstrapService;
uses io.ebean.service.SpiJsonService;
requires transitive java.sql;
@@ -1 +1 @@
ebean-version: 143
ebean-version: 145
+26 -26
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean bom</name>
@@ -89,25 +89,25 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -125,13 +125,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -155,37 +155,37 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<!-- platforms -->
@@ -193,79 +193,79 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
+6 -6
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -46,7 +46,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -159,21 +159,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -33,6 +33,10 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
*/
private final boolean textRoot;
public static <P> ExpressionList<P> forFetchGroup(Query<P> q) {
return new DefaultExpressionList<>(q, null, null, null, false);
}
/**
* Construct for Text root expression list - this handles implicit Bool Should, Must etc.
*/
@@ -2,32 +2,10 @@ package io.ebeaninternal.server.query;
import io.avaje.lang.NonNullApi;
import io.avaje.lang.Nullable;
import io.ebean.CacheMode;
import io.ebean.CountDistinctOrder;
import io.ebean.Database;
import io.ebean.DtoQuery;
import io.ebean.Expression;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebean.FetchConfig;
import io.ebean.FetchGroup;
import io.ebean.FetchPath;
import io.ebean.FutureIds;
import io.ebean.FutureList;
import io.ebean.FutureRowCount;
import io.ebean.OrderBy;
import io.ebean.PagedList;
import io.ebean.PersistenceContextScope;
import io.ebean.ProfileLocation;
import io.ebean.Query;
import io.ebean.QueryIterator;
import io.ebean.QueryType;
import io.ebean.RawSql;
import io.ebean.Transaction;
import io.ebean.UpdateQuery;
import io.ebean.Version;
import io.ebean.*;
import io.ebean.service.SpiFetchGroupQuery;
import io.ebeaninternal.api.SpiQueryFetch;
import io.ebeaninternal.server.expression.DefaultExpressionList;
import io.ebeaninternal.server.querydefn.OrmQueryDetail;
import io.ebeaninternal.server.querydefn.SpiFetchGroup;
@@ -53,6 +31,7 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
private static final FetchConfig FETCH_LAZY = FetchConfig.ofLazy();
private OrmQueryDetail detail = new OrmQueryDetail();
private OrderBy<T> orderBy;
@Override
public FetchGroup<T> buildFetchGroup() {
@@ -438,7 +417,7 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
@Override
public ExpressionList<T> where() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
return DefaultExpressionList.forFetchGroup(this);
}
@Override
@@ -468,7 +447,10 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
@Override
public OrderBy<T> orderBy() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
if (orderBy == null) {
orderBy = new OrderBy<>();
}
return orderBy;
}
@Override
@@ -506,6 +488,11 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public Query<T> setPaging(Paging paging) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public Query<T> setMapKey(String mapKey) {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
@@ -1827,6 +1827,22 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
return this;
}
@Override
@SuppressWarnings("unchecked")
public Query<T> setPaging(@Nullable Paging paging) {
if (paging != null && paging.pageSize() > 0) {
firstRow = paging.pageIndex() * paging.pageSize();
maxRows = paging.pageSize();
orderBy = (OrderBy<T>) paging.orderBy();
if (orderBy == null || orderBy.isEmpty()) {
// should not be paging without any order by clause so set
// orderById such that the Id property is used
orderById = true;
}
}
return this;
}
@Override
public final String mapKey() {
return mapKey;
+7 -6
View File
@@ -73,11 +73,12 @@ module io.ebean.core {
exports io.ebeaninternal.server.transaction to io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.k8scache;
exports io.ebeaninternal.server.util to io.ebean.querybean;
provides io.ebean.metric.MetricFactory with io.ebeaninternal.server.profile.DMetricFactory;
provides io.ebean.service.SpiContainerFactory with io.ebeaninternal.server.DContainerFactory;
provides io.ebean.service.SpiFetchGroupService with io.ebeaninternal.server.query.DFetchGroupService;
provides io.ebean.service.SpiJsonService with io.ebeaninternal.json.DJsonService;
provides io.ebean.service.SpiProfileLocationFactory with io.ebeaninternal.server.profile.DProfileLocationFactory;
provides io.ebean.service.SpiRawSqlService with io.ebeaninternal.server.rawsql.DRawSqlService;
provides io.ebean.service.BootstrapService with
io.ebeaninternal.server.DContainerFactory,
io.ebeaninternal.server.query.DFetchGroupService,
io.ebeaninternal.server.profile.DProfileLocationFactory,
io.ebeaninternal.server.rawsql.DRawSqlService,
io.ebeaninternal.server.profile.DMetricFactory,
io.ebeaninternal.json.DJsonService;
}
@@ -1 +0,0 @@
io.ebeaninternal.server.profile.DMetricFactory
@@ -0,0 +1,6 @@
io.ebeaninternal.server.DContainerFactory
io.ebeaninternal.server.rawsql.DRawSqlService
io.ebeaninternal.server.query.DFetchGroupService
io.ebeaninternal.server.profile.DProfileLocationFactory
io.ebeaninternal.server.profile.DMetricFactory
io.ebeaninternal.json.DJsonService
@@ -1 +0,0 @@
io.ebeaninternal.server.DContainerFactory
@@ -1 +0,0 @@
io.ebeaninternal.server.query.DFetchGroupService
@@ -1 +0,0 @@
io.ebeaninternal.json.DJsonService
@@ -1 +0,0 @@
io.ebeaninternal.server.profile.DProfileLocationFactory
@@ -1 +0,0 @@
io.ebeaninternal.server.rawsql.DRawSqlService
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean net postgis types</name>
@@ -19,14 +19,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -54,7 +54,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -78,7 +78,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.5.2</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean postgis types</name>
@@ -19,14 +19,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -62,7 +62,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -86,7 +86,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.5.2</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -63,14 +63,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -84,7 +84,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -100,7 +100,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.5.2</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
@@ -319,6 +319,12 @@ public abstract class QueryBean<T, R> implements IQueryBean<T, R> {
return root;
}
@Override
public R setPaging(Paging paging) {
query.setPaging(paging);
return root;
}
@Override
public final R setMaxRows(int maxRows) {
query.setMaxRows(maxRows);
@@ -1,5 +1,6 @@
package io.ebean.typequery;
import io.ebean.Expr;
import io.ebean.ExpressionList;
import io.ebean.FetchConfig;
import io.ebean.FetchGroup;
@@ -188,102 +189,36 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
return set;
}
/**
* Apply a filter when fetching these beans.
*/
public final R filterMany(ExpressionList<T> filter) {
protected final R _filterMany(ExpressionList<T> filter) {
@SuppressWarnings("unchecked")
ExpressionList<T> expressionList = (ExpressionList<T>) expr().filterMany(_name);
expressionList.addAll(filter);
return _root;
}
/**
* @deprecated for removal - migrate to {@link #filterManyRaw(String, Object...)}.
* <p>
* Apply a filter when fetching these beans.
* <p>
* The expressions can use any valid Ebean expression and contain
* placeholders for bind values using <code>?</code> or <code>?1</code> style.
* </p>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("firstName istartsWith ?", "Rob")
* .findList();
*
* }</pre>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("whenCreated inRange ? to ?", startDate, endDate)
* .findList();
*
* }</pre>
*
* @param expressions The expressions including and, or, not etc with ? and ?1 bind params.
* @param params The bind parameter values
*/
@Deprecated(forRemoval = true)
public final R filterMany(String expressions, Object... params) {
protected final R _filterMany(String expressions, Object... params) {
expr().filterMany(_name, expressions, params);
return _root;
}
/**
* Add filter expressions for the many path. The expressions can include SQL functions if
* desired and the property names are translated to column names.
* <p>
* The expressions can contain placeholders for bind values using <code>?</code> or <code>?1</code> style.
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Shrek")
* .contacts.filterManyRaw("status = ? and firstName like ?", Contact.Status.NEW, "Rob%")
* .findList();
*
* }</pre>
*
* @param rawExpressions The raw expressions which can include ? and ?1 style bind parameter placeholders
* @param params The parameter values to bind
*/
public final R filterManyRaw(String rawExpressions, Object... params) {
protected final R _filterManyRaw(String rawExpressions, Object... params) {
expr().filterManyRaw(_name, rawExpressions, params);
return _root;
}
/**
* Is empty for a collection property.
* <p>
* This effectively adds a not exists sub-query on the collection property.
* </p>
* <p>
* This expression only works on OneToMany and ManyToMany properties.
* </p>
*/
public final R isEmpty() {
protected final R _isEmpty() {
expr().isEmpty(_name);
return _root;
}
/**
* Is not empty for a collection property.
* <p>
* This effectively adds an exists sub-query on the collection property.
* </p>
* <p>
* This expression only works on OneToMany and ManyToMany properties.
* </p>
*/
public final R isNotEmpty() {
protected final R _isNotEmpty() {
expr().isNotEmpty(_name);
return _root;
}
protected final <S> ExpressionList<S> _newExpressionList() {
return Expr.factory().expressionList();
}
}
@@ -0,0 +1,94 @@
package io.ebean.typequery;
import io.ebean.ExpressionList;
/**
* Expressions for Query Bean ToMany relationships.
*
* @param <T> The entity bean type
* @param <R> The root query bean type
*/
public interface TQAssocMany<T, R, QB> {
/**
* Filter the beans fetched for this relationship.
*
* @param filter The filter to apply
*/
R filterMany(java.util.function.Consumer<QB> filter);
/**
* Filter the beans fetched for this relationship.
*/
R filterMany(ExpressionList<T> filter);
/**
* @param expressions The expressions including and, or, not etc with ? and ?1 bind params.
* @param params The bind parameter values
* @deprecated for removal - migrate to {@link #filterManyRaw(String, Object...)}.
* <p>
* Apply a filter when fetching these beans.
* <p>
* The expressions can use any valid Ebean expression and contain
* placeholders for bind values using <code>?</code> or <code>?1</code> style.
* </p>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("firstName istartsWith ?", "Rob")
* .findList();
*
* }</pre>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("whenCreated inRange ? to ?", startDate, endDate)
* .findList();
*
* }</pre>
*/
@Deprecated(forRemoval = true)
R filterMany(String expressions, Object... params);
/**
* Add filter expressions for the many path. The expressions can include SQL functions if
* desired and the property names are translated to column names.
* <p>
* The expressions can contain placeholders for bind values using <code>?</code> or <code>?1</code> style.
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Shrek")
* .contacts.filterManyRaw("status = ? and firstName like ?", Contact.Status.NEW, "Rob%")
* .findList();
*
* }</pre>
*
* @param rawExpressions The raw expressions which can include ? and ?1 style bind parameter placeholders
* @param params The parameter values to bind
*/
R filterManyRaw(String rawExpressions, Object... params);
/**
* Is empty for a collection property.
* <p>
* This effectively adds a not exists sub-query on the collection property.
* <p>
* This expression only works on OneToMany and ManyToMany properties.
*/
R isEmpty();
/**
* Is not empty for a collection property.
* <p>
* This effectively adds an exists sub-query on the collection property.
* <p>
* This expression only works on OneToMany and ManyToMany properties.
*/
R isNotEmpty();
}
@@ -23,6 +23,7 @@ public class QContactTest {
var query = new QContact()
.firstName.isNotNull()
.email.isNotNull()
.others.filterMany(o -> o.something.gt(43))
.inTuples(inTuples)
.query();
@@ -148,6 +148,31 @@ public class QCustomerTest {
assertThat(batchSizes.get(1)).isEqualTo(9);
}
// using QCustomer.forFetchGroup() ... does not need any Ebean Database initialisation etc
// and so is good for when we want to build a static final OrderBy
static final OrderBy<Customer> orderBy = QCustomer.forFetchGroup()
.name.asc()
.email.desc()
.query().orderBy();
@Test
void findWithPaging() {
// OrderBy<Customer> orderBy = new QCustomer().name.asc().email.desc().query().orderBy();
OrderBy<Customer> orderBy = OrderBy.of("name, email desc");
var paging = Paging.of(2, 10, QCustomerTest.orderBy);
LoggedSql.start();
new QCustomer()
.name.isNotNull()
.setPaging(paging)
.findList();
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(1);
assertThat(sql.get(0)).contains("where t0.name is not null order by t0.name, t0.email desc limit 10 offset 20");
}
@Test
public void findIterate() {
+7 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>ebean-redis</artifactId>
@@ -29,35 +29,35 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -72,7 +72,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.3.0</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>ebean-spring-txn</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -77,7 +77,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -99,7 +99,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.3.0</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
+7 -7
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>ebean test</name>
@@ -33,20 +33,20 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -149,14 +149,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -309,7 +309,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.3.0</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
@@ -289,7 +289,7 @@ public class TestQueryFilterMany extends BaseTestCase {
assertEquals(1, sqlList.size());
assertThat(sqlList.get(0)).contains("from o_customer t0 left join o_order t1 on t1.kcustomer_id = t0.id and t1.order_date is not null left join o_customer t2 on t2.id = t1.kcustomer_id where (t1.id is null or (t1.status ");
if (isPostgresCompatible()) {
assertThat(sqlList.get(0)).contains("where (t1.id is null or (t1.status = any(?) order by t0.id");
assertThat(sqlList.get(0)).contains("where (t1.id is null or (t1.status = any(?))) order by t0.id");
} else {
assertThat(sqlList.get(0)).contains("where (t1.id is null or (t1.status in (?))) order by t0.id");
}
@@ -0,0 +1,114 @@
package org.tests.query;
import io.ebean.DB;
import io.ebean.OrderBy;
import io.ebean.Paging;
import io.ebean.test.LoggedSql;
import io.ebean.xtest.BaseTestCase;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Contact;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class TestQueryPaging extends BaseTestCase {
@Test
void example() {
var orderBy = OrderBy.of("lastName desc nulls first, firstName asc");
var paging = Paging.of(0, 100, orderBy);
DB.find(Contact.class)
.setPaging(paging)
.where().startsWith("lastName", "foo")
.findList();
// or instead of findList() use another find method like ...
// findPagedList(), findEach(), findStream(), findMap(), findSet(), findSingleAttributeList(),
var nextPage = paging.withPage(1);
DB.find(Contact.class)
.setPaging(nextPage)
.findList();
}
@Test
void whenNoOrderBy_expect_orderByIdUsed() {
ResetBasicData.reset();
LoggedSql.start();
DB.find(Contact.class).select("lastName").setPaging(Paging.of(0, 4)).findList();
DB.find(Contact.class).select("lastName").setPaging(Paging.of(2, 4)).findList();
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(2);
if (isLimitOffset()) {
assertThat(sql.get(0)).contains("order by t0.id limit 4");
assertThat(sql.get(1)).contains("order by t0.id limit 4 offset 8");
}
}
@Test
void whenOrderBy_expect_noExtraIdInTheOrderBy() {
ResetBasicData.reset();
LoggedSql.start();
DB.find(Contact.class).select("lastName").setPaging(Paging.of(1, 4, "lastName")).findList();
DB.find(Contact.class).select("lastName").setPaging(Paging.of(1, 4, "lastName, id")).findList();
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(2);
if (isLimitOffset()) {
assertThat(sql.get(0)).contains("order by t0.last_name limit 4 offset 4");
assertThat(sql.get(1)).contains("order by t0.last_name, t0.id limit 4 offset 4");
}
}
@Test
void whenNone_expect_noLimitOffsetAtAll() {
ResetBasicData.reset();
LoggedSql.start();
DB.find(Contact.class).select("lastName").setPaging(Paging.ofNone()).findList();
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(1);
assertThat(sql.get(0)).contains("select t0.id, t0.last_name from contact t0;");
}
@Test
void withPage() {
Paging paging = Paging.of(0, 100);
assertThat(paging.pageIndex()).isEqualTo(0);
assertThat(paging.pageSize()).isEqualTo(100);
Paging pg1 = paging.withPage(1);
assertThat(pg1.pageIndex()).isEqualTo(1);
assertThat(pg1.pageSize()).isEqualTo(100);
Paging pg6 = paging.withPage(6);
assertThat(pg6.pageIndex()).isEqualTo(6);
assertThat(pg6.pageSize()).isEqualTo(100);
}
@Test
void withOrderBy() {
Paging pg1 = Paging.of(1, 100);
assertThat(pg1.pageIndex()).isEqualTo(1);
assertThat(pg1.pageSize()).isEqualTo(100);
Paging pgWithOrder = pg1.withOrderBy("lastName desc nulls first, firstName asc");
OrderBy<?> orderBy = pgWithOrder.orderBy();
List<OrderBy.Property> properties = orderBy.getProperties();
assertThat(properties).hasSize(2);
assertThat(properties.get(0).getProperty()).isEqualTo("lastName");
assertThat(properties.get(0).isAscending()).isFalse();
assertThat(properties.get(1).getProperty()).isEqualTo("firstName");
assertThat(properties.get(1).isAscending()).isTrue();
}
}
+2 -2
View File
@@ -15,8 +15,8 @@ mvn -T 4 clean package
mvn -T 4 deploy -pl '!composites,!platforms' -Pcentral -DskipTests -DskipStagingRepositoryClose=true -DstagingProgressTimeoutMinutes=9
## git commit, git tag, git push --tags
git commit -am 'Version 14.5.2'
git tag 14.5.2
git commit -am 'Version 14.6.0'
git tag 14.6.0
git push --tags
## convert to javax
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>kotlin querybean generator</name>
@@ -21,7 +21,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -35,7 +35,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
@@ -56,14 +56,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
+14 -14
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,67 +15,67 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hsqldb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlanywhere</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<!-- Provided scope so that the H2HistoryTrigger can live in Ebean core
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,13 +15,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>platforms</artifactId>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -15,7 +15,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
</dependencies>
+3 -3
View File
@@ -9,7 +9,7 @@
<groupId>io.ebean</groupId>
<artifactId>ebean-parent</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<packaging>pom</packaging>
<name>ebean parent</name>
@@ -53,8 +53,8 @@
<ebean-migration.version>14.2.0</ebean-migration.version>
<ebean-test-containers.version>7.4</ebean-test-containers.version>
<ebean-datasource.version>9.0</ebean-datasource.version>
<ebean-agent.version>14.5.2</ebean-agent.version>
<ebean-maven-plugin.version>14.5.1</ebean-maven-plugin.version>
<ebean-agent.version>14.6.0</ebean-agent.version>
<ebean-maven-plugin.version>14.6.0</ebean-maven-plugin.version>
<surefire.useModulePath>false</surefire.useModulePath>
</properties>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<name>querybean generator</name>
@@ -6,6 +6,8 @@ interface Constants {
String AT_TYPEQUERYBEAN = "@io.ebean.typequery.TypeQueryBean(\"v1\")";
String GENERATED = "io.ebean.typequery.Generated";
String ONE_TO_MANY = "jakarta.persistence.OneToMany";
String MANY_TO_MANY = "jakarta.persistence.ManyToMany";
String MAPPED_SUPERCLASS = "jakarta.persistence.MappedSuperclass";
String DISCRIMINATOR_VALUE = "jakarta.persistence.DiscriminatorValue";
String INHERITANCE = "jakarta.persistence.Inheritance";
@@ -217,6 +217,10 @@ class ProcessingContext implements Constants {
return hasAnnotations(field, DBARRAY);
}
private static boolean dbToMany(Element field) {
return hasAnnotations(field, ONE_TO_MANY, MANY_TO_MANY);
}
/**
* Escape the type (e.g. java.lang.String) from the TypeMirror toString().
*/
@@ -239,6 +243,7 @@ class ProcessingContext implements Constants {
}
PropertyType getPropertyType(VariableElement field) {
boolean toMany = dbToMany(field);
if (dbJsonField(field)) {
return propertyTypeMap.getDbJsonType();
}
@@ -278,13 +283,15 @@ class ProcessingContext implements Constants {
if (targetEntity != null) {
final TypeElement element = elementUtils.getTypeElement(targetEntity);
if (isEntityOrEmbedded(element)) {
return createPropertyTypeAssoc(typeDef(element.asType()));
boolean embeddable = isEmbeddable(element);
return createPropertyTypeAssoc(embeddable, toMany, typeDef(element.asType()));
}
}
if (isEntityOrEmbedded(fieldType)) {
// public QAssocContact<QCustomer> contacts;
return createPropertyTypeAssoc(typeDef(typeMirror));
boolean embeddable = isEmbeddable(fieldType);
return createPropertyTypeAssoc(embeddable, toMany, typeDef(typeMirror));
}
final PropertyType result;
@@ -322,16 +329,19 @@ class ProcessingContext implements Constants {
}
private PropertyType createManyTypeAssoc(VariableElement field, DeclaredType declaredType) {
boolean toMany = dbToMany(field);
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (typeArguments.size() == 1) {
Element argElement = typeUtils.asElement(typeArguments.get(0));
if (isEntityOrEmbedded(argElement)) {
return createPropertyTypeAssoc(typeDef(argElement.asType()));
boolean embeddable = isEmbeddable(argElement);
return createPropertyTypeAssoc(embeddable, toMany, typeDef(argElement.asType()));
}
} else if (typeArguments.size() == 2) {
Element argElement = typeUtils.asElement(typeArguments.get(1));
if (isEntityOrEmbedded(argElement)) {
return createPropertyTypeAssoc(typeDef(argElement.asType()));
boolean embeddable = isEmbeddable(argElement);
return createPropertyTypeAssoc(embeddable, toMany, typeDef(argElement.asType()));
}
}
return null;
@@ -359,7 +369,7 @@ class ProcessingContext implements Constants {
/**
* Create the QAssoc PropertyType.
*/
private PropertyType createPropertyTypeAssoc(String fullName) {
private PropertyType createPropertyTypeAssoc(boolean embeddable, boolean toMany, String fullName) {
TypeElement typeElement = elementUtils.getTypeElement(fullName);
String type;
if (typeElement.getNestingKind().isNested()) {
@@ -368,8 +378,9 @@ class ProcessingContext implements Constants {
type = typeElement.getQualifiedName().toString();
}
String suffix = toMany ? "Many" : embeddable ? "": "One";
String[] split = Split.split(type);
String propertyName = "Q" + split[1] + ".Assoc";
String propertyName = "Q" + split[1] + ".Assoc" + suffix;
String importName = split[0] + ".query.Q" + split[1];
return new PropertyTypeAssoc(propertyName, importName);
}
@@ -267,42 +267,75 @@ class SimpleQueryBeanWriter {
if (embeddable) {
writer.append(" public static final class Assoc<R> extends io.ebean.typequery.TQAssoc<%s,R> {", beanFullName).eol();
} else {
writer.append(" public static final class Assoc<R> extends io.ebean.typequery.TQAssocBean<%s,R,Q%s> {", beanFullName, shortInnerName).eol();
writer.append(" public static abstract class Assoc<R> extends io.ebean.typequery.TQAssocBean<%s,R,Q%s> {", beanFullName, shortInnerName).eol();
}
writer.eol();
for (PropertyMeta property : properties) {
writer.append(" ");
property.writeFieldDefn(writer, shortName, true, fullyQualify);
writer.eol();
}
writer.eol();
writeAssocBeanConstructor();
writeAssocBeanConstructor("protected Assoc");
writeAssocBeanFetch();
writer.append(" }").eol();
if (!embeddable) {
writeAssocFilterMany();
writeAssocBeanFetch();
writeAssocOne();
writeAssocMany();
}
}
private void writeAssocOne() {
writer.eol();
writer.append(" /** Associated ToOne query bean */").eol();
writer.append(" ").append(Constants.AT_GENERATED).eol();
writer.append(" ").append(Constants.AT_TYPEQUERYBEAN).eol();
writer.append(" public static final class AssocOne<R> extends Assoc<R> {").eol();
writeAssocBeanConstructor("public AssocOne");
writer.append(" }").eol();
}
private void writeAssocMany() {
writer.eol();
writer.append(" /** Associated ToMany query bean */").eol();
writer.append(" ").append(Constants.AT_GENERATED).eol();
writer.append(" ").append(Constants.AT_TYPEQUERYBEAN).eol();
writer.append(" public static final class AssocMany<R> extends Assoc<R> implements io.ebean.typequery.TQAssocMany<%s, R, Q%s>{", beanFullName, shortInnerName).eol();
writeAssocBeanConstructor("public AssocMany");
writeAssocFilterMany();
writer.append(" }").eol();
}
private void writeAssocFilterMany() {
writer.eol();
writer.append(" @SuppressWarnings({\"unchecked\", \"rawtypes\"})").eol();
writer.append(" @Override").eol();
writer.append(" public R filterMany(java.util.function.Consumer<Q%s> apply) {", shortName).eol();
writer.append(" final io.ebean.ExpressionList list = io.ebean.Expr.factory().expressionList();", shortName).eol();
writer.append(" final var qb = new Q%s(list);", shortName).eol();
writer.append(" apply.accept(qb);").eol();
writer.append(" expr().filterMany(_name).addAll(list);").eol();
writer.append(" return _root;").eol();
writer.append(" final io.ebean.ExpressionList<%s> list = _newExpressionList();", beanFullName).eol();
writer.append(" apply.accept(new Q%s(list));", shortName).eol();
writer.append(" return _filterMany(list);").eol();
writer.append(" }").eol();
writer.eol();
writer.append(" @Override").eol();
writer.append(" public R filterMany(io.ebean.ExpressionList<%s> filter) { return _filterMany(filter); }", beanFullName).eol();
writer.eol();
writer.append(" @Override").eol();
writer.append(" public R filterManyRaw(String rawExpressions, Object... params) { return _filterManyRaw(rawExpressions, params); }").eol();
writer.eol();
writer.append(" @Override").eol();
writer.append(" @Deprecated(forRemoval = true)").eol();
writer.append(" public R filterMany(String expressions, Object... params) { return _filterMany(expressions, params); }").eol();
writer.eol();
writer.append(" @Override").eol();
writer.append(" public R isEmpty() { return _isEmpty(); }").eol();
writer.eol();
writer.append(" @Override").eol();
writer.append(" public R isNotEmpty() { return _isNotEmpty(); }").eol();
}
private void writeAssocBeanConstructor() {
writer.append(" public Assoc(String name, R root) {").eol();
writer.append(" super(name, root);").eol();
writer.append(" }").eol().eol();
writer.append(" public Assoc(String name, R root, String prefix) {").eol();
writer.append(" super(name, root, prefix);").eol();
writer.append(" }").eol();
private void writeAssocBeanConstructor(String prefix) {
writer.append(" %s(String name, R root) { super(name, root); }", prefix).eol();
writer.append(" %s(String name, R root, String prefix) { super(name, root, prefix); }", prefix).eol();
}
private void writeAssocBeanFetch() {
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>tests</artifactId>
+5 -5
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>tests</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>test-java16</artifactId>
@@ -18,7 +18,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -30,14 +30,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>provided</scope>
</dependency>
@@ -52,7 +52,7 @@
<extensions>true</extensions>
<configuration>
<tiles>
<tile>io.ebean.tile:enhancement:14.3.0</tile>
<tile>io.ebean.tile:enhancement:14.6.0</tile>
</tiles>
</configuration>
</plugin>
+3 -3
View File
@@ -6,7 +6,7 @@
<parent>
<artifactId>tests</artifactId>
<groupId>io.ebean</groupId>
<version>14.5.2</version>
<version>14.6.0</version>
</parent>
<artifactId>test-kotlin</artifactId>
@@ -40,7 +40,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
</dependency>
<dependency>
@@ -53,7 +53,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>14.5.2</version>
<version>14.6.0</version>
<scope>test</scope>
</dependency>