Compare commits

..
Author SHA1 Message Date
Rob Bygrave 4bcfa80df2 Merge pull request #3594 from ebean-orm/feature/improved-readOnly-immutable-DisabledLazyLoad
Modify disableLazyLoad to throw LazyInitialisationException instead o…
2025-04-29 23:32:46 +12:00
Rob Bygrave c583879d57 Modify disableLazyLoad to throw LazyInitialisationException instead of returning null
Modify such that accessing an unloaded property throws a LazyInitialisationException. This includes ToMany collections that where previously initialised as empty collections (that didn't lazy load).

This change brings the disableLazyLoad behaviour in line with the unmodifiable behaviour.

It does mean that the use case of bulk mapping from entities to DTOs via something like MapStruct will no longer work nicely (mapping nulls and empty lists versus LazyInitialisationException).
2025-03-18 23:46:42 +13:00
136 changed files with 549 additions and 926 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java_version: [GA,EA]
java_version: [GA,EA,23]
os: [ubuntu-latest]
steps:
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-clickhouse</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-db2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-hana</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mariadb</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-mysql</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-net-postgis-types</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-nuodb</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-oracle</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -22,13 +22,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -47,19 +47,19 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlite</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -42,13 +42,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<relativePath>../..</relativePath>
</parent>
@@ -17,13 +17,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -41,7 +41,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -60,13 +60,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<artifactId>composites</artifactId>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean api</name>
@@ -35,7 +35,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-config</artifactId>
<version>4.0</version>
<version>3.12</version>
</dependency>
<dependency>
@@ -2019,11 +2019,6 @@ public interface DatabaseBuilder {
@Deprecated
DatabaseBuilder setQueryPlanTTLSeconds(int queryPlanTTLSeconds);
/**
* Set the EXPLAIN (with options) to use for query plan capture.
*/
DatabaseBuilder queryPlanExplain(String queryPlanExplain);
/**
* Create a new PlatformConfig based of the one held but with overridden properties by reading
* properties with the given path and prefix.
@@ -3049,11 +3044,6 @@ public interface DatabaseBuilder {
*/
int getQueryPlanTTLSeconds();
/**
* Return the EXPLAIN (with options) to use for capturing query plans.
*/
String getQueryPlanExplain();
/**
* Return mapping locations to search for xml mapping via class path search.
*/
@@ -1,74 +0,0 @@
package io.ebean;
import jakarta.persistence.PersistenceException;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* FutureMap represents the result of a background query execution that will
* return a map of entities.
* <p>
* It extends the java.util.concurrent.Future with the ability to cancel the
* query, check if it is finished and get the resulting list waiting for the
* query to finish (ie. the standard features of java.util.concurrent.Future).
* </p>
* <p>
* A simple example:
* </p>
* <pre>{@code
*
* // create a query to find all orders
* Query<Long,Order> query = DB.find(Order.class)
* .setMapKey("id");
*
* // execute the query in a background thread
* // immediately returning the futureMap
* FutureMap<Long,Order> futureMap = query.findFutureMap();
*
* // do something else ...
*
* if (!futureMap.isDone()){
* // we can cancel the query execution. This will cancel
* // the underlying query if that is supported by the JDBC
* // driver and database
* futureMap.cancel(true);
* }
*
* if (!futureMap.isCancelled()){
* // wait for the query to finish and return the map
* Map<Long,Order> map = futureMap.get();
* ...
* }
*
* }</pre>
*/
public interface FutureMap<K, T> extends Future<Map<K, T>> {
/**
* Return the query that is being executed by a background thread.
*/
Query<T> getQuery();
/**
* Same as {@link #get()} but wraps InterruptedException and ExecutionException in the
* unchecked PersistenceException.
*
* @return The query list result
* @throws PersistenceException when a InterruptedException or ExecutionException occurs.
*/
Map<K, T> getUnchecked();
/**
* Same as {@link #get(long, TimeUnit)} but wraps InterruptedException
* and ExecutionException in the unchecked PersistenceException.
*
* @return The query list result
* @throws TimeoutException if the wait timed out
* @throws PersistenceException if a InterruptedException or ExecutionException occurs.
*/
Map<K, T> getUnchecked(long timeout, TimeUnit unit) throws TimeoutException;
}
@@ -956,16 +956,6 @@ public interface QueryBuilder<SELF extends QueryBuilder<SELF, T>, T> extends Que
*/
FutureList<T> findFutureList();
/**
* Execute find map query in a background thread.
* <p>
* This query will execute in it's own PersistenceContext and using its own transaction.
* What that means is that it will not share any bean instances with other queries.
*
* @return a Future object for the map result of the query
*/
<K> FutureMap<K,T> findFutureMap();
/**
* Return a PagedList for this query using firstRow and maxRows.
* <p>
@@ -381,11 +381,6 @@ public interface EntityBeanIntercept extends Serializable {
*/
void loadBean(int loadProperty);
/**
* Invoke the lazy loading. This method is synchronised externally.
*/
void loadBeanInternal(int loadProperty, BeanLoader loader);
/**
* Called when a BeanCollection is initialised automatically.
*/
@@ -393,11 +393,6 @@ public final class InterceptReadOnly extends InterceptBase {
}
@Override
public void loadBeanInternal(int loadProperty, BeanLoader loader) {
}
@Override
public void initialisedMany(int propertyIndex) {
loaded[propertyIndex] = true;
@@ -2,6 +2,7 @@ package io.ebean.bean;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.LazyInitialisationException;
import io.ebean.ValuePair;
import jakarta.persistence.EntityNotFoundException;
@@ -59,7 +60,7 @@ public final class InterceptReadWrite extends InterceptBase {
private EntityBean embeddedOwner;
private int embeddedOwnerIndex;
/**
* One of NEW, REF, UPD.
* One of NEW, REFERENCE, LOADED.
*/
private int state;
private boolean forceUpdate;
@@ -645,6 +646,9 @@ public final class InterceptReadWrite extends InterceptBase {
public void loadBean(int loadProperty) {
lock.lock();
try {
if (disableLazyLoad) {
throw new LazyInitialisationException("Property not loaded: " + property(loadProperty));
}
if (beanLoader == null) {
final Database database = DB.byName(ebeanServerName);
if (database == null) {
@@ -668,8 +672,7 @@ public final class InterceptReadWrite extends InterceptBase {
}
}
@Override
public void loadBeanInternal(int loadProperty, BeanLoader loader) {
private void loadBeanInternal(int loadProperty, BeanLoader loader) {
if ((flags[loadProperty] & FLAG_LOADED_PROP) != 0) {
// race condition where multiple threads calling preGetter concurrently
return;
@@ -771,7 +774,7 @@ public final class InterceptReadWrite extends InterceptBase {
@Override
public void preGetter(int propertyIndex) {
preGetterCallback(propertyIndex);
if (state == STATE_NEW || disableLazyLoad) {
if (state == STATE_NEW) {
return;
}
if (!isLoadedProperty(propertyIndex)) {
@@ -1,6 +1,5 @@
package io.ebean.cache;
import java.time.Instant;
import java.util.Set;
/**
@@ -11,11 +10,11 @@ import java.util.Set;
* the query cache entry is treated as invalid.
* </p>
*/
public final class QueryCacheEntry {
public class QueryCacheEntry {
private final Object value;
private final Set<String> dependentTables;
private final Instant timestamp;
private final long timestamp;
/**
* Create with dependent tables and timestamp.
@@ -24,7 +23,7 @@ public final class QueryCacheEntry {
* @param dependentTables The extra tables the query is dependent on (joins to)
* @param timestamp The timestamp that the query uses to check for modifications
*/
public QueryCacheEntry(Object value, Set<String> dependentTables, Instant timestamp) {
public QueryCacheEntry(Object value, Set<String> dependentTables, long timestamp) {
this.value = value;
this.dependentTables = dependentTables;
this.timestamp = timestamp;
@@ -33,21 +32,21 @@ public final class QueryCacheEntry {
/**
* Return the actual query result.
*/
public Object value() {
public Object getValue() {
return value;
}
/**
* Return the tables the query result is dependent on.
*/
public Set<String> dependentTables() {
public Set<String> getDependentTables() {
return dependentTables;
}
/**
* Return the timestamp used to check for modifications on the dependent tables.
*/
public Instant timestamp() {
public long getTimestamp() {
return timestamp;
}
}
@@ -251,7 +251,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
/**
* The default batch size for lazy loading
*/
private int lazyLoadBatchSize = 100;
private int lazyLoadBatchSize = 10;
/**
* The default batch size for 'query joins'.
@@ -481,7 +481,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
* Time to live for query plans - defaults to 5 minutes.
*/
private int queryPlanTTLSeconds = 60 * 5;
private String queryPlanExplain;
/**
* Set to true to globally disable L2 caching (typically for performance testing).
@@ -2152,7 +2151,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
queryPlanCapturePeriodSecs = p.getLong("queryPlan.capturePeriodSecs", queryPlanCapturePeriodSecs);
queryPlanCaptureMaxTimeMillis = p.getLong("queryPlan.captureMaxTimeMillis", queryPlanCaptureMaxTimeMillis);
queryPlanCaptureMaxCount = p.getInt("queryPlan.captureMaxCount", queryPlanCaptureMaxCount);
queryPlanExplain = p.get("queryPlan.explain", queryPlanExplain);
docStoreOnly = p.getBoolean("docStoreOnly", docStoreOnly);
disableL2Cache = p.getBoolean("disableL2Cache", disableL2Cache);
localOnlyL2Cache = p.getBoolean("localOnlyL2Cache", localOnlyL2Cache);
@@ -2404,17 +2402,6 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
return queryPlanTTLSeconds;
}
@Override
public String getQueryPlanExplain() {
return queryPlanExplain;
}
@Override
public DatabaseBuilder queryPlanExplain(String queryPlanExplain) {
this.queryPlanExplain = queryPlanExplain;
return this;
}
@Override
public DatabaseConfig setQueryPlanTTLSeconds(int queryPlanTTLSeconds) {
this.queryPlanTTLSeconds = queryPlanTTLSeconds;
@@ -1,19 +1,18 @@
package io.ebean.meta;
import java.util.*;
import static java.util.Objects.requireNonNull;
import java.util.HashSet;
import java.util.Set;
/**
* Initiate query plan collection for plans by their hash or all query plans.
*/
public class QueryPlanInit {
private final Map<String,Long> hashes = new HashMap<>();
private boolean all;
private long defaultThresholdMicros;
private Set<String> hashes = new HashSet<>();
private long thresholdMicros;
/**
* Return true if this initiates bind collection on all query plans.
@@ -30,74 +29,39 @@ public class QueryPlanInit {
}
/**
* Return the default query execution time threshold which must be exceeded to initiate
* Return the query execution time threshold which must be exceeded to initiate
* query plan collection.
*/
public long thresholdMicros() {
return defaultThresholdMicros;
return thresholdMicros;
}
/**
* Set the default query execution time threshold which must be exceeded to initiate
* Set the query execution time threshold which must be exceeded to initiate
* query plan collection.
*/
public void thresholdMicros(long thresholdMicros) {
this.defaultThresholdMicros = thresholdMicros;
this.thresholdMicros = thresholdMicros;
}
/**
* Return true if the query plan should be initiated based on it's hash.
*/
public boolean includeHash(String hash) {
return all || hashes.containsKey(hash);
return all || hashes.contains(hash);
}
/**
* Return the specific hashes that we want to collect query plans on.
*
* @param hash The hash of the query plan.
* @param thresholdMicros The threshold in micros to use.
*/
public void add(String hash, long thresholdMicros) {
requireNonNull(hash);
if (!"all".equals(hash)) {
hashes.put(hash, thresholdMicros);
} else {
all = true;
if (thresholdMicros > 0) {
defaultThresholdMicros = thresholdMicros;
}
}
public Set<String> hashes() {
return hashes;
}
/**
* Remove a hash from this request.
* Set the specific hashes that we want to collect query plans on.
*/
public void remove(String hash) {
hashes.remove(hash);
}
/**
* Return the threshold in micros to use for the given hash.
*/
public long thresholdMicros(String hash) {
Long threshold = hashes.get(hash);
return threshold == null || threshold < 1 ? defaultThresholdMicros : threshold;
}
/**
* Return true if there are no registered hashes and not collect <em>All</em> plans.
*/
public boolean isEmpty() {
return !all && hashes.isEmpty();
}
@Override
public String toString() {
return "QueryPlanInit{" +
"all=" + all +
", hashes=" + hashes +
", thresholdMicros=" + defaultThresholdMicros +
'}';
public void hashes(Set<String> hashes) {
this.hashes = hashes;
}
}
@@ -77,8 +77,6 @@ class DatabaseConfigTest {
props.setProperty("readOnlyDatabase", "true");
props.setProperty("lengthCheck", "ON");
props.setProperty("includeLabelInSql", "false");
props.setProperty("lazyLoadBatchSize", "50");
props.setProperty("queryBatchSize", "60");
props.setProperty("queryPlan.enable", "true");
props.setProperty("queryPlan.thresholdMicros", "10000");
@@ -86,7 +84,6 @@ class DatabaseConfigTest {
props.setProperty("queryPlan.capturePeriodSecs", "42");
props.setProperty("queryPlan.captureMaxTimeMillis", "560");
props.setProperty("queryPlan.captureMaxCount", "7");
props.setProperty("queryPlan.explain", "explain (verbose)");
config.loadFromProperties(props);
@@ -102,8 +99,6 @@ class DatabaseConfigTest {
assertTrue(settings.readOnlyDatabase());
assertFalse(settings.isIncludeLabelInSql());
assertThat(settings.getLengthCheck()).isEqualTo(LengthCheck.ON);
assertThat(settings.getLazyLoadBatchSize()).isEqualTo(50);
assertThat(settings.getQueryBatchSize()).isEqualTo(60);
assertTrue(settings.isIdGeneratorAutomatic());
assertFalse(settings.getPlatformConfig().isCaseSensitiveCollation());
@@ -134,18 +129,15 @@ class DatabaseConfigTest {
assertEquals(42, settings.getQueryPlanCapturePeriodSecs());
assertEquals(560, settings.getQueryPlanCaptureMaxTimeMillis());
assertEquals(7, settings.getQueryPlanCaptureMaxCount());
assertEquals("explain (verbose)", settings.getQueryPlanExplain());
assertThat(settings.getMappingLocations()).containsExactly("classpath:/foo","bar");
config.persistBatch(PersistBatch.NONE)
.persistBatchOnCascade(PersistBatch.NONE)
.lengthCheck(LengthCheck.ON)
.lengthCheck(LengthCheck.UTF8)
.queryPlanExplain("explain (buffers)");
.lengthCheck(LengthCheck.UTF8);
assertThat(config.settings().getQueryPlanExplain()).isEqualTo("explain (buffers)");
Properties props1 = new Properties();
props1.setProperty("ebean.persistBatch", "ALL");
props1.setProperty("ebean.persistBatchOnCascade", "ALL");
@@ -183,8 +175,6 @@ class DatabaseConfigTest {
assertTrue(config.getPlatformConfig().isCaseSensitiveCollation());
assertTrue(config.isAutoLoadModuleInfo());
assertTrue(config.isLoadModuleInfo());
assertThat(config.getLazyLoadBatchSize()).isEqualTo(100);
assertThat(config.getQueryBatchSize()).isEqualTo(100);
assertFalse(config.isQueryPlanEnable());
assertEquals(Long.MAX_VALUE, config.getQueryPlanThresholdMicros());
@@ -192,7 +182,6 @@ class DatabaseConfigTest {
assertEquals(600, config.getQueryPlanCapturePeriodSecs());
assertEquals(10000L, config.getQueryPlanCaptureMaxTimeMillis());
assertEquals(10, config.getQueryPlanCaptureMaxCount());
assertThat(config.getQueryPlanExplain()).isNull();
assertThat(config.getLengthCheck()).isEqualTo(LengthCheck.OFF);
assertTrue(config.isIncludeLabelInSql());
@@ -203,10 +192,6 @@ class DatabaseConfigTest {
assertTrue(config.isAutoPersistUpdates());
config.setSkipDataSourceCheck(true);
assertTrue(config.skipDataSourceCheck());
config.lazyLoadBatchSize(20);
assertThat(config.getLazyLoadBatchSize()).isEqualTo(20);
config.queryBatchSize(30);
assertThat(config.getQueryBatchSize()).isEqualTo(30);
}
@Test
@@ -1,43 +0,0 @@
package io.ebean.meta;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class QueryPlanInitTest {
@Test
void initialQueryPlanInit() {
var init = new QueryPlanInit();
assertThat(init.isEmpty()).isTrue();
assertThat(init.isAll()).isFalse();
assertThat(init.thresholdMicros()).isEqualTo(0L);
}
@Test
void add_all() {
var init = new QueryPlanInit();
init.add("all", 57L);
assertThat(init.isEmpty()).isFalse();
assertThat(init.isAll()).isTrue();
assertThat(init.thresholdMicros()).isEqualTo(57L);
}
@Test
void addWithThresholds() {
var init = new QueryPlanInit();
init.thresholdMicros(1000);
init.add("xOne", 0);
init.add("xTwo", 2000L);
assertThat(init.isEmpty()).isFalse();
assertThat(init.isAll()).isFalse();
assertThat(init.includeHash("xJunk")).isFalse();
assertThat(init.includeHash("xOne")).isTrue();
assertThat(init.includeHash("xTwo")).isTrue();
assertThat(init.thresholdMicros("xJunk")).isEqualTo(1000L);
assertThat(init.thresholdMicros("xOne")).isEqualTo(1000L);
assertThat(init.thresholdMicros("xTwo")).isEqualTo(2000L);
}
}
+26 -26
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean bom</name>
@@ -89,25 +89,25 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -125,13 +125,13 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -155,37 +155,37 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>kotlin-querybean-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-redis</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-spring-txn</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<!-- platforms -->
@@ -193,79 +193,79 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-clickhouse</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-db2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-h2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-hana</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mariadb</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-mysql</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-nuodb</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-oracle</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-postgis-types</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlite</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-sqlserver</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
</dependencies>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<artifactId>ebean-core-type</artifactId>
@@ -16,7 +16,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
+6 -6
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<artifactId>ebean-core</artifactId>
@@ -22,7 +22,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -46,7 +46,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -159,21 +159,21 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-sqlserver</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
@@ -348,8 +348,6 @@ public interface SpiEbeanServer extends SpiServer, BeanCollectionLoader {
<T> FutureList<T> findFutureList(SpiQuery<T> query);
<K, T> FutureMap<K, T> findFutureMap(SpiQuery<T> query);
<T> PagedList<T> findPagedList(SpiQuery<T> query);
<T> Set<T> findSet(SpiQuery<T> query);
@@ -14,7 +14,6 @@ import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.Instant;
/**
* Extends Transaction with additional API required on server.
@@ -96,7 +95,7 @@ public interface SpiTransaction extends Transaction {
/**
* Return the start timestamp for the transaction (JVM side).
*/
Instant startTime();
long startNanoTime();
/**
* Return true if this transaction has updateAllLoadedProperties set.
@@ -14,7 +14,6 @@ import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.Instant;
/**
* Proxy for an underlying SpiTransaction (most of the API).
@@ -29,8 +28,8 @@ public abstract class SpiTransactionProxy implements SpiTransaction {
}
@Override
public Instant startTime() {
return transaction.startTime();
public long startNanoTime() {
return transaction.startNanoTime();
}
@Override
@@ -23,7 +23,7 @@ public class DefaultServerQueryCache extends DefaultServerCache {
@Override
protected Object unwrapEntry(CacheEntry entry) {
return ((QueryCacheEntry) entry.getValue()).value();
return ((QueryCacheEntry) entry.getValue()).getValue();
}
@Override
@@ -1249,55 +1249,66 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
private <T> SpiQuery<T> configureForFuture(SpiQuery<T> query) {
query.usingFuture();
if (query.transaction() == null) {
// use a current transaction if active
query.usingTransaction(currentServerTransaction());
}
return query;
}
@Override
public <T> FutureRowCount<T> findFutureCount(SpiQuery<T> query) {
SpiQuery<T> copy = configureForFuture(query.copy());
var queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy));
SpiQuery<T> copy = query.copy();
copy.usingFuture();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
copy.usingTransaction(transaction);
}
var queryFuture = new QueryFutureRowCount<>(new CallableQueryCount<>(this, copy, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <T> FutureIds<T> findFutureIds(SpiQuery<T> query) {
SpiQuery<T> copy = configureForFuture(query.copy());
final var queryFuture = new QueryFutureIds<T>(new CallableQueryIds<>(this, copy));
SpiQuery<T> copy = query.copy();
copy.usingFuture();
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
copy.usingTransaction(transaction);
}
QueryFutureIds<T> queryFuture = new QueryFutureIds<>(new CallableQueryIds<>(this, copy, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <T> FutureList<T> findFutureList(SpiQuery<T> query) {
SpiQuery<T> spiQuery = configureForFuture(query.copy());
// FutureList query always run in its own persistence content
SpiQuery<T> spiQuery = query.copy();
spiQuery.usingFuture();
// FutureList query always run in it's own persistence content
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
if (!spiQuery.isDisableReadAudit()) {
BeanDescriptor<T> desc = descriptorManager.descriptor(spiQuery.getBeanType());
desc.readAuditFutureList(spiQuery);
}
final var queryFuture = new QueryFutureList<T>(new CallableQueryList<>(this, spiQuery));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@Override
public <K, T> FutureMap<K, T> findFutureMap(SpiQuery<T> query) {
SpiQuery<T> spiQuery = configureForFuture(query.copy());
// FutureMap query always run in it's own persistence content
spiQuery.setPersistenceContext(new DefaultPersistenceContext());
if (!spiQuery.isDisableReadAudit()) {
BeanDescriptor<T> desc = descriptorManager.descriptor(spiQuery.getBeanType());
desc.readAuditFutureList(spiQuery);
// Create a new transaction solely to execute the findList() at some future time
boolean createdTransaction = false;
SpiTransaction transaction = query.transaction();
if (transaction == null) {
transaction = currentServerTransaction();
if (transaction == null) {
transaction = (SpiTransaction) createTransaction();
createdTransaction = true;
}
spiQuery.usingTransaction(transaction);
}
final var queryFuture = new QueryFutureMap<K, T>(new CallableQueryMap<>(this, spiQuery));
QueryFutureList<T> queryFuture = new QueryFutureList<>(new CallableQueryList<>(this, spiQuery, createdTransaction));
backgroundExecutor.execute(queryFuture.futureTask());
return queryFuture;
}
@@ -585,32 +585,27 @@ public final class InternalConfiguration {
return QueryPlanManager.NOOP;
}
long threshold = config.getQueryPlanThresholdMicros();
return new CQueryPlanManager(transactionManager, threshold, queryPlanLogger(databasePlatform.platform(), config), extraMetrics);
return new CQueryPlanManager(transactionManager, threshold, queryPlanLogger(databasePlatform.platform()), extraMetrics);
}
/**
* Returns the logger to log query plans for the given platform.
*/
QueryPlanLogger queryPlanLogger(Platform platform, DatabaseBuilder.Settings config) {
QueryPlanLogger queryPlanLogger(Platform platform) {
switch (platform.base()) {
case SQLSERVER:
return new QueryPlanLoggerSqlServer();
case ORACLE:
return new QueryPlanLoggerOracle();
case POSTGRES:
return new QueryPlanLoggerExplain(explain(config, "explain (analyze, costs, verbose, buffers) "));
return new QueryPlanLoggerExplain("explain (analyze, buffers) ");
case YUGABYTE:
return new QueryPlanLoggerExplain(explain(config,"explain (analyze, buffers, dist) "));
return new QueryPlanLoggerExplain("explain (analyze, buffers, dist) ");
default:
return new QueryPlanLoggerExplain(explain(config,"explain "));
return new QueryPlanLoggerExplain("explain ");
}
}
private static String explain(DatabaseBuilder.Settings config, String defaultExplain) {
String explain = config.getQueryPlanExplain();
return explain == null ? defaultExplain : explain + ' ';
}
/**
* Return the DDL generator.
*/
@@ -665,7 +665,7 @@ public final class OrmQueryRequest<T> extends BeanRequest implements SpiOrmQuery
}
public void putToQueryCache(Object result) {
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.startTime()));
beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.startNanoTime()));
}
/**
@@ -1471,7 +1471,7 @@ public class BeanDescriptor<T> implements BeanType<T>, STreeType, SpiBeanType {
void queryPlanInit(QueryPlanInit request, List<MetaQueryPlan> list) {
for (CQueryPlan queryPlan : queryPlanCache.values()) {
if (request.includeHash(queryPlan.hash())) {
queryPlan.queryPlanInit(request.thresholdMicros(queryPlan.hash()));
queryPlan.queryPlanInit(request.thresholdMicros());
list.add(queryPlan.createMeta(null, null));
}
}
@@ -58,7 +58,7 @@ final class BeanEmbeddedMetaFactory {
}
private static int dbLength(Column override, BeanProperty source) {
return (override != null && (override.length() != 0)) ? override.length() : source.dbLength();
return (override != null && (override.length() != 255)) ? override.length() : source.dbLength();
}
private static int dbScale(Column override, BeanProperty source) {
@@ -1,5 +1,6 @@
package io.ebeaninternal.server.deploy;
import io.ebean.Query;
import io.ebean.SqlUpdate;
import io.ebean.Transaction;
import io.ebean.ValuePair;
@@ -124,10 +125,6 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
// no imported or exported information
} else if (!oneToOneExported) {
importedId = createImportedId(this, targetDescriptor, tableJoin);
if (importedId == null) {
throw new PersistenceException("Cannot find imported id for " + fullName() + " from " + targetDescriptor
+ ". If using native-image, possibly missing reflect-config for the Id property.");
}
if (importedId.isScalar()) {
// limit JoinColumn mapping to the @Id / primary key
TableJoinColumn[] columns = tableJoin.columns();
@@ -98,7 +98,7 @@ public abstract class AnnotationParser extends AnnotationBase {
prop.setUnique(columnAnn.unique());
if (columnAnn.precision() > 0) {
prop.setDbLength(columnAnn.precision());
} else if (columnAnn.length() != 0) {
} else if (columnAnn.length() != 255) {
// set default 255 on DbTypeMap
prop.setDbLength(columnAnn.length());
}
@@ -97,7 +97,7 @@ public final class DLoadContext implements LoadContext {
this.profilingListener = query.profilingListener();
this.planLabel = query.planLabel();
this.profileLocation = query.profileLocation();
this.secondaryProperties = query.isUnmodifiable() ? new HashSet<>() : null;
this.secondaryProperties = query.isUnmodifiable() || query.isDisableLazyLoading() ? new HashSet<>() : null;
ObjectGraphNode parentNode = query.parentNode();
if (parentNode != null) {
@@ -1,5 +1,6 @@
package io.ebeaninternal.server.query;
import io.ebean.Transaction;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
@@ -10,9 +11,11 @@ abstract class CallableQuery<T> {
final SpiQuery<T> query;
final SpiEbeanServer server;
final Transaction transaction;
CallableQuery(SpiEbeanServer server, SpiQuery<T> query) {
this.server = server;
this.query = query;
this.transaction = query.transaction();
}
}
@@ -10,8 +10,15 @@ import java.util.concurrent.Callable;
*/
public final class CallableQueryCount<T> extends CallableQuery<T> implements Callable<Integer> {
public CallableQueryCount(SpiEbeanServer server, SpiQuery<T> query) {
private final boolean createdTransaction;
/**
* Note that the transaction passed in is always a new transaction solely to
* find the row count so it must be cleaned up by this CallableQueryRowCount.
*/
public CallableQueryCount(SpiEbeanServer server, SpiQuery<T> query, boolean createdTransaction) {
super(server, query);
this.createdTransaction = createdTransaction;
}
/**
@@ -19,7 +26,13 @@ public final class CallableQueryCount<T> extends CallableQuery<T> implements Cal
*/
@Override
public Integer call() {
return server.findCountWithCopy(query);
try {
return server.findCountWithCopy(query);
} finally {
if (createdTransaction) {
transaction.end();
}
}
}
}
@@ -11,16 +11,28 @@ import java.util.concurrent.Callable;
*/
public final class CallableQueryIds<T> extends CallableQuery<T> implements Callable<List<Object>> {
public CallableQueryIds(SpiEbeanServer server, SpiQuery<T> query) {
private final boolean createdTransaction;
public CallableQueryIds(SpiEbeanServer server, SpiQuery<T> query, boolean createdTransaction) {
super(server, query);
this.createdTransaction = createdTransaction;
}
/**
* Execute the find Id's query returning the list of Id's.
*/
@Override
public List<Object> call() {
// we have already made a copy of the query
// this way the same query instance is available to the
// QueryFutureIds (as so has access to the List before it is done)
return server.findIdsWithCopy(query);
try {
return server.findIdsWithCopy(query);
} finally {
if (createdTransaction) {
transaction.end();
}
}
}
}
@@ -11,13 +11,25 @@ import java.util.concurrent.Callable;
*/
public final class CallableQueryList<T> extends CallableQuery<T> implements Callable<List<T>> {
public CallableQueryList(SpiEbeanServer server, SpiQuery<T> query) {
private final boolean createdTransaction;
public CallableQueryList(SpiEbeanServer server, SpiQuery<T> query, boolean createdTransaction) {
super(server, query);
this.createdTransaction = createdTransaction;
}
/**
* Execute the query returning the resulting List.
*/
@Override
public List<T> call() {
return server.findList(query);
try {
return server.findList(query);
} finally {
if (createdTransaction) {
transaction.end();
}
}
}
}
@@ -1,23 +0,0 @@
package io.ebeaninternal.server.query;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiQuery;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* Represent the findMap query as a Callable.
*/
public final class CallableQueryMap<K, T> extends CallableQuery<T> implements Callable<Map<K, T>> {
public CallableQueryMap(SpiEbeanServer server, SpiQuery<T> query) {
super(server, query);
}
@Override
public Map<K, T> call() {
return server.findMap(query);
}
}
@@ -365,11 +365,6 @@ final class DefaultFetchGroupQuery<T> implements SpiFetchGroupQuery<T>, SpiQuery
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public <K> FutureMap<K,T> findFutureMap() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
}
@Override
public PagedList<T> findPagedList() {
throw new RuntimeException("EB102: Only select() and fetch() clause is allowed on FetchGroup");
@@ -23,6 +23,10 @@ public final class QueryFutureIds<T> extends BaseFuture<List<Object>> implements
return futureTask;
}
public Transaction transaction() {
return call.transaction;
}
@Override
public Query<T> getQuery() {
return call.query;
@@ -27,6 +27,10 @@ public final class QueryFutureList<T> extends BaseFuture<List<T>> implements Fut
return futureTask;
}
public Transaction transaction() {
return call.transaction;
}
@Override
public Query<T> getQuery() {
return call.query;
@@ -1,71 +0,0 @@
package io.ebeaninternal.server.query;
import io.ebean.FutureMap;
import io.ebean.Query;
import io.ebean.Transaction;
import jakarta.persistence.PersistenceException;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Default implementation for FutureMap.
*/
public final class QueryFutureMap<K, T> extends BaseFuture<Map<K, T>> implements FutureMap<K, T> {
private final CallableQueryMap<K, T> call;
public QueryFutureMap(CallableQueryMap<K, T> call) {
super(new FutureTask<>(call));
this.call = call;
}
public FutureTask<Map<K, T>> futureTask() {
return futureTask;
}
@Override
public Query<T> getQuery() {
return call.query;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
call.query.cancel();
return super.cancel(mayInterruptIfRunning);
}
@Override
public Map<K, T> getUnchecked() {
try {
return get();
} catch (InterruptedException e) {
// restore the interrupted status (so client can check for that)
Thread.currentThread().interrupt();
throw new PersistenceException(e);
} catch (ExecutionException e) {
throw new PersistenceException(e);
}
}
@Override
public Map<K, T> getUnchecked(long timeout, TimeUnit unit) throws TimeoutException {
try {
return get(timeout, unit);
} catch (InterruptedException e) {
// restore the interrupted status (so client can check for that)
Thread.currentThread().interrupt();
throw new PersistenceException(e);
} catch (ExecutionException e) {
throw new PersistenceException(e);
}
}
}
@@ -21,6 +21,10 @@ public final class QueryFutureRowCount<T> extends BaseFuture<Integer> implements
return futureTask;
}
public Transaction transaction() {
return call.transaction;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
call.query.cancel();
@@ -32,6 +32,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
private final boolean readIdNormal;
private final boolean disableLazyLoad;
private final boolean unmodifiable;
private final boolean loadListReferences;
private final InheritInfo inheritInfo;
final String prefix;
private final Map<String, String> pathMap;
@@ -55,6 +56,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
this.readIdNormal = readId && !temporalVersions;
this.disableLazyLoad = node.disableLazyLoad;
this.unmodifiable = node.unmodifiable;
this.loadListReferences = !unmodifiable && !disableLazyLoad;
this.partialObject = node.partialObject;
this.properties = node.properties;
this.pathMap = node.pathMap;
@@ -301,7 +303,7 @@ class SqlTreeLoadBean implements SqlTreeLoad {
boolean forceNewReference = queryMode == Mode.REFRESH_BEAN;
for (STreePropertyAssocMany many : localDesc.propsMany()) {
if (many != loadingChildProperty) {
if (!unmodifiable || ctx.includeSecondary(many.asMany())) {
if (loadListReferences || ctx.includeSecondary(many.asMany())) {
// create a proxy for the many (deferred fetching)
BeanCollection<?> ref = many.createReference(localBean, forceNewReference);
if (ref != null) {
@@ -76,7 +76,6 @@ final class SqlTreeNodeRoot extends SqlTreeNodeBean {
@Override
public void dependentTables(Set<String> tables) {
tables.add(baseTable);
for (SqlTreeNode child : children) {
child.dependentTables(tables);
}
@@ -1614,11 +1614,6 @@ public class DefaultOrmQuery<T> extends AbstractQuery implements SpiQuery<T> {
return server.findFutureList(this);
}
@Override
public final <K> FutureMap<K, T> findFutureMap() {
return server.findFutureMap(this);
}
@Override
public final FutureRowCount<T> findFutureCount() {
return server.findFutureCount(this);
@@ -14,7 +14,6 @@ import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
@@ -59,7 +58,6 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
private SpiPersistenceContext persistenceContext;
private Object tenantId;
private Map<String, Object> userObjects;
private final Instant startTime = Instant.now();
private final long startNanos;
private ProfileLocation profileLocation;
@@ -91,8 +89,9 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
}
@Override
public Instant startTime() {
return startTime;
public long startNanoTime() {
// not used on read only transaction
return startNanos;
}
@Override
@@ -17,7 +17,6 @@ import jakarta.persistence.PersistenceException;
import jakarta.persistence.RollbackException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.Instant;
import java.util.*;
import java.util.function.Consumer;
@@ -92,7 +91,6 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
DocStoreTransaction docStoreTxn;
private ProfileStream profileStream;
private ProfileLocation profileLocation;
private final Instant startTime = Instant.now();
private final long startNanos;
private boolean autoPersistUpdates;
@@ -143,8 +141,8 @@ class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
}
@Override
public final Instant startTime() {
return startTime;
public final long startNanoTime() {
return startNanos;
}
@Override
@@ -17,7 +17,6 @@ import io.ebeanservice.docstore.api.DocStoreTransaction;
import jakarta.persistence.PersistenceException;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.Instant;
/**
* Placeholder for use with SUPPORTS and NEVER transactional when there really isn't a transaction.
@@ -57,9 +56,9 @@ final class NoTransaction implements SpiTransaction {
}
@Override
public Instant startTime() {
public long startNanoTime() {
// not used
return Instant.now();
return System.nanoTime();
}
@Override
@@ -6,7 +6,6 @@ import io.ebean.cache.QueryCacheEntryValidate;
import io.ebean.cache.ServerCacheNotification;
import io.ebean.cache.ServerCacheNotify;
import java.time.Instant;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -24,7 +23,7 @@ public final class TableModState implements QueryCacheEntryValidate, ServerCache
private static final System.Logger log = AppLog.getLogger("io.ebean.cache.TABLEMOD");
private final Map<String, Instant> tableModStamp = new ConcurrentHashMap<>();
private final Map<String, Long> tableModStamp = new ConcurrentHashMap<>();
public TableModState() {
}
@@ -33,22 +32,22 @@ public final class TableModState implements QueryCacheEntryValidate, ServerCache
* Set the modified timestamp on the tables that have been touched.
*/
void touch(Set<String> touchedTables) {
final var modTime = Instant.now();
long modNanoTime = System.nanoTime();
for (String tableName : touchedTables) {
tableModStamp.put(tableName, modTime);
tableModStamp.put(tableName, modNanoTime);
}
if (log.isLoggable(DEBUG)) {
log.log(DEBUG, "TableModState updated - touched:{0} modTime:{1}", touchedTables, modTime);
log.log(DEBUG, "TableModState updated - touched:{0} modNanoTime:{1}", touchedTables, modNanoTime);
}
}
/**
* Return true if all the tables are valid based on timestamp comparison.
*/
boolean isValid(Set<String> tables, Instant sinceTime) {
boolean isValid(Set<String> tables, long sinceNanoTime) {
for (String tableName : tables) {
final var modTime = tableModStamp.get(tableName);
if (modTime != null && !modTime.isBefore(sinceTime)) {
Long modTime = tableModStamp.get(tableName);
if (modTime != null && modTime >= sinceNanoTime) {
if (log.isLoggable(TRACE)) {
log.log(TRACE, "Invalidate on table:{0}", tableName);
}
@@ -60,9 +59,9 @@ public final class TableModState implements QueryCacheEntryValidate, ServerCache
@Override
public boolean isValid(QueryCacheEntry entry) {
Set<String> dependentTables = entry.dependentTables();
Set<String> dependentTables = entry.getDependentTables();
if (dependentTables != null && !dependentTables.isEmpty()) {
return isValid(dependentTables, entry.timestamp());
return isValid(dependentTables, entry.getTimestamp());
}
return true;
}
@@ -2,7 +2,6 @@ package io.ebeaninternal.server.transaction;
import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -10,23 +9,24 @@ import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class TableModStateTest {
public class TableModStateTest {
private final TableModState tableModState = new TableModState();
private TableModState tableModState = new TableModState();
@Test
void isValid() {
Instant before = Instant.now();
public void isValid() {
long before = System.nanoTime();
tableModState.touch(setOf("one", "two", "three"));
Instant after = Instant.now();
long after = System.nanoTime();
// empty
assertTrue(tableModState.isValid(Collections.emptySet(), before));
assertTrue(tableModState.isValid(Collections.emptySet(), 12L));
// no entry
assertTrue(tableModState.isValid(setOf("noEntry"), before));
assertTrue(tableModState.isValid(setOf("noEntry"), 12L));
// later timestamp
assertTrue(tableModState.isValid(setOf("one"), after));
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean ddl generation</name>
@@ -28,14 +28,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -65,7 +65,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -14,7 +14,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core-type</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean net postgis types</name>
@@ -19,14 +19,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -54,7 +54,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
@@ -12,7 +12,7 @@ ebean:
postgis:
containerName: ebeanbuild_postgis2
port: 9433
image: ghcr.io/baosystems/postgis:16
image: ghcr.io/baosystems/postgis:15
# extensions: postgis
# url: jdbc:postgresql_lwgis://localhost:6432/mygisapp
# driver: org.postgis.DriverWrapperLW
+4 -4
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean postgis types</name>
@@ -19,14 +19,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-postgres</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<!-- provided scope -->
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -62,7 +62,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
@@ -12,7 +12,7 @@ ebean:
postgis:
containerName: ebeanbuild_postgis
port: 9432
image: ghcr.io/baosystems/postgis:16
image: ghcr.io/baosystems/postgis:15
# extensions: postgis
# url: jdbc:postgresql_lwgis://localhost:6432/mygisapp
# driver: org.postgis.DriverWrapperLW
+5 -5
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean querybean</name>
@@ -17,7 +17,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -59,14 +59,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
@@ -80,7 +80,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -856,11 +856,6 @@ public abstract class QueryBean<T, R extends QueryBean<T, R>> implements IQueryB
return query.findFutureList();
}
@Override
public final <K> FutureMap<K,T> findFutureMap() {
return query.findFutureMap();
}
@Override
public final PagedList<T> findPagedList() {
return query.findPagedList();
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<artifactId>ebean-redis</artifactId>
@@ -29,35 +29,35 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-api</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-querybean</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>querybean-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -1,6 +1,7 @@
package io.ebean.redis;
import io.ebean.cache.ServerCache;
import io.ebean.cache.ServerCacheStatistics;
import io.ebean.meta.MetricVisitor;
import io.ebeaninternal.server.cache.DefaultServerCache;
@@ -281,7 +281,7 @@ final class RedisCacheFactory implements ServerCacheFactory {
public void invalidateKeys(String cacheKey, Set<Object> keySet) {
try {
sendMessage(messageInvalidateKeys(cacheKey, keySet));
} catch (Exception e) {
} catch (IOException e) {
logger.log(ERROR, "failed to transmit invalidateKeys() message", e);
}
}
@@ -290,7 +290,7 @@ final class RedisCacheFactory implements ServerCacheFactory {
public void invalidateKey(String cacheKey, Object id) {
try {
sendMessage(messageInvalidateKey(cacheKey, id));
} catch (Exception e) {
} catch (IOException e) {
logger.log(ERROR, "failed to transmit invalidateKeys() message", e);
}
}
@@ -299,7 +299,7 @@ final class RedisCacheFactory implements ServerCacheFactory {
public void invalidateClear(String cacheKey) {
try {
sendMessage(messageInvalidateClear(cacheKey));
} catch (Exception e) {
} catch (IOException e) {
logger.log(ERROR, "failed to transmit invalidateKeys() message", e);
}
}
@@ -422,7 +422,7 @@ final class RedisCacheFactory implements ServerCacheFactory {
throw new IllegalStateException("Unexpected message type ? " + msgType);
}
} catch (Exception e) {
} catch (IOException | ClassNotFoundException e) {
logger.log(ERROR, "failed to decode near cache message [" + SafeEncoder.encode(message) + "] for cache:" + cacheKey, e);
if (cacheKey != null) {
nearCacheInvalidateClear(cacheKey);
+3 -3
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<artifactId>ebean-spring-txn</artifactId>
@@ -28,7 +28,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
@@ -77,7 +77,7 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</parent>
<name>ebean test</name>
@@ -33,20 +33,20 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-h2</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-ddl-generator</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
</dependency>
<dependency>
@@ -149,14 +149,14 @@
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-jackson-mapper</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-platform-all</artifactId>
<version>16.0.0-rc1</version>
<version>14.10.0</version>
<scope>test</scope>
</dependency>
@@ -49,7 +49,7 @@ class PostgisSetup implements PlatformSetup {
}
config.setExtensions("hstore,pgcrypto,postgis");
config.setDockerContainerName("ut_postgis");
config.setDockerVersion("16-3.5");
config.setDockerVersion("14-3.2");
return config.getDockerProperties();
}
@@ -25,7 +25,7 @@ class PostgresSetup implements PlatformSetup {
if (!config.isUseDocker()) {
return new Properties();
}
config.setDockerVersion("16");
config.setDockerVersion("14");
config.setExtensions("hstore,pgcrypto");
return config.getDockerProperties();
}
@@ -1,6 +1,5 @@
package io.ebean.xtest;
import io.avaje.config.Config;
import io.ebean.CacheMode;
import io.ebean.DB;
import io.ebean.Database;
@@ -72,12 +71,6 @@ public abstract class BaseTestCase {
String propsFile = System.getProperty("props.file");
System.out.println("BaseTestCase: -Dprops.file=" + propsFile); // help debug CI
// First try, if we get the default server. If this fails, all tests will fail.
String dsName = Config.getNullable("datasource.default");
System.out.println("config: datasource.default " + dsName);
System.out.println("config: username " + Config.getNullable("datasource." + dsName + ".username"));
System.out.println("config: password " + Config.getNullable("datasource." + dsName + ".password"));
System.out.println("config: url " + Config.getNullable("datasource." + dsName + ".url"));
DB.getDefault();
} catch (Throwable e) {
logger.error("Fatal error while getting ebean-server. Exiting...", e);
@@ -1,10 +1,7 @@
package io.ebean.xtest.config;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.Transaction;
import io.ebean.*;
import io.ebean.annotation.Platform;
import io.ebean.DatabaseBuilder;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.dbplatform.DbIdentity;
import io.ebean.config.dbplatform.IdType;
@@ -15,6 +12,7 @@ import org.tests.model.basic.EBasicVer;
import org.tests.model.draftable.BasicDraftableBean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class PlatformNoGeneratedKeysTest {
@@ -39,7 +37,7 @@ public class PlatformNoGeneratedKeysTest {
.findOne();
assertThat(found.getName()).isEqualTo("basic");
assertThat(found.getDescription()).isNull();
assertThrows(LazyInitialisationException.class, found::getDescription);
}
@Test
@@ -653,11 +653,6 @@ public class TDSpiEbeanServer extends TDSpiServer implements SpiEbeanServer {
return null;
}
@Override
public <K, T> FutureMap<K, T> findFutureMap(SpiQuery<T> query) {
return null;
}
@Override
public <T> PagedList<T> findPagedList(SpiQuery<T> query) {
return null;
@@ -2,50 +2,99 @@ package io.ebean.xtest.internal.server.query;
import io.ebean.*;
import io.ebean.xtest.BaseTestCase;
import io.ebeaninternal.server.query.QueryFutureIds;
import io.ebeaninternal.server.query.QueryFutureList;
import io.ebeaninternal.server.query.QueryFutureRowCount;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.ResetBasicData;
import java.util.concurrent.ExecutionException;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;
class TestFutureRowCountErrorHandling extends BaseTestCase {
public class TestFutureRowCountErrorHandling extends BaseTestCase {
@Test
void testFutureRowCount() {
public void testFutureRowCount() throws InterruptedException {
ResetBasicData.reset();
Query<Customer> query = DB.find(Customer.class)
Database server = DB.getDefault();
Query<Customer> query = server.createQuery(Customer.class)
.where().eq("doesNotExist", "this will fail")
.query();
FutureRowCount<Customer> futureRowCount = query.findFutureCount();
assertThrows(ExecutionException.class, futureRowCount::get);
QueryFutureRowCount<Customer> internalRowCount = (QueryFutureRowCount<Customer>) futureRowCount;
Transaction t = internalRowCount.transaction();
try {
futureRowCount.get();
fail("never get here as the SQL is invalid");
} catch (ExecutionException e) {
// Confirm the Transaction has been rolled back
assertFalse(t.isActive());
}
}
@Test
void testFutureIds() {
public void testFutureIds() throws InterruptedException {
ResetBasicData.reset();
Query<Customer> query = DB.find(Customer.class)
Database server = DB.getDefault();
Query<Customer> query = server.createQuery(Customer.class)
.where().eq("doesNotExist", "this will fail")
.query();
FutureIds<Customer> futureIds = query.findFutureIds();
assertThrows(ExecutionException.class, futureIds::get);
QueryFutureIds<Customer> internalFuture = (QueryFutureIds<Customer>) futureIds;
Transaction t = internalFuture.transaction();
try {
internalFuture.get();
fail("never get here as the SQL is invalid");
} catch (ExecutionException e) {
// Confirm the Transaction has been rolled back
assertFalse(t.isActive());
}
}
@Test
void testFutureList() {
public void testFutureList() throws InterruptedException {
ResetBasicData.reset();
Query<Customer> query = DB.createQuery(Customer.class)
Database server = DB.getDefault();
Query<Customer> query = server.createQuery(Customer.class)
.where().eq("doesNotExist", "this will fail")
.query();
FutureList<Customer> futureList = query.findFutureList();
assertThrows(ExecutionException.class, futureList::get);
QueryFutureList<Customer> internalFuture = (QueryFutureList<Customer>) futureList;
Transaction t = internalFuture.transaction();
try {
internalFuture.get();
fail("never get here as the SQL is invalid");
} catch (ExecutionException e) {
// Confirm the Transaction has been rolled back
assertFalse(t.isActive());
}
}
}
@@ -1,6 +1,5 @@
package misc.migration.v1_0;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@@ -12,7 +11,6 @@ public class CKeyDetail {
@Id
Integer id;
@Column(length = 255)
String something;
@@ -2,7 +2,7 @@ package org.tests.batchload;
import io.ebean.BeanState;
import io.ebean.DB;
import io.ebean.UnmodifiableEntityException;
import io.ebean.LazyInitialisationException;
import io.ebean.bean.EntityBean;
import io.ebean.bean.EntityBeanIntercept;
import io.ebean.xtest.BaseTestCase;
@@ -83,7 +83,7 @@ class TestBeanState extends BaseTestCase {
BeanState beanState = DB.beanState(customer);
beanState.setDisableLazyLoad(true);
assertNull(customer.getName());
assertThrows(LazyInitialisationException.class, customer::getName);
}
@Test
@@ -1,18 +1,18 @@
package org.tests.batchload;
import io.ebean.LazyInitialisationException;
import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.test.LoggedSql;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import java.sql.Date;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.*;
public class TestQueryDisableLazyLoad extends BaseTestCase {
@@ -32,8 +32,7 @@ public class TestQueryDisableLazyLoad extends BaseTestCase {
Order order = l0.get(0);
List<OrderDetail> details = order.getDetails();
assertEquals(details.size(), 0);
assertThrows(LazyInitialisationException.class, order::getDetails);
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(1);
@@ -59,7 +58,7 @@ public class TestQueryDisableLazyLoad extends BaseTestCase {
Order order = l0.get(0);
// normally invokes lazy loading
assertNull(order.getCustomer().getStatus());
assertThrows(LazyInitialisationException.class, () -> order.getCustomer().getStatus());
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(1);
@@ -83,7 +82,29 @@ public class TestQueryDisableLazyLoad extends BaseTestCase {
Order order = l0.get(0);
// normally invokes lazy loading
assertNull(order.getCustomer().getStatus());
assertThrows(LazyInitialisationException.class, () -> order.getCustomer().getStatus());
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(1);
}
@Test
public void onSetter_expect_LazyInitialisationException() {
ResetBasicData.reset();
LoggedSql.start();
List<Order> l0 = DB.find(Order.class)
.setDisableLazyLoading(true)
.select("status, orderDate")
.orderBy().asc("id")
.findList();
assertThat(l0).isNotEmpty();
Order order = l0.get(0);
// normally invokes lazy loading
assertThrows(LazyInitialisationException.class, () -> order.setShipDate(new Date(System.currentTimeMillis())));
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(1);
@@ -1,5 +1,6 @@
package org.tests.batchload;
import io.ebean.LazyInitialisationException;
import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.test.LoggedSql;
@@ -16,6 +17,7 @@ import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class TestQueryJoinToAssocOne extends BaseTestCase {
@@ -91,15 +93,15 @@ public class TestQueryJoinToAssocOne extends BaseTestCase {
Order order = l0.get(0);
// normally invokes lazy loading
order.getOrderDate();
assertThrows(LazyInitialisationException.class, order::getOrderDate);
List<OrderDetail> details = order.getDetails();
OrderDetail orderDetail = details.get(0);
// normally invokes lazy loading
orderDetail.getShipQty();
assertThrows(LazyInitialisationException.class, orderDetail::getShipQty);
// normally invokes lazy loading
order.getShipments().size();
assertThrows(LazyInitialisationException.class, order::getShipments);
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(2);
@@ -129,13 +131,11 @@ public class TestQueryJoinToAssocOne extends BaseTestCase {
Order order = l0.get(0);
// try to invoke lazy loading on the bean
assertThat(order.getCustomer()).isNull();
assertThat(order.getCretime()).isNull();
assertThrows(LazyInitialisationException.class, order::getCustomer);
assertThrows(LazyInitialisationException.class, order::getCretime);
// try to invoke lazy loading on the OneToMany ...
List<OrderDetail> details = order.getDetails();
assertThat(details).isEmpty();
assertThat(details.size()).isEqualTo(0);
assertThrows(LazyInitialisationException.class, order::getDetails);
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(1);
@@ -163,7 +163,7 @@ public class TestQueryJoinToAssocOne extends BaseTestCase {
.setId(tenant.getId())
.findOne();
assertThat(found.getRoles().size()).isEqualTo(0);
assertThrows(LazyInitialisationException.class, found::getRoles);
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(1);
@@ -189,7 +189,7 @@ public class TestQueryJoinToAssocOne extends BaseTestCase {
.findOne();
// normally invokes lazy loading
assertThat(found.getRoles().size()).isEqualTo(0);
assertThrows(LazyInitialisationException.class, found::getRoles);
// only 1 query ... no lazy loading query
List<String> sql = LoggedSql.stop();
@@ -217,12 +217,12 @@ public class TestQueryJoinToAssocOne extends BaseTestCase {
Order order = l0.get(0);
// normally invokes lazy loading
order.getOrderDate();
assertThrows(LazyInitialisationException.class, order::getOrderDate);
List<OrderDetail> details = order.getDetails();
OrderDetail orderDetail = details.get(0);
// normally invokes lazy loading
orderDetail.getShipQty();
assertThrows(LazyInitialisationException.class, orderDetail::getShipQty);
List<String> loggedSql = LoggedSql.stop();
assertThat(loggedSql).hasSize(1);
@@ -1,99 +0,0 @@
package org.tests.cache;
import io.ebean.DB;
import io.ebean.annotation.Platform;
import io.ebean.xtest.BaseTestCase;
import io.ebean.xtest.ForPlatform;
import org.junit.jupiter.api.Test;
import org.tests.model.cache.EColAB;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestQueryCacheConcurrent extends BaseTestCase {
private volatile boolean running;
private volatile boolean failed;
private volatile int step;
@ForPlatform(Platform.POSTGRES) // H2 isn't good enough for this test
@Test
public void testConcurrent() throws InterruptedException {
Thread t1 = new Thread(() -> {
while (running) {
while (step <1) {
if (!running) return;
}
System.out.println("T1 BEFORE Insert");
new EColAB("01", "20").save();
System.out.println("T1 AFTER Insert");
step = 2;
while (step < 3) {
if (!running) return;
}
System.out.println("-------------------------");
step = 1;
}
});
Thread t2 = new Thread(() -> {
while (running) {
while (step < 1) {
if (!running) return;
}
System.out.println("T2 before FIND1");
List<EColAB> list = DB.find(EColAB.class)
.setUseQueryCache(true)
.where()
.eq("columnA", "01")
.eq("columnB", "20")
.findList();
System.out.println("T2 FIND1: " + list.size());
while (step < 2) {
if (!running) return;
}
System.out.println("T2 before FIND2");
list = DB.find(EColAB.class)
.setUseQueryCache(true)
.where()
.eq("columnA", "01")
.eq("columnB", "20")
.findList();
System.out.println("T2 FIND2: " + list.size());
if (list.isEmpty()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
list = DB.find(EColAB.class)
.setUseQueryCache(true)
.where()
.eq("columnA", "01")
.eq("columnB", "20")
.findList();
System.out.println("After 1s: in cache" + list);
System.out.println("... in DB" + DB.find(EColAB.class).findOne());
}
if (list.isEmpty()) {
failed = true;
}
DB.find(EColAB.class).delete();
step = 3;
}
});
running = true;
t1.start();
t2.start();
step = 1;
Thread.sleep(1000);
running = false;
t1.join();
t2.join();
assertThat(failed).isFalse();
}
}
@@ -1,5 +1,6 @@
package org.tests.model.aggregation;
import io.ebean.LazyInitialisationException;
import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.test.LoggedSql;
@@ -8,6 +9,7 @@ import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class TestAggregationMany extends BaseTestCase {
@@ -26,7 +28,7 @@ public class TestAggregationMany extends BaseTestCase {
for (DMachine machine : machines) {
assertThat(machine.getAuxUseAggs()).isNotEmpty();
assertThat(machine.getMachineStats()).isEmpty();
assertThrows(LazyInitialisationException.class, machine::getMachineStats);
}
List<String> sql = LoggedSql.stop();
@@ -57,7 +59,7 @@ public class TestAggregationMany extends BaseTestCase {
for (DMachine machine : machines) {
assertThat(machine.getAuxUseAggs()).isNotEmpty();
assertThat(machine.getMachineStats()).isEmpty();
assertThrows(LazyInitialisationException.class, machine::getMachineStats);
}
List<String> sql = LoggedSql.stop();
@@ -83,7 +85,7 @@ public class TestAggregationMany extends BaseTestCase {
for (DMachine machine : machines) {
assertThat(machine.getAuxUseAggs()).isNotEmpty();
System.out.println(machine);
assertThat(machine.getMachineStats()).isEmpty();
assertThrows(LazyInitialisationException.class, machine::getMachineStats);
}
List<String> sql = LoggedSql.stop();
@@ -14,7 +14,7 @@ public class Pview {
private String name;
@Basic(optional = false)
@Column(length = 255, nullable = false)
@Column(length = 100, nullable = false)
private String value;
@JoinTable(name = "pp_to_ww", joinColumns = {@JoinColumn(name = "pp_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "ww_id", referencedColumnName = "id")})
@@ -1,28 +1,24 @@
package org.tests.query;
import io.ebean.FutureMap;
import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.FutureList;
import io.ebean.Transaction;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Order;
import org.tests.model.basic.Product;
import org.tests.model.basic.ResetBasicData;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TestQueryFindFutureList extends BaseTestCase {
public class TestQueryFindFutureList extends BaseTestCase {
@Test
@SuppressWarnings("resource")
void test_cancel() throws InterruptedException {
public void test_cancel() throws InterruptedException {
ResetBasicData.reset();
// warm the connection pool
@@ -45,7 +41,8 @@ class TestQueryFindFutureList extends BaseTestCase {
}
@Test
void test_findFutureList() {
public void test_findFutureList() throws InterruptedException {
ResetBasicData.reset();
FutureList<Order> futureList = DB.find(Order.class).findFutureList();
@@ -57,47 +54,16 @@ class TestQueryFindFutureList extends BaseTestCase {
}
@Test
void test_findFutureListWithTimeout() throws TimeoutException {
public void test_findFutureListWithTimeout() throws InterruptedException, TimeoutException {
ResetBasicData.reset();
FutureList<Order> futureList = DB.find(Order.class).findFutureList();
FutureList<Product> futureList2 = DB.find(Product.class).findFutureList();
// wait for it to complete
List<Order> orders = futureList.getUnchecked(1, TimeUnit.SECONDS);
List<Product> products2 = futureList2.getUnchecked(1, TimeUnit.SECONDS);
assertEquals(DB.find(Order.class).findCount(), orders.size());
assertThat(products2).isNotEmpty();
}
@Test
void test_findFutureMap_defaultIdAsKey() {
ResetBasicData.reset();
FutureMap<Integer, Order> futureMap = DB.find(Order.class)
.findFutureMap();
// wait for it to complete
Map<Integer, Order> orders = futureMap.getUnchecked();
assertEquals(DB.find(Order.class).findCount(), orders.size());
}
@Test
void test_findFutureMap() {
ResetBasicData.reset();
FutureMap<String, Product> futureMap = DB.find(Product.class)
.setMapKey("sku")
.findFutureMap();
// wait for it to complete
Map<String, Product> products = futureMap.getUnchecked();
Product desk = products.get("DSK1");
assertThat(desk).isNotNull();
assertThat(desk.getName()).isEqualTo("Desk");
assertEquals(DB.find(Product.class).findCount(), products.size());
}
}
@@ -1,5 +1,6 @@
package org.tests.text.json;
import io.ebean.LazyInitialisationException;
import io.ebean.text.json.JsonReadOptions;
import io.ebean.xtest.BaseTestCase;
import io.ebean.BeanState;
@@ -19,8 +20,7 @@ import java.io.IOException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;
public class TestTextJsonReferenceBean extends BaseTestCase {
@@ -33,7 +33,7 @@ public class TestTextJsonReferenceBean extends BaseTestCase {
assertThat(DB.beanState(productRefBean).isReference()).isTrue();
// does not lazy load by default
assertThat(productRefBean.getName()).isNull();
assertThrows(LazyInitialisationException.class, productRefBean::getName);
}
@Test
+7 -11
View File
@@ -131,17 +131,17 @@ datasource.hsqldb.url=jdbc:hsqldb:mem:tests
# Set caseSensitiveCollation to false when using
# MySql with case insensitive collation
#ebean.mysql.caseSensitiveCollation=false
datasource.mysql.username=test_ebean
datasource.mysql.password=test
datasource.mysql.url=jdbc:mysql://127.0.0.1:4306/test_ebean
datasource.mysql.username=unit
datasource.mysql.password=unit
datasource.mysql.url=jdbc:mysql://127.0.0.1:4306/unit
#datasource.mysql.username=test_ebean
#datasource.mysql.password=test
#datasource.mysql.url=jdbc:mysql://127.0.0.1:4306/test_ebean
#datasource.mysql.driver=com.mysql.cj.jdbc.Driver
datasource.mariadb.username=unit
datasource.mariadb.password=test
datasource.mariadb.url=jdbc:mariadb://localhost:14307/unit?useLegacyDatetimeCode=false
datasource.mariadb.password=unit
datasource.mariadb.url=jdbc:mariadb://localhost:5306/unit?useLegacyDatetimeCode=false
datasource.cockroach.username=root
datasource.cockroach.password=
@@ -152,10 +152,6 @@ datasource.yugabyte.username=unit
datasource.yugabyte.password=test
datasource.yugabyte.url=jdbc:postgresql://localhost:6433/unit?sslmode=disable
datasource.postgres.username=unit
datasource.postgres.password=test
datasource.postgres.url=jdbc:postgresql://localhost:6432/unit
datasource.oracle.username=test_eb
datasource.oracle.password=test
datasource.oracle.url=jdbc:oracle:thin:@localhost:1521:XE
@@ -195,8 +191,8 @@ datasource.nuodb.password=test
datasource.nuodb.url=jdbc:com.nuodb://localhost/testdb
#datasource.nuodb.driver=com.nuodb.jdbc.Driver
datasource.db2.username=admin
datasource.db2.password=admin
datasource.db2.username=unit
datasource.db2.password=test
datasource.db2.url=jdbc:db2://127.0.0.1:50000/unit
#datasource.db2.driver=com.ibm.db2.jcc.DB2Driver
@@ -8,7 +8,7 @@ create table migtest_ckey_assoc (
create table migtest_ckey_detail (
id integer generated by default as identity not null,
something varchar(255),
something varchar,
constraint pk_migtest_ckey_detail primary key (id)
);
@@ -174,7 +174,6 @@ update migtest_e_history6 set test_number1 = 42 where test_number1 is null;
alter table "table" alter column textfield drop not null;
alter table "table" add column "select" varchar;
alter table "table" add column textfield2 varchar;
alter table migtest_ckey_detail alter column something type varchar;
alter table migtest_ckey_detail add column one_key integer;
alter table migtest_ckey_detail add column two_key varchar(127);
alter table migtest_ckey_parent add column assoc_id integer;
@@ -1,5 +1,5 @@
-1873582099, 1.0__initial.sql
-105047402, 1.1.sql
479024598, 1.0__initial.sql
51162323, 1.1.sql
856096334, 1.2__dropsFor_1.1.sql
-1876375912, 1.3.sql
-1416035730, 1.4__dropsFor_1.3.sql
@@ -7,7 +7,7 @@
</createTable>
<createTable name="migtest_ckey_detail" pkName="pk_migtest_ckey_detail">
<column name="id" type="integer" primaryKey="true"/>
<column name="something" type="varchar(255)"/>
<column name="something" type="varchar"/>
</createTable>
<createTable name="migtest_ckey_parent" pkName="pk_migtest_ckey_parent">
<column name="one_key" type="integer" primaryKey="true"/>
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<migration xmlns="http://ebean-orm.github.io/xml/ns/dbmigration">
<changeSet type="apply">
<alterColumn columnName="something" tableName="migtest_ckey_detail" type="varchar" currentType="varchar(255)" currentNotnull="false"/>
<addColumn tableName="migtest_ckey_detail">
<column name="one_key" type="integer"/>
<column name="two_key" type="varchar(127)"/>
@@ -8,7 +8,7 @@ create table migtest_ckey_assoc (
create table migtest_ckey_detail (
id integer generated by default as identity not null,
something varchar(255),
something varchar,
constraint pk_migtest_ckey_detail primary key (id)
);
@@ -203,7 +203,6 @@ drop view table_with_history;
alter table "table" alter column textfield drop not null;
alter table "table" add column if not exists "select" varchar;
alter table "table" add column if not exists textfield2 varchar;
alter table migtest_ckey_detail alter column something type varchar using something::varchar;
alter table migtest_ckey_detail add column if not exists one_key integer;
alter table migtest_ckey_detail add column if not exists two_key varchar(127);
alter table migtest_ckey_parent add column if not exists assoc_id integer;
@@ -1,5 +1,5 @@
542280208, 1.0__initial.sql
-235555338, 1.1.sql
284266403, 1.0__initial.sql
2064479644, 1.1.sql
-328303888, 1.2__dropsFor_1.1.sql
-1996146206, 1.3.sql
-1371008923, 1.4__dropsFor_1.3.sql

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