mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
151
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c6592a6ec | ||
|
|
554c5a7bfc | ||
|
|
7a32c50894 | ||
|
|
3fa8f04a4c | ||
|
|
962d7f601d | ||
|
|
f2aa2b5b8b | ||
|
|
87b485cfa4 | ||
|
|
5a55b5235d | ||
|
|
97adb76eac | ||
|
|
d0d5ab474d | ||
|
|
d396f09b3a | ||
|
|
3baa5bca46 | ||
|
|
c00484026c | ||
|
|
71798afadd | ||
|
|
1ec2f74df9 | ||
|
|
61a0651439 | ||
|
|
eae06059c9 | ||
|
|
a1ff9034b6 | ||
|
|
1085a8d608 | ||
|
|
3a547bf487 | ||
|
|
82489636d5 | ||
|
|
3cafb37a73 | ||
|
|
b4c7cf529d | ||
|
|
ba5c67f936 | ||
|
|
2bd7995ca1 | ||
|
|
cc8c860709 | ||
|
|
7d25e31289 | ||
|
|
936e56835c | ||
|
|
0d848e9311 | ||
|
|
b794b6c77e | ||
|
|
f45d240682 | ||
|
|
1a6f68edd3 | ||
|
|
81683c5d2a | ||
|
|
2b535d59b8 | ||
|
|
ae0bbaaaf8 | ||
|
|
aaca20f9c3 | ||
|
|
245cbb0ea1 | ||
|
|
dbe984c668 | ||
|
|
89088f9480 | ||
|
|
80253c4e07 | ||
|
|
f96ce11c73 | ||
|
|
b8f8cb5ae7 | ||
|
|
b8a2aac95a | ||
|
|
7b090a6346 | ||
|
|
b10c68489f | ||
|
|
2dbb2d9911 | ||
|
|
b3b4c72a77 | ||
|
|
1c040e4583 | ||
|
|
9677e585b6 | ||
|
|
c53806224f | ||
|
|
6fd5927c64 | ||
|
|
920635c6df | ||
|
|
fb1c29b57c | ||
|
|
89bed8be67 | ||
|
|
776e48a501 | ||
|
|
0666a72df7 | ||
|
|
55000a3515 | ||
|
|
8307e259ba | ||
|
|
95b7574d04 | ||
|
|
f6466d3211 | ||
|
|
160e4d7dd1 | ||
|
|
a00980c61f | ||
|
|
72d2fcb59e | ||
|
|
0f503b2a2f | ||
|
|
a79e2e786a | ||
|
|
c9ffa2673f | ||
|
|
0e0fa37f0d | ||
|
|
f7bbd5b3bb | ||
|
|
ba614cd287 | ||
|
|
7d028f3318 | ||
|
|
21b04c244b | ||
|
|
957c2def43 | ||
|
|
35f9cd3821 | ||
|
|
e95d3304bf | ||
|
|
0f7c9da5d2 | ||
|
|
b4008da70c | ||
|
|
34a0f16c74 | ||
|
|
a880109201 | ||
|
|
0607151ac8 | ||
|
|
5c4ad4c01c | ||
|
|
3564504e00 | ||
|
|
49babef495 | ||
|
|
9e3362d004 | ||
|
|
3f0dcdb6d1 | ||
|
|
481116251d | ||
|
|
d490966025 | ||
|
|
5bc0b01a6c | ||
|
|
2bd14db8f7 | ||
|
|
17a0933860 | ||
|
|
5bb8384567 | ||
|
|
29a6bbb6e6 | ||
|
|
46a1324f58 | ||
|
|
8f7199b586 | ||
|
|
d2c3142de4 | ||
|
|
721a50219d | ||
|
|
f0b8270e5e | ||
|
|
92232c2afb | ||
|
|
5e68b1a25e | ||
|
|
041324d177 | ||
|
|
7d02a42276 | ||
|
|
2a900165f0 | ||
|
|
e7c40e9552 | ||
|
|
0d92807308 | ||
|
|
16f7de30c6 | ||
|
|
3d250b0eca | ||
|
|
8403adac90 | ||
|
|
c006aa3f48 | ||
|
|
dcb7054248 | ||
|
|
12833bc918 | ||
|
|
71d805bc17 | ||
|
|
ab8704e2c9 | ||
|
|
327e2baae7 | ||
|
|
6e89c551d5 | ||
|
|
0a3941227f | ||
|
|
0013cb1a76 | ||
|
|
8fe91f66c0 | ||
|
|
053fdf4abb | ||
|
|
24be907dc5 | ||
|
|
6aa915b420 | ||
|
|
40d87af5b1 | ||
|
|
75082fe0c0 | ||
|
|
7d43f5a3d7 | ||
|
|
99203a35a2 | ||
|
|
67f427b83e | ||
|
|
f5a2cf8ff9 | ||
|
|
4e1cda691f | ||
|
|
64b01324d1 | ||
|
|
3cba238073 | ||
|
|
b5b4a4639f | ||
|
|
2d0a179c3b | ||
|
|
40f7a0088d | ||
|
|
6a02a8d69f | ||
|
|
ed18cbcabf | ||
|
|
3ce4f2fb35 | ||
|
|
962a27f838 | ||
|
|
2b583cf707 | ||
|
|
ef9ade4f5c | ||
|
|
b1b7774a23 | ||
|
|
c6632bbc25 | ||
|
|
8c12fc762c | ||
|
|
8cb0b13ccb | ||
|
|
c2faffb6f4 | ||
|
|
e17d823c17 | ||
|
|
9bf9338ba9 | ||
|
|
0da764ed0c | ||
|
|
43003f4a3a | ||
|
|
7081d3f54a | ||
|
|
cce2c2e28f | ||
|
|
61ecf16978 | ||
|
|
9ff4e63c32 | ||
|
|
a13fd55f64 |
@@ -1,5 +1,6 @@
|
||||
*.autofetch
|
||||
*.sql
|
||||
*.orig
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
[](https://waffle.io/ebean-orm/avaje-ebeanorm)
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm) - avaje-ebeanorm
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-agent) - avaje-ebeanorm-agent
|
||||
* [](https://maven-badges.herokuapp.com/maven-central/org.avaje.ebeanorm/avaje-ebeanorm-mavenenhancer) - avaje-ebeanorm-mavenenhancer
|
||||
|
||||
|
||||
Ebean ORM
|
||||
==============
|
||||
|
||||
Project Website
|
||||
----------------
|
||||
[http://ebean-orm.github.io/](http://ebean-orm.github.io/ "Ebean ORM's Website")
|
||||
|
||||
|
||||
@@ -12,5 +13,11 @@ Maven Dependency
|
||||
<dependency>
|
||||
<groupId>org.avaje.ebeanorm</groupId>
|
||||
<artifactId>avaje-ebeanorm</artifactId>
|
||||
<version>4.5.5</version>
|
||||
<version>4.7.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
[Maven central - avaje-ebeanorm](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.avaje.ebeanorm%22%20AND%20a%3A%22avaje-ebeanorm%22 "maven central ebeanorm")
|
||||
|
||||
[Maven central - all related projects](http://search.maven.org/#search%7Cga%7C1%7Cavaje-ebeanorm "maven central ebeanorm")
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>org.avaje.ebeanorm</groupId>
|
||||
<artifactId>avaje-ebeanorm</artifactId>
|
||||
<version>4.6.1</version>
|
||||
<version>6.2.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>avaje-ebeanorm</name>
|
||||
@@ -43,6 +43,12 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>13.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.persistence</groupId>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
@@ -55,12 +61,21 @@
|
||||
<version>1.7.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope for JsonNode support -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.5.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Jackson core used internally by Ebean -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<version>2.5.3</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>jta</artifactId>
|
||||
@@ -68,6 +83,7 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- provided scope to read validation annotations Size etc -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
@@ -89,6 +105,14 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Provided scope for Postgres JSON/JSONB support -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4-1201-jdbc41</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
@@ -124,13 +148,6 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>8.4-701.jdbc4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
@@ -141,7 +158,7 @@
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.27</version>
|
||||
<version>5.1.36</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -254,8 +271,6 @@
|
||||
<configuration>
|
||||
<doctitle>Ebean 4</doctitle>
|
||||
<overview>src/main/java/com/avaje/ebean/overview.html</overview>
|
||||
<!-- <excludePackageNames>com.avaje.ebeaninternal.*:com.avaje.ebean.util</excludePackageNames> -->
|
||||
<!--<additionalparam>-Xdoclint:none</additionalparam>-->
|
||||
<source>1.8</source>
|
||||
<doclet>org.avaje.doclet.PygmentsDoclet</doclet>
|
||||
<excludePackageNames>com.avaje.ebeaninternal.*:com.avaje.ebean.util</excludePackageNames>
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.avaje.ebean;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -10,6 +9,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.persistence.OptimisticLockException;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -101,7 +101,7 @@ import com.avaje.ebean.text.json.JsonContext;
|
||||
* specific database.
|
||||
* </p>
|
||||
*
|
||||
* <pre> {@code
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Get access to the Human Resources EbeanServer/Database
|
||||
* EbeanServer hrDb = Ebean.getServer("hr");
|
||||
@@ -146,9 +146,9 @@ public final class Ebean {
|
||||
private final Object monitor = new Object();
|
||||
|
||||
/**
|
||||
* The 'default/primary' EbeanServer.
|
||||
* The 'default' EbeanServer.
|
||||
*/
|
||||
private EbeanServer primaryServer;
|
||||
private EbeanServer defaultServer;
|
||||
|
||||
private ServerManager() {
|
||||
|
||||
@@ -162,10 +162,10 @@ public final class Ebean {
|
||||
|
||||
} else {
|
||||
// look to see if there is a default server defined
|
||||
String primaryName = PrimaryServer.getPrimaryServerName();
|
||||
logger.debug("primaryName:" + primaryName);
|
||||
if (primaryName != null && primaryName.trim().length() > 0) {
|
||||
primaryServer = getWithCreate(primaryName.trim());
|
||||
String defaultName = PrimaryServer.getDefaultServerName();
|
||||
logger.debug("defaultName:" + defaultName);
|
||||
if (defaultName != null && defaultName.trim().length() > 0) {
|
||||
defaultServer = getWithCreate(defaultName.trim());
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
@@ -174,19 +174,19 @@ public final class Ebean {
|
||||
}
|
||||
}
|
||||
|
||||
private EbeanServer getPrimaryServer() {
|
||||
if (primaryServer == null) {
|
||||
private EbeanServer getDefaultServer() {
|
||||
if (defaultServer == null) {
|
||||
String msg = "The default EbeanServer has not been defined?";
|
||||
msg += " This is normally set via the ebean.datasource.default property.";
|
||||
msg += " Otherwise it should be registered programatically via registerServer()";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
return primaryServer;
|
||||
return defaultServer;
|
||||
}
|
||||
|
||||
private EbeanServer get(String name) {
|
||||
if (name == null || name.length() == 0) {
|
||||
return primaryServer;
|
||||
return defaultServer;
|
||||
}
|
||||
// non-synchronized read
|
||||
EbeanServer server = concMap.get(name);
|
||||
@@ -221,12 +221,12 @@ public final class Ebean {
|
||||
registerWithName(server.getName(), server, isPrimaryServer);
|
||||
}
|
||||
|
||||
private void registerWithName(String name, EbeanServer server, boolean isPrimaryServer) {
|
||||
private void registerWithName(String name, EbeanServer server, boolean isDefaultServer) {
|
||||
synchronized (monitor) {
|
||||
concMap.put(name, server);
|
||||
syncMap.put(name, server);
|
||||
if (isPrimaryServer) {
|
||||
primaryServer = server;
|
||||
if (isDefaultServer) {
|
||||
defaultServer = server;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,12 +254,22 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*
|
||||
* @param name
|
||||
* the name of the server, use null for the 'default server'
|
||||
* the name of the server, can use null for the 'default server'
|
||||
*/
|
||||
public static EbeanServer getServer(String name) {
|
||||
return serverMgr.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default EbeanServer.
|
||||
* <p>
|
||||
* This is equivalent to <code>Ebean.getServer(null);</code>
|
||||
* </p>
|
||||
*/
|
||||
public static EbeanServer getDefaultServer() {
|
||||
return serverMgr.getDefaultServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ExpressionFactory from the default server.
|
||||
* <p>
|
||||
@@ -278,23 +288,23 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static ExpressionFactory getExpressionFactory() {
|
||||
return serverMgr.getPrimaryServer().getExpressionFactory();
|
||||
return serverMgr.getDefaultServer().getExpressionFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the server with this Ebean singleton. Specify if the registered
|
||||
* server is the primary/default server.
|
||||
*/
|
||||
public static void register(EbeanServer server, boolean isPrimaryServer) {
|
||||
serverMgr.register(server, isPrimaryServer);
|
||||
public static void register(EbeanServer server, boolean defaultServer) {
|
||||
serverMgr.register(server, defaultServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backdoor for registering a mock implementation of EbeanServer as the default server.
|
||||
*/
|
||||
protected static EbeanServer mock(String name, EbeanServer server, boolean isPrimaryServer) {
|
||||
EbeanServer originalPrimaryServer = serverMgr.primaryServer;
|
||||
serverMgr.registerWithName(name, server, isPrimaryServer);
|
||||
protected static EbeanServer mock(String name, EbeanServer server, boolean defaultServer) {
|
||||
EbeanServer originalPrimaryServer = serverMgr.defaultServer;
|
||||
serverMgr.registerWithName(name, server, defaultServer);
|
||||
return originalPrimaryServer;
|
||||
}
|
||||
|
||||
@@ -311,11 +321,14 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Object nextId(Class<?> beanType) {
|
||||
return serverMgr.getPrimaryServer().nextId(beanType);
|
||||
return serverMgr.getDefaultServer().nextId(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new explicit transaction.
|
||||
* Start a transaction with 'REQUIRED' semantics.
|
||||
* <p>
|
||||
* With REQUIRED semantics if an active transaction already exists that transaction will be used.
|
||||
* </p>
|
||||
* <p>
|
||||
* The transaction is stored in a ThreadLocal variable and typically you only
|
||||
* need to use the returned Transaction <em>IF</em> you wish to do things like
|
||||
@@ -356,7 +369,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Transaction beginTransaction() {
|
||||
return serverMgr.getPrimaryServer().beginTransaction();
|
||||
return serverMgr.getDefaultServer().beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,7 +380,7 @@ public final class Ebean {
|
||||
*
|
||||
*/
|
||||
public static Transaction beginTransaction(TxIsolation isolation) {
|
||||
return serverMgr.getPrimaryServer().beginTransaction(isolation);
|
||||
return serverMgr.getDefaultServer().beginTransaction(isolation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -422,7 +435,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static Transaction beginTransaction(TxScope scope){
|
||||
return serverMgr.getPrimaryServer().beginTransaction(scope);
|
||||
return serverMgr.getDefaultServer().beginTransaction(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,7 +443,7 @@ public final class Ebean {
|
||||
* in scope.
|
||||
*/
|
||||
public static Transaction currentTransaction() {
|
||||
return serverMgr.getPrimaryServer().currentTransaction();
|
||||
return serverMgr.getDefaultServer().currentTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,21 +456,21 @@ public final class Ebean {
|
||||
* @throws PersistenceException if there is no currently active transaction
|
||||
*/
|
||||
public static void register(TransactionCallback transactionCallback) throws PersistenceException {
|
||||
serverMgr.getPrimaryServer().register(transactionCallback);
|
||||
serverMgr.getDefaultServer().register(transactionCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit the current transaction.
|
||||
*/
|
||||
public static void commitTransaction() {
|
||||
serverMgr.getPrimaryServer().commitTransaction();
|
||||
serverMgr.getDefaultServer().commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the current transaction.
|
||||
*/
|
||||
public static void rollbackTransaction() {
|
||||
serverMgr.getPrimaryServer().rollbackTransaction();
|
||||
serverMgr.getDefaultServer().rollbackTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -486,7 +499,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void endTransaction() {
|
||||
serverMgr.getPrimaryServer().endTransaction();
|
||||
serverMgr.getDefaultServer().endTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,7 +510,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static Map<String, ValuePair> diff(Object a, Object b) {
|
||||
return serverMgr.getPrimaryServer().diff(a, b);
|
||||
return serverMgr.getDefaultServer().diff(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -520,7 +533,6 @@ public final class Ebean {
|
||||
* public class Order { ...
|
||||
*
|
||||
* @OneToMany(cascade=CascadeType.ALL, mappedBy="order")
|
||||
* @JoinColumn(name="order_id")
|
||||
* List<OrderDetail> details;
|
||||
* ...
|
||||
* }
|
||||
@@ -534,7 +546,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void save(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getPrimaryServer().save(bean);
|
||||
serverMgr.getDefaultServer().save(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -542,14 +554,14 @@ public final class Ebean {
|
||||
* want to explicitly insert it.
|
||||
*/
|
||||
public static void insert(Object bean) {
|
||||
serverMgr.getPrimaryServer().insert(bean);
|
||||
serverMgr.getDefaultServer().insert(bean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a collection of beans.
|
||||
*/
|
||||
public static void insert(Collection<?> beans) {
|
||||
serverMgr.getPrimaryServer().insert(beans);
|
||||
public static void insertAll(Collection<?> beans) {
|
||||
serverMgr.getDefaultServer().insertAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -573,7 +585,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void markAsDirty(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getPrimaryServer().markAsDirty(bean);
|
||||
serverMgr.getDefaultServer().markAsDirty(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -613,28 +625,21 @@ public final class Ebean {
|
||||
* @see ServerConfig#setUpdateChangesOnly(boolean)
|
||||
*/
|
||||
public static void update(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getPrimaryServer().update(bean);
|
||||
serverMgr.getDefaultServer().update(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the beans in the collection.
|
||||
*/
|
||||
public static void update(Collection<?> beans) throws OptimisticLockException {
|
||||
serverMgr.getPrimaryServer().update(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans from an Iterator.
|
||||
*/
|
||||
public static int save(Iterator<?> iterator) throws OptimisticLockException {
|
||||
return serverMgr.getPrimaryServer().save(iterator);
|
||||
public static void updateAll(Collection<?> beans) throws OptimisticLockException {
|
||||
serverMgr.getDefaultServer().updateAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all the beans from a Collection.
|
||||
*/
|
||||
public static int save(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getPrimaryServer().save(beans);
|
||||
public static int saveAll(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().saveAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,7 +653,7 @@ public final class Ebean {
|
||||
* @return the number of associations deleted (from the intersection table).
|
||||
*/
|
||||
public static int deleteManyToManyAssociations(Object ownerBean, String propertyName) {
|
||||
return serverMgr.getPrimaryServer().deleteManyToManyAssociations(ownerBean, propertyName);
|
||||
return serverMgr.getDefaultServer().deleteManyToManyAssociations(ownerBean, propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -666,7 +671,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void saveManyToManyAssociations(Object ownerBean, String propertyName) {
|
||||
serverMgr.getPrimaryServer().saveManyToManyAssociations(ownerBean, propertyName);
|
||||
serverMgr.getDefaultServer().saveManyToManyAssociations(ownerBean, propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -686,7 +691,7 @@ public final class Ebean {
|
||||
* the property we want to save
|
||||
*/
|
||||
public static void saveAssociation(Object ownerBean, String propertyName) {
|
||||
serverMgr.getPrimaryServer().saveAssociation(ownerBean, propertyName);
|
||||
serverMgr.getDefaultServer().saveAssociation(ownerBean, propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -697,35 +702,28 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void delete(Object bean) throws OptimisticLockException {
|
||||
serverMgr.getPrimaryServer().delete(bean);
|
||||
serverMgr.getDefaultServer().delete(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the bean given its type and id.
|
||||
*/
|
||||
public static int delete(Class<?> beanType, Object id) {
|
||||
return serverMgr.getPrimaryServer().delete(beanType, id);
|
||||
return serverMgr.getDefaultServer().delete(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete several beans given their type and id values.
|
||||
*/
|
||||
public static void delete(Class<?> beanType, Collection<?> ids) {
|
||||
serverMgr.getPrimaryServer().delete(beanType, ids);
|
||||
public static void deleteAll(Class<?> beanType, Collection<?> ids) {
|
||||
serverMgr.getDefaultServer().deleteAll(beanType, ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the beans from an Iterator.
|
||||
* Delete all the beans in the Collection.
|
||||
*/
|
||||
public static int delete(Iterator<?> it) throws OptimisticLockException {
|
||||
return serverMgr.getPrimaryServer().delete(it);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the beans from a Collection.
|
||||
*/
|
||||
public static int delete(Collection<?> c) throws OptimisticLockException {
|
||||
return delete(c.iterator());
|
||||
public static int deleteAll(Collection<?> beans) throws OptimisticLockException {
|
||||
return serverMgr.getDefaultServer().deleteAll(beans);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -736,7 +734,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void refresh(Object bean) {
|
||||
serverMgr.getPrimaryServer().refresh(bean);
|
||||
serverMgr.getDefaultServer().refresh(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -757,7 +755,7 @@ public final class Ebean {
|
||||
* the property name of the List Set or Map to refresh.
|
||||
*/
|
||||
public static void refreshMany(Object bean, String manyPropertyName) {
|
||||
serverMgr.getPrimaryServer().refreshMany(bean, manyPropertyName);
|
||||
serverMgr.getDefaultServer().refreshMany(bean, manyPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -785,7 +783,7 @@ public final class Ebean {
|
||||
* the id value
|
||||
*/
|
||||
public static <T> T getReference(Class<T> beanType, Object id) {
|
||||
return serverMgr.getPrimaryServer().getReference(beanType, id);
|
||||
return serverMgr.getDefaultServer().getReference(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -831,7 +829,7 @@ public final class Ebean {
|
||||
* the properties to sort the list by
|
||||
*/
|
||||
public static <T> void sort(List<T> list, String sortByClause) {
|
||||
serverMgr.getPrimaryServer().sort(list, sortByClause);
|
||||
serverMgr.getDefaultServer().sort(list, sortByClause);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -880,8 +878,9 @@ public final class Ebean {
|
||||
* @param id
|
||||
* the id value
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T find(Class<T> beanType, Object id) {
|
||||
return serverMgr.getPrimaryServer().find(beanType, id);
|
||||
return serverMgr.getDefaultServer().find(beanType, id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -893,7 +892,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static SqlQuery createSqlQuery(String sql) {
|
||||
return serverMgr.getPrimaryServer().createSqlQuery(sql);
|
||||
return serverMgr.getDefaultServer().createSqlQuery(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -906,7 +905,7 @@ public final class Ebean {
|
||||
* the name of the query
|
||||
*/
|
||||
public static SqlQuery createNamedSqlQuery(String namedQuery) {
|
||||
return serverMgr.getPrimaryServer().createNamedSqlQuery(namedQuery);
|
||||
return serverMgr.getDefaultServer().createNamedSqlQuery(namedQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -924,7 +923,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static SqlUpdate createSqlUpdate(String sql) {
|
||||
return serverMgr.getPrimaryServer().createSqlUpdate(sql);
|
||||
return serverMgr.getDefaultServer().createSqlUpdate(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -933,7 +932,7 @@ public final class Ebean {
|
||||
* @see CallableSql
|
||||
*/
|
||||
public static CallableSql createCallableSql(String sql) {
|
||||
return serverMgr.getPrimaryServer().createCallableSql(sql);
|
||||
return serverMgr.getDefaultServer().createCallableSql(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -956,7 +955,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static SqlUpdate createNamedSqlUpdate(String namedQuery) {
|
||||
return serverMgr.getPrimaryServer().createNamedSqlUpdate(namedQuery);
|
||||
return serverMgr.getDefaultServer().createNamedSqlUpdate(namedQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -984,7 +983,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
|
||||
|
||||
return serverMgr.getPrimaryServer().createNamedQuery(beanType, namedQuery);
|
||||
return serverMgr.getDefaultServer().createNamedQuery(beanType, namedQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1012,7 +1011,7 @@ public final class Ebean {
|
||||
* the object query
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType, String query) {
|
||||
return serverMgr.getPrimaryServer().createQuery(beanType, query);
|
||||
return serverMgr.getDefaultServer().createQuery(beanType, query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1071,7 +1070,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> Update<T> createNamedUpdate(Class<T> beanType, String namedUpdate) {
|
||||
|
||||
return serverMgr.getPrimaryServer().createNamedUpdate(beanType, namedUpdate);
|
||||
return serverMgr.getDefaultServer().createNamedUpdate(beanType, namedUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1105,7 +1104,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> Update<T> createUpdate(Class<T> beanType, String ormUpdate) {
|
||||
|
||||
return serverMgr.getPrimaryServer().createUpdate(beanType, ormUpdate);
|
||||
return serverMgr.getDefaultServer().createUpdate(beanType, ormUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1113,7 +1112,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> CsvReader<T> createCsvReader(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getPrimaryServer().createCsvReader(beanType);
|
||||
return serverMgr.getDefaultServer().createCsvReader(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1170,7 +1169,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> Query<T> createQuery(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getPrimaryServer().createQuery(beanType);
|
||||
return serverMgr.getDefaultServer().createQuery(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1187,7 +1186,7 @@ public final class Ebean {
|
||||
*/
|
||||
public static <T> Query<T> find(Class<T> beanType) {
|
||||
|
||||
return serverMgr.getPrimaryServer().find(beanType);
|
||||
return serverMgr.getDefaultServer().find(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1201,7 +1200,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static <T> Filter<T> filter(Class<T> beanType) {
|
||||
return serverMgr.getPrimaryServer().filter(beanType);
|
||||
return serverMgr.getDefaultServer().filter(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1248,7 +1247,7 @@ public final class Ebean {
|
||||
* @see Ebean#execute(CallableSql)
|
||||
*/
|
||||
public static int execute(SqlUpdate sqlUpdate) {
|
||||
return serverMgr.getPrimaryServer().execute(sqlUpdate);
|
||||
return serverMgr.getDefaultServer().execute(sqlUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1277,7 +1276,7 @@ public final class Ebean {
|
||||
* @see Ebean#execute(SqlUpdate)
|
||||
*/
|
||||
public static int execute(CallableSql callableSql) {
|
||||
return serverMgr.getPrimaryServer().execute(callableSql);
|
||||
return serverMgr.getDefaultServer().execute(callableSql);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1302,7 +1301,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void execute(TxScope scope, TxRunnable r) {
|
||||
serverMgr.getPrimaryServer().execute(scope, r);
|
||||
serverMgr.getDefaultServer().execute(scope, r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1330,7 +1329,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static void execute(TxRunnable r) {
|
||||
serverMgr.getPrimaryServer().execute(r);
|
||||
serverMgr.getDefaultServer().execute(r);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1357,7 +1356,7 @@ public final class Ebean {
|
||||
*
|
||||
*/
|
||||
public static <T> T execute(TxScope scope, TxCallable<T> c) {
|
||||
return serverMgr.getPrimaryServer().execute(scope, c);
|
||||
return serverMgr.getDefaultServer().execute(scope, c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1391,7 +1390,7 @@ public final class Ebean {
|
||||
* }</pre>
|
||||
*/
|
||||
public static <T> T execute(TxCallable<T> c) {
|
||||
return serverMgr.getPrimaryServer().execute(c);
|
||||
return serverMgr.getDefaultServer().execute(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1428,10 +1427,9 @@ public final class Ebean {
|
||||
* @param deletes
|
||||
* true if rows on the table where deleted
|
||||
*/
|
||||
public static void externalModification(String tableName, boolean inserts, boolean updates,
|
||||
boolean deletes) {
|
||||
public static void externalModification(String tableName, boolean inserts, boolean updates, boolean deletes) {
|
||||
|
||||
serverMgr.getPrimaryServer().externalModification(tableName, inserts, updates, deletes);
|
||||
serverMgr.getDefaultServer().externalModification(tableName, inserts, updates, deletes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1441,7 +1439,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static BeanState getBeanState(Object bean) {
|
||||
return serverMgr.getPrimaryServer().getBeanState(bean);
|
||||
return serverMgr.getDefaultServer().getBeanState(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1449,7 +1447,7 @@ public final class Ebean {
|
||||
*
|
||||
*/
|
||||
public static ServerCacheManager getServerCacheManager() {
|
||||
return serverMgr.getPrimaryServer().getServerCacheManager();
|
||||
return serverMgr.getDefaultServer().getServerCacheManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1457,7 +1455,7 @@ public final class Ebean {
|
||||
* queries.
|
||||
*/
|
||||
public static BackgroundExecutor getBackgroundExecutor() {
|
||||
return serverMgr.getPrimaryServer().getBackgroundExecutor();
|
||||
return serverMgr.getDefaultServer().getBackgroundExecutor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1468,7 +1466,7 @@ public final class Ebean {
|
||||
* </p>
|
||||
*/
|
||||
public static void runCacheWarming() {
|
||||
serverMgr.getPrimaryServer().runCacheWarming();
|
||||
serverMgr.getDefaultServer().runCacheWarming();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1480,22 +1478,14 @@ public final class Ebean {
|
||||
*/
|
||||
public static void runCacheWarming(Class<?> beanType) {
|
||||
|
||||
serverMgr.getPrimaryServer().runCacheWarming(beanType);
|
||||
serverMgr.getDefaultServer().runCacheWarming(beanType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JsonContext for reading/writing JSON.
|
||||
*/
|
||||
public static JsonContext json() {
|
||||
return serverMgr.getPrimaryServer().json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JsonContext for reading/writing JSON.
|
||||
* @deprecated Please use #json instead.
|
||||
*/
|
||||
public static JsonContext createJsonContext() {
|
||||
return json();
|
||||
return serverMgr.getDefaultServer().json();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -15,6 +14,7 @@ import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.meta.MetaInfoManager;
|
||||
import com.avaje.ebean.text.csv.CsvReader;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Provides the API for fetching and saving beans to a particular DataSource.
|
||||
@@ -148,7 +148,7 @@ public interface EbeanServer {
|
||||
* difference comparison.
|
||||
* </p>
|
||||
*/
|
||||
Map<String, ValuePair> diff(Object a, Object b);
|
||||
Map<String, ValuePair> diff(Object newBean, Object oldBean);
|
||||
|
||||
/**
|
||||
* Create a new instance of T that is an EntityBean.
|
||||
@@ -509,7 +509,10 @@ public interface EbeanServer {
|
||||
Transaction createTransaction(TxIsolation isolation);
|
||||
|
||||
/**
|
||||
* Start a new explicit transaction putting it into a ThreadLocal.
|
||||
* Start a transaction with 'REQUIRED' semantics.
|
||||
* <p>
|
||||
* With REQUIRED semantics if an active transaction already exists that transaction will be used.
|
||||
* </p>
|
||||
* <p>
|
||||
* The transaction is stored in a ThreadLocal variable and typically you only
|
||||
* need to use the returned Transaction <em>IF</em> you wish to do things like
|
||||
@@ -902,17 +905,13 @@ public interface EbeanServer {
|
||||
<T> void findEachWhile(Query<T> query, QueryEachWhileConsumer<T> consumer, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Deprecated in favor of #findEachWhile which is functionally exactly the same
|
||||
* but has a much better name.
|
||||
* Return versions of a @History entity bean.
|
||||
* <p>
|
||||
* Execute the query visiting the results. This is similar to findIterate in
|
||||
* that not all the result beans need to be held in memory at the same time
|
||||
* and as such is go for processing large queries.
|
||||
* Generally this query is expected to be a find by id or unique predicates query.
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
<T> void findVisit(Query<T> query, QueryResultVisitor<T> visitor, Transaction transaction);
|
||||
<T> List<Version<T>> findVersions(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute a query returning a list of beans.
|
||||
@@ -1106,6 +1105,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* @see Query#findUnique()
|
||||
*/
|
||||
@Nullable
|
||||
<T> T findUnique(Query<T> query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1182,6 +1182,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* @see SqlQuery#findUnique()
|
||||
*/
|
||||
@Nullable
|
||||
SqlRow findUnique(SqlQuery query, Transaction transaction);
|
||||
|
||||
/**
|
||||
@@ -1219,15 +1220,10 @@ public interface EbeanServer {
|
||||
*/
|
||||
void save(Object bean) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans in the iterator.
|
||||
*/
|
||||
int save(Iterator<?> it) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans in the collection.
|
||||
*/
|
||||
int save(Collection<?> beans) throws OptimisticLockException;
|
||||
int saveAll(Collection<?> beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete the bean.
|
||||
@@ -1238,15 +1234,10 @@ public interface EbeanServer {
|
||||
*/
|
||||
void delete(Object bean) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete all the beans from an Iterator.
|
||||
*/
|
||||
int delete(Iterator<?> it) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete all the beans in the collection.
|
||||
*/
|
||||
int delete(Collection<?> c) throws OptimisticLockException;
|
||||
int deleteAll(Collection<?> beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete the bean given its type and id.
|
||||
@@ -1261,13 +1252,18 @@ public interface EbeanServer {
|
||||
/**
|
||||
* Delete several beans given their type and id values.
|
||||
*/
|
||||
void delete(Class<?> beanType, Collection<?> ids);
|
||||
void deleteAll(Class<?> beanType, Collection<?> ids);
|
||||
|
||||
/**
|
||||
* Delete several beans given their type and id values with an explicit
|
||||
* transaction.
|
||||
*/
|
||||
void delete(Class<?> beanType, Collection<?> ids, Transaction transaction);
|
||||
void deleteAll(Class<?> beanType, Collection<?> ids, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Delete the bean with an explicit transaction.
|
||||
*/
|
||||
void delete(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Execute a Sql Update Delete or Insert statement. This returns the number of
|
||||
@@ -1325,7 +1321,7 @@ public interface EbeanServer {
|
||||
* Execute a ORM insert update or delete statement with an explicit
|
||||
* transaction.
|
||||
*/
|
||||
int execute(Update<?> update, Transaction t);
|
||||
int execute(Update<?> update, Transaction transaction);
|
||||
|
||||
/**
|
||||
* For making calls to stored procedures.
|
||||
@@ -1397,27 +1393,22 @@ public interface EbeanServer {
|
||||
* the type of entity bean to find
|
||||
* @param beanType
|
||||
* the type of entity bean to find
|
||||
* @param uid
|
||||
* @param id
|
||||
* the bean id value
|
||||
* @param transaction
|
||||
* the transaction to use (can be null)
|
||||
*/
|
||||
<T> T find(Class<T> beanType, Object uid, Transaction transaction);
|
||||
<T> T find(Class<T> beanType, Object id, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Insert or update a bean with an explicit transaction.
|
||||
*/
|
||||
void save(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans in the iterator with an explicit transaction.
|
||||
*/
|
||||
int save(Iterator<?> it, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Save all the beans in the collection with an explicit transaction.
|
||||
*/
|
||||
int save(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
|
||||
int saveAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Marks the entity bean as dirty.
|
||||
@@ -1482,7 +1473,7 @@ public interface EbeanServer {
|
||||
/**
|
||||
* Update a bean additionally specifying a transaction.
|
||||
*/
|
||||
void update(Object bean, Transaction t) throws OptimisticLockException;
|
||||
void update(Object bean, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a bean additionally specifying a transaction and the deleteMissingChildren setting.
|
||||
@@ -1502,13 +1493,13 @@ public interface EbeanServer {
|
||||
* Update a collection of beans. If there is no current transaction one is created and used to
|
||||
* update all the beans in the collection.
|
||||
*/
|
||||
void update(Collection<?> beans) throws OptimisticLockException;
|
||||
void updateAll(Collection<?> beans) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Update a collection of beans with an explicit transaction.
|
||||
*/
|
||||
void update(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
void updateAll(Collection<?> beans, Transaction transaction) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Insert the bean.
|
||||
* <p>
|
||||
@@ -1522,18 +1513,18 @@ public interface EbeanServer {
|
||||
/**
|
||||
* Insert the bean with a transaction.
|
||||
*/
|
||||
void insert(Object bean, Transaction t);
|
||||
void insert(Object bean, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Insert a collection of beans. If there is no current transaction one is created and used to
|
||||
* insert all the beans in the collection.
|
||||
*/
|
||||
void insert(Collection<?> beans);
|
||||
void insertAll(Collection<?> beans);
|
||||
|
||||
/**
|
||||
* Insert a collection of beans with an explicit transaction.
|
||||
*/
|
||||
void insert(Collection<?> beans, Transaction t);
|
||||
void insertAll(Collection<?> beans, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Delete the associations (from the intersection table) of a ManyToMany given
|
||||
@@ -1542,7 +1533,7 @@ public interface EbeanServer {
|
||||
* Typically these deletions occur automatically when persisting a ManyToMany
|
||||
* collection and this provides a way to invoke those deletions directly.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the number of associations deleted (from the intersection table).
|
||||
*/
|
||||
int deleteManyToManyAssociations(Object ownerBean, String propertyName);
|
||||
@@ -1557,10 +1548,10 @@ public interface EbeanServer {
|
||||
* Typically these deletions occur automatically when persisting a ManyToMany
|
||||
* collection and this provides a way to invoke those deletions directly.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @return the number of associations deleted (from the intersection table).
|
||||
*/
|
||||
int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
|
||||
int deleteManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Save the associations of a ManyToMany given the owner bean and the
|
||||
@@ -1582,7 +1573,7 @@ public interface EbeanServer {
|
||||
* way to invoke those insertions directly.
|
||||
* </p>
|
||||
*/
|
||||
void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction t);
|
||||
void saveManyToManyAssociations(Object ownerBean, String propertyName, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Save the associated collection or bean given the property name.
|
||||
@@ -1619,27 +1610,18 @@ public interface EbeanServer {
|
||||
* @param propertyName
|
||||
* the property we want to save
|
||||
*/
|
||||
void saveAssociation(Object ownerBean, String propertyName, Transaction t);
|
||||
void saveAssociation(Object ownerBean, String propertyName, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Delete the bean with an explicit transaction.
|
||||
*/
|
||||
void delete(Object bean, Transaction t) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Delete all the beans from an iterator.
|
||||
*/
|
||||
int delete(Iterator<?> it, Transaction t) throws OptimisticLockException;
|
||||
|
||||
/**
|
||||
* Execute explicitly passing a transaction.
|
||||
*/
|
||||
int execute(SqlUpdate updSql, Transaction t);
|
||||
int execute(SqlUpdate updSql, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute explicitly passing a transaction.
|
||||
*/
|
||||
int execute(CallableSql callableSql, Transaction t);
|
||||
int execute(CallableSql callableSql, Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute a TxRunnable in a Transaction with an explicit scope.
|
||||
@@ -1662,7 +1644,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
void execute(TxScope scope, TxRunnable r);
|
||||
void execute(TxScope scope, TxRunnable runnable);
|
||||
|
||||
/**
|
||||
* Execute a TxRunnable in a Transaction with the default scope.
|
||||
@@ -1688,7 +1670,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
void execute(TxRunnable r);
|
||||
void execute(TxRunnable runnable);
|
||||
|
||||
/**
|
||||
* Execute a TxCallable in a Transaction with an explicit scope.
|
||||
@@ -1712,7 +1694,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> T execute(TxScope scope, TxCallable<T> c);
|
||||
<T> T execute(TxScope scope, TxCallable<T> callable);
|
||||
|
||||
/**
|
||||
* Execute a TxCallable in a Transaction with the default scope.
|
||||
@@ -1744,7 +1726,7 @@ public interface EbeanServer {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
<T> T execute(TxCallable<T> c);
|
||||
<T> T execute(TxCallable<T> callable);
|
||||
|
||||
/**
|
||||
* Return the manager of the server cache ("L2" cache).
|
||||
@@ -1774,12 +1756,6 @@ public interface EbeanServer {
|
||||
*/
|
||||
void runCacheWarming(Class<?> beanType);
|
||||
|
||||
/**
|
||||
* Return the JsonContext for reading/writing JSON.
|
||||
* @deprecated Please use #json instead.
|
||||
*/
|
||||
JsonContext createJsonContext();
|
||||
|
||||
/**
|
||||
* Return the JsonContext for reading/writing JSON.
|
||||
* <p>
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.avaje.ebean;
|
||||
import com.avaje.ebean.common.SpiContainer;
|
||||
import com.avaje.ebean.config.ContainerConfig;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebeaninternal.server.lib.ShutdownManager;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -75,6 +76,32 @@ public class EbeanServerFactory {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
|
||||
*/
|
||||
public static synchronized EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
|
||||
|
||||
ClassLoader currentContextLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
try {
|
||||
return EbeanServerFactory.create(config);
|
||||
|
||||
} finally {
|
||||
// set the currentContextLoader back
|
||||
Thread.currentThread().setContextClassLoader(currentContextLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
|
||||
* <p>
|
||||
* This is typically invoked via JVM shutdown hook and not explicitly called.
|
||||
* </p>
|
||||
*/
|
||||
public static synchronized void shutdown() {
|
||||
ShutdownManager.shutdown();
|
||||
}
|
||||
|
||||
|
||||
private static EbeanServer createInternal(ServerConfig config) {
|
||||
|
||||
|
||||
@@ -169,7 +169,22 @@ public interface ExpressionFactory {
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
Expression in(String propertyName, Collection<?> values);
|
||||
|
||||
|
||||
/**
|
||||
* Not In - property has a value in the array of values.
|
||||
*/
|
||||
Expression notIn(String propertyName, Object[] values);
|
||||
|
||||
/**
|
||||
* Not In - property has a value in the collection of values.
|
||||
*/
|
||||
Expression notIn(String propertyName, Collection<?> values);
|
||||
|
||||
/**
|
||||
* Not In - using a subQuery.
|
||||
*/
|
||||
Expression notIn(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Exists expression
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -94,6 +96,17 @@ public interface ExpressionList<T> extends Serializable {
|
||||
*/
|
||||
Query<T> apply(PathProperties pathProperties);
|
||||
|
||||
/**
|
||||
* Perform an 'As of' query using history tables to return the object graph
|
||||
* as of a time in the past.
|
||||
* <p>
|
||||
* To perform this query the DB must have underlying history tables.
|
||||
* </p>
|
||||
*
|
||||
* @param asOf the date time in the past at which you want to view the data
|
||||
*/
|
||||
Query<T> asOf(Timestamp asOf);
|
||||
|
||||
/**
|
||||
* Execute the query iterating over the results.
|
||||
*
|
||||
@@ -116,14 +129,6 @@ public interface ExpressionList<T> extends Serializable {
|
||||
*/
|
||||
void findEachWhile(QueryEachWhileConsumer<T> consumer);
|
||||
|
||||
/**
|
||||
* Deprecated in favor of #findEachWhile which is functionally exactly the same
|
||||
* but has a much better name.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
void findVisit(QueryResultVisitor<T> visitor);
|
||||
|
||||
/**
|
||||
* Execute the query returning a list.
|
||||
*
|
||||
@@ -170,6 +175,7 @@ public interface ExpressionList<T> extends Serializable {
|
||||
*
|
||||
* @see Query#findUnique()
|
||||
*/
|
||||
@Nullable
|
||||
T findUnique();
|
||||
|
||||
/**
|
||||
@@ -229,6 +235,15 @@ public interface ExpressionList<T> extends Serializable {
|
||||
*/
|
||||
PagedList<T> findPagedList(int pageIndex, int pageSize);
|
||||
|
||||
/**
|
||||
* Return versions of a @History entity bean.
|
||||
* <p>
|
||||
* Generally this query is expected to be a find by id or unique predicates query.
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
List<Version<T>> findVersions();
|
||||
|
||||
/**
|
||||
* Add some filter predicate expressions to the many property.
|
||||
*/
|
||||
@@ -473,7 +488,22 @@ public interface ExpressionList<T> extends Serializable {
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
ExpressionList<T> in(String propertyName, Collection<?> values);
|
||||
|
||||
|
||||
/**
|
||||
* Not In - property has a value in the array of values.
|
||||
*/
|
||||
ExpressionList<T> notIn(String propertyName, Object... values);
|
||||
|
||||
/**
|
||||
* Not In - property has a value in the collection of values.
|
||||
*/
|
||||
ExpressionList<T> notIn(String propertyName, Collection<?> values);
|
||||
|
||||
/**
|
||||
* Not In - using a subQuery.
|
||||
*/
|
||||
ExpressionList<T> notIn(String propertyName, Query<?> subQuery);
|
||||
|
||||
/**
|
||||
* Exists expression
|
||||
*/
|
||||
|
||||
@@ -22,57 +22,57 @@ import java.io.Serializable;
|
||||
* efficient loaded as 2 SQL queries.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
* // Normal fetch join results in a single SQL query
|
||||
* List<Order> list = Ebean.find(Order.class).fetch("details").findList();
|
||||
* List<Order> list = Ebean.find(Order.class).fetch("details").findList();
|
||||
*
|
||||
* // Find Orders join details using a single SQL query
|
||||
* </pre>
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Example: Using a "query join" instead of a "fetch join" we instead use 2 SQL
|
||||
* queries
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
* // This will use 2 SQL queries to build this object graph
|
||||
* List<Order> list =
|
||||
* List<Order> list =
|
||||
* Ebean.find(Order.class)
|
||||
* .fetch("details", new FetchConfig().query())
|
||||
* .fetch("details", new FetchConfig().query())
|
||||
* .findList();
|
||||
*
|
||||
* // query 1) find order
|
||||
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
|
||||
* </pre>
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Example: Using 2 "query joins"
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
* // This will use 3 SQL queries to build this object graph
|
||||
* List<Order> list =
|
||||
* List<Order> list =
|
||||
* Ebean.find(Order.class)
|
||||
* .fetch("details", new FetchConfig().query())
|
||||
* .fetch("customer", new FetchConfig().queryFirst(5))
|
||||
* .fetch("details", new FetchConfig().query())
|
||||
* .fetch("customer", new FetchConfig().queryFirst(5))
|
||||
* .findList();
|
||||
*
|
||||
* // query 1) find order
|
||||
* // query 2) find orderDetails where order.id in (?,?...) // first 100 order id's
|
||||
* // query 3) find customer where id in (?,?,?,?,?) // first 5 customers
|
||||
* </pre>
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Example: Using "query joins" and partial objects
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
* // This will use 3 SQL queries to build this object graph
|
||||
* List<Order> list =
|
||||
* List<Order> list =
|
||||
* Ebean.find(Order.class)
|
||||
* .select("status, shipDate")
|
||||
* .fetch("details", "quantity, price", new FetchConfig().query())
|
||||
* .fetch("details.product", "sku, name")
|
||||
* .fetch("customer", "name", new FetchConfig().queryFirst(5))
|
||||
* .fetch("customer.contacts")
|
||||
* .fetch("customer.shippingAddress")
|
||||
* .select("status, shipDate")
|
||||
* .fetch("details", "quantity, price", new FetchConfig().query())
|
||||
* .fetch("details.product", "sku, name")
|
||||
* .fetch("customer", "name", new FetchConfig().queryFirst(5))
|
||||
* .fetch("customer.contacts")
|
||||
* .fetch("customer.shippingAddress")
|
||||
* .findList();
|
||||
*
|
||||
* // query 1) find order (status, shipDate)
|
||||
@@ -81,22 +81,22 @@ import java.io.Serializable;
|
||||
* // query 3) find customer (name) fetch contacts (*) fetch shippingAddress (*)
|
||||
* // where id in (?,?,?,?,?)
|
||||
*
|
||||
* // Note: the fetch of "details.product" is automatically included into the
|
||||
* // fetch of "details"
|
||||
* // Note: the fetch of "details.product" is automatically included into the
|
||||
* // fetch of "details"
|
||||
* //
|
||||
* // Note: the fetch of "customer.contacts" and "customer.shippingAddress"
|
||||
* // are automatically included in the fetch of "customer"
|
||||
* </pre>
|
||||
* // Note: the fetch of "customer.contacts" and "customer.shippingAddress"
|
||||
* // are automatically included in the fetch of "customer"
|
||||
* }</pre>
|
||||
* <p>
|
||||
* You can use query() and lazy together on a single join. The query is executed
|
||||
* immediately and the lazy defines the batch size to use for further lazy
|
||||
* loading (if lazy loading is invoked).
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* List<Order> list =
|
||||
* <pre>{@code
|
||||
* List<Order> list =
|
||||
* Ebean.find(Order.class)
|
||||
* .fetch("customer", new FetchConfig().query(10).lazy(5))
|
||||
* .fetch("customer", new FetchConfig().query(10).lazy(5))
|
||||
* .findList();
|
||||
*
|
||||
* // query 1) find order
|
||||
@@ -104,7 +104,7 @@ import java.io.Serializable;
|
||||
* // .. then if lazy loading of customers is invoked
|
||||
* // .. use a batch size of 5 to load the customers
|
||||
*
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* Example of controlling the lazy loading query:
|
||||
@@ -114,12 +114,12 @@ import java.io.Serializable;
|
||||
* case.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .fetch("customer","name", new FetchConfig().lazy(5))
|
||||
* .fetch("customer.contacts","contactName, phone, email")
|
||||
* .fetch("customer.shippingAddress")
|
||||
* .where().eq("status",Order.Status.NEW)
|
||||
* <pre>{@code
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .fetch("customer","name", new FetchConfig().lazy(5))
|
||||
* .fetch("customer.contacts","contactName, phone, email")
|
||||
* .fetch("customer.shippingAddress")
|
||||
* .where().eq("status",Order.Status.NEW)
|
||||
* .findList();
|
||||
*
|
||||
* // query 1) find order where status = Order.Status.NEW
|
||||
@@ -132,7 +132,7 @@ import java.io.Serializable;
|
||||
* fetch customer.shippingAddress (*)
|
||||
* where id in (?,?,?,?,?)
|
||||
*
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*
|
||||
* @author mario
|
||||
* @author rbygrave
|
||||
|
||||
@@ -2,14 +2,13 @@ package com.avaje.ebean;
|
||||
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebean.util.ClassUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A MappedSuperclass base class that provides convenience methods for inserting, updating and
|
||||
@@ -152,7 +151,7 @@ public abstract class Model {
|
||||
* }</pre>
|
||||
*/
|
||||
public static EbeanServer db() {
|
||||
return Ebean.getServer(null);
|
||||
return Ebean.getDefaultServer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,8 +450,8 @@ public abstract class Model {
|
||||
* Construct passing the class literal type of the entity type.
|
||||
*/
|
||||
protected Find(String serverName, Class<T> type) {
|
||||
this.type = type;
|
||||
this.serverName = serverName;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -514,6 +513,7 @@ public abstract class Model {
|
||||
* <p>
|
||||
* Equivalent to {@link EbeanServer#find(Class, Object)}
|
||||
*/
|
||||
@Nullable
|
||||
public T byId(I id) {
|
||||
return db().find(type, id);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class PrimaryServer {
|
||||
/**
|
||||
* Return the default server name.
|
||||
*/
|
||||
static synchronized String getPrimaryServerName() {
|
||||
static synchronized String getDefaultServerName() {
|
||||
getProperties();
|
||||
return defaultServerName;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -284,6 +286,17 @@ public interface Query<T> extends Serializable {
|
||||
*/
|
||||
Query<T> setRawSql(RawSql rawSql);
|
||||
|
||||
/**
|
||||
* Perform an 'As of' query using history tables to return the object graph
|
||||
* as of a time in the past.
|
||||
* <p>
|
||||
* To perform this query the DB must have underlying history tables.
|
||||
* </p>
|
||||
*
|
||||
* @param asOf the date time in the past at which you want to view the data
|
||||
*/
|
||||
Query<T> asOf(Timestamp asOf);
|
||||
|
||||
/**
|
||||
* Cancel the query execution if supported by the underlying database and
|
||||
* driver.
|
||||
@@ -483,7 +496,7 @@ public interface Query<T> extends Serializable {
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
Query<T> fetch(String path, FetchConfig joinConfig);
|
||||
Query<T> fetch(String path, FetchConfig fetchConfig);
|
||||
|
||||
/**
|
||||
* Apply the path properties replacing the select and fetch clauses.
|
||||
@@ -520,19 +533,7 @@ public interface Query<T> extends Serializable {
|
||||
*/
|
||||
QueryIterator<T> findIterate();
|
||||
|
||||
/**
|
||||
* This is deprecated in favor of #findEachWhile.
|
||||
* <p>
|
||||
* This is functionally exactly the same as #findEachWhile. It is
|
||||
* replaced by findEachWhile because the method name is much better.
|
||||
* </p>
|
||||
*
|
||||
* @param visitor
|
||||
* the visitor used to process the queried beans.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
void findVisit(QueryResultVisitor<T> visitor);
|
||||
|
||||
|
||||
/**
|
||||
* Execute the query processing the beans one at a time.
|
||||
@@ -716,8 +717,18 @@ public interface Query<T> extends Serializable {
|
||||
* ...
|
||||
* }</pre>
|
||||
*/
|
||||
@Nullable
|
||||
T findUnique();
|
||||
|
||||
/**
|
||||
* Return versions of a @History entity bean.
|
||||
* <p>
|
||||
* Generally this query is expected to be a find by id or unique predicates query.
|
||||
* It will execute the query against the history returning the versions of the bean.
|
||||
* </p>
|
||||
*/
|
||||
List<Version<T>> findVersions();
|
||||
|
||||
/**
|
||||
* Return the count of entities this query should return.
|
||||
* <p>
|
||||
@@ -878,6 +889,11 @@ public interface Query<T> extends Serializable {
|
||||
*/
|
||||
Query<T> setId(Object id);
|
||||
|
||||
/**
|
||||
* Return the Id value.
|
||||
*/
|
||||
Object getId();
|
||||
|
||||
/**
|
||||
* Add additional clause(s) to the where clause.
|
||||
* <p>
|
||||
@@ -1123,8 +1139,8 @@ public interface Query<T> extends Serializable {
|
||||
|
||||
/**
|
||||
* Set the first row to return for this query.
|
||||
*
|
||||
* @param firstRow
|
||||
*
|
||||
* @param firstRow the first row to include in the query result.
|
||||
*/
|
||||
Query<T> setFirstRow(int firstRow);
|
||||
|
||||
@@ -1235,4 +1251,10 @@ public interface Query<T> extends Serializable {
|
||||
* Set root table alias.
|
||||
*/
|
||||
Query<T> alias(String alias);
|
||||
|
||||
/**
|
||||
* Return the type of beans being queried.
|
||||
*/
|
||||
Class<T> getBeanType();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
/**
|
||||
* Used to process a query result one bean at a time via a callback to this
|
||||
* visitor.
|
||||
* <p>
|
||||
* If you wish to stop further processing return false from the accept method.
|
||||
* </p>
|
||||
* <p>
|
||||
* Unlike findList() and findSet() using a QueryResultVisitor does not require
|
||||
* all the beans in the query result to be held in memory at once. This makes
|
||||
* QueryResultVisitor useful for processing large queries.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
*
|
||||
* Query<Customer> query = server.find(Customer.class)
|
||||
* .fetch("contacts", new FetchConfig().query(2))
|
||||
* .where().gt("id", 0)
|
||||
* .orderBy("id")
|
||||
* .setMaxRows(2);
|
||||
*
|
||||
* query.findVisit(new QueryResultVisitor<Customer>() {
|
||||
*
|
||||
* public boolean accept(Customer customer) {
|
||||
* // do something with customer
|
||||
* System.out.println("-- visit " + customer);
|
||||
* return true;
|
||||
* }
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @author rbygrave
|
||||
*
|
||||
* @param <T>
|
||||
* the type of entity bean being queried.
|
||||
*/
|
||||
public interface QueryResultVisitor<T> {
|
||||
|
||||
/**
|
||||
* Process the bean and return true if you want to continue processing more
|
||||
* beans. Return false if you want to stop processing further.
|
||||
*
|
||||
* @param bean
|
||||
* the entity bean to process
|
||||
* @return true to continue processing or false to stop.
|
||||
*/
|
||||
boolean accept(T bean);
|
||||
}
|
||||
@@ -480,6 +480,13 @@ public final class RawSql implements Serializable {
|
||||
this.queryHashCode = hc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the property is mapped.
|
||||
*/
|
||||
public boolean contains(String property) {
|
||||
return this.propertyColumnMap.containsKey(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an immutable copy of this ColumnMapping.
|
||||
*
|
||||
|
||||
@@ -97,6 +97,17 @@ public interface Transaction extends Closeable {
|
||||
*/
|
||||
void setPersistCascade(boolean persistCascade);
|
||||
|
||||
/**
|
||||
* Set to true when you want all loaded properties to be included in the update
|
||||
* (rather than just the changed properties).
|
||||
* <p>
|
||||
* You might set this when using JDBC batch in order to get multiple updates
|
||||
* with slightly different sets of changed properties into the same statement
|
||||
* and hence better JDBC batch performance.
|
||||
* </p>
|
||||
*/
|
||||
void setUpdateAllLoadedProperties(boolean updateAllLoadedProperties);
|
||||
|
||||
/**
|
||||
* Turn on or off statement batching. Statement batching can be transparent
|
||||
* for drivers and databases that support getGeneratedKeys. Otherwise you may
|
||||
|
||||
@@ -5,10 +5,19 @@ package com.avaje.ebean;
|
||||
*/
|
||||
public class ValuePair {
|
||||
|
||||
private final Object newValue;
|
||||
protected Object newValue;
|
||||
|
||||
private final Object oldValue;
|
||||
protected Object oldValue;
|
||||
|
||||
/**
|
||||
* Default constructor for JSON tools.
|
||||
*/
|
||||
public ValuePair() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct with the pair of new and old values.
|
||||
*/
|
||||
public ValuePair(Object newValue, Object oldValue) {
|
||||
this.newValue = newValue;
|
||||
this.oldValue = oldValue;
|
||||
@@ -27,21 +36,19 @@ public class ValuePair {
|
||||
public Object getOldValue() {
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the new value.
|
||||
* Set the new value.
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getValue1() {
|
||||
return newValue;
|
||||
public void setNewValue(Object newValue) {
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the old value.
|
||||
* Set the old value.
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getValue2() {
|
||||
return oldValue;
|
||||
public void setOldValue(Object oldValue) {
|
||||
this.oldValue = oldValue;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.avaje.ebean;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Wraps a version of a @History bean.
|
||||
*/
|
||||
public class Version<T> {
|
||||
|
||||
/**
|
||||
* The version of the bean.
|
||||
*/
|
||||
protected T bean;
|
||||
|
||||
/**
|
||||
* The effective start date time of this version.
|
||||
*/
|
||||
protected Timestamp start;
|
||||
|
||||
/**
|
||||
* The effective end date time of this version.
|
||||
*/
|
||||
protected Timestamp end;
|
||||
|
||||
/**
|
||||
* The map of changed properties.
|
||||
*/
|
||||
protected Map<String, ValuePair> diff;
|
||||
|
||||
/**
|
||||
* Construct with bean and an effective date time range.
|
||||
*/
|
||||
public Version(T bean, Timestamp start, Timestamp end) {
|
||||
this.bean = bean;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor - useful for JSON tools such as Jackson.
|
||||
*/
|
||||
public Version() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean instance for this version.
|
||||
*/
|
||||
public T getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bean instance for this version.
|
||||
*/
|
||||
public void setBean(T bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the effective start date time of this version.
|
||||
*/
|
||||
public Timestamp getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the effective start date time of this version.
|
||||
*/
|
||||
public void setStart(Timestamp start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the effective end date time of this version.
|
||||
*/
|
||||
public Timestamp getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the effective end date time of this version.
|
||||
*/
|
||||
public void setEnd(Timestamp end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the map of differences from this bean to the prior version.
|
||||
*/
|
||||
public void setDiff(Map<String, ValuePair> diff) {
|
||||
this.diff = diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map of differences from this bean to the prior version.
|
||||
*/
|
||||
public Map<String, ValuePair> getDiff() {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
@@ -55,4 +55,4 @@ public @interface CacheStrategy {
|
||||
*/
|
||||
String warmingQuery() default "";
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -44,4 +44,12 @@ public @interface CacheTuning {
|
||||
* </p>
|
||||
*/
|
||||
int maxSecsToLive() default 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The frequency (in seconds) that cache trimming should occur.
|
||||
* <p>
|
||||
* This is a hint for cache implementations that use background cache trimming.
|
||||
* </p>
|
||||
*/
|
||||
int trimFrequency() default 0;
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ColumnHstore {
|
||||
|
||||
}
|
||||
@@ -18,14 +18,17 @@ import java.lang.annotation.Target;
|
||||
* timestamp value after the insert has occurred. You need to fetch the entity
|
||||
* back to get the inserted timestamp if you want to used it.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Column(insertable = false, updateable = false)
|
||||
* Timestamp cretimestamp;
|
||||
* </pre>
|
||||
*
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @CreatedTimestamp
|
||||
* Timestamp whenCreated;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CreatedTimestamp {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Used for mapping a Map<String,String> type property to Postgres HSTORE data type.
|
||||
* <p>
|
||||
* The Map property should have keys and values of type String.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @DbHstore
|
||||
* Map<String, String> tags;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DbHstore {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specify a property holding JSON content.
|
||||
* <p>
|
||||
* By default the content will be stored in a DB Clob except on Postgres where DB JSON type is used.
|
||||
* </p>
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Store as JSON on Postgres or Clob on other databases
|
||||
* @DbJson
|
||||
* Map<String,Object> content;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Example with JSONB storage</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Store as JSONB on Postgres or Clob on other databases
|
||||
* @DbJson(storage = DbJsonType.JSONB)
|
||||
* Map<String,Object> content;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DbJson {
|
||||
|
||||
/**
|
||||
* Specify the database type used to store the JSON content.
|
||||
*/
|
||||
DbJsonType storage() default DbJsonType.JSON;
|
||||
|
||||
/**
|
||||
* For VARCHAR storage specify the column length (defaults to 3000).
|
||||
*/
|
||||
int length() default 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specify a property holding JSON content.
|
||||
* <p>
|
||||
* The content will be stored on Postgres using it's JSONB type and as Clob for other databases.
|
||||
* </p>
|
||||
* <p>
|
||||
* This is equivalent to using <code>@DbJson(storage = DbJsonType.JSONB)</code>
|
||||
* </p>
|
||||
*
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Store as JSONB on Postgres or Clob on other databases
|
||||
* @DbJsonB
|
||||
* Map<String,Object> content;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Equivalent to:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // Store as JSONB on Postgres or Clob on other databases
|
||||
* @DbJson(storage = DbJsonType.JSONB)
|
||||
* Map<String,Object> content;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DbJsonB {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
/**
|
||||
* Specify the DB storage type used to store JSON content.
|
||||
*/
|
||||
public enum DbJsonType {
|
||||
|
||||
/**
|
||||
* Store as JSON on Postgres and for other databases store as CLOB.
|
||||
*/
|
||||
JSON,
|
||||
|
||||
/**
|
||||
* Store as JSONB on Postgres and for other databases store as CLOB.
|
||||
*/
|
||||
JSONB,
|
||||
|
||||
/**
|
||||
* Store as database VARCHAR.
|
||||
*/
|
||||
VARCHAR,
|
||||
|
||||
/**
|
||||
* Store as database CLOB.
|
||||
*/
|
||||
CLOB,
|
||||
|
||||
/**
|
||||
* Store as database BLOB.
|
||||
*/
|
||||
BLOB
|
||||
}
|
||||
@@ -28,4 +28,4 @@ public @interface EmbeddedColumns {
|
||||
*/
|
||||
String columns() default "";
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ public @interface Encrypted {
|
||||
* Used to specify the DB column length.
|
||||
*/
|
||||
int dbLength() default 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,4 +87,4 @@ public @interface EnumMapping {
|
||||
* The length of DB column if mapping to string values.
|
||||
*/
|
||||
int length() default 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,19 +8,21 @@ import java.lang.annotation.Target;
|
||||
/**
|
||||
* Enables you to specify a value to use to persist for an enum value.
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
*
|
||||
* public enum Status {
|
||||
* @EnumValue("N")
|
||||
*
|
||||
* @EnumValue("N")
|
||||
* NEW,
|
||||
*
|
||||
* @EnumValue("A")
|
||||
* @EnumValue("A")
|
||||
* ACTIVE,
|
||||
*
|
||||
* @EnumValue("I")
|
||||
* @EnumValue("I")
|
||||
* INACTIVE,
|
||||
* }
|
||||
*
|
||||
* </pre>
|
||||
* }</pre>
|
||||
* <p>
|
||||
* This is an alternative to using the JPA standard approach or Ebean's
|
||||
* {@link EnumMapping} annotation.
|
||||
@@ -43,4 +45,4 @@ public @interface EnumValue {
|
||||
* </p>
|
||||
*/
|
||||
String value();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,17 +12,17 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Expose {
|
||||
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is written out in the JSON while
|
||||
* serializing. If {@code false}, the field marked with this annotation is skipped from the
|
||||
* serialized output. Defaults to {@code true}.
|
||||
*/
|
||||
public boolean serialize() default true;
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is written out in the JSON while
|
||||
* serializing. If {@code false}, the field marked with this annotation is skipped from the
|
||||
* serialized output. Defaults to {@code true}.
|
||||
*/
|
||||
boolean serialize() default true;
|
||||
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is deserialized from the JSON.
|
||||
* If {@code false}, the field marked with this annotation is skipped during deserialization.
|
||||
* Defaults to {@code true}.
|
||||
*/
|
||||
public boolean deserialize() default true;
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is deserialized from the JSON.
|
||||
* If {@code false}, the field marked with this annotation is skipped during deserialization.
|
||||
* Defaults to {@code true}.
|
||||
*/
|
||||
boolean deserialize() default true;
|
||||
}
|
||||
@@ -39,30 +39,31 @@ import com.avaje.ebean.Query;
|
||||
* queries - it needs to be explicitly included.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
*
|
||||
* // find by Id
|
||||
* Order o1 = Ebean.find(Order.class)
|
||||
* .select("id, totalAmount")
|
||||
* .select("id, totalAmount")
|
||||
* .setId(1).findUnique();
|
||||
*
|
||||
* // find list ... using totalAmount in the where clause
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .select("id, totalAmount")
|
||||
* List<Order> list = Ebean.find(Order.class)
|
||||
* .select("id, totalAmount")
|
||||
* .where()
|
||||
* .eq("status", Order.Status.NEW)
|
||||
* .gt("totalAmount", 10)
|
||||
* .eq("status", Order.Status.NEW)
|
||||
* .gt("totalAmount", 10)
|
||||
* .findList();
|
||||
*
|
||||
* // as a join from customer
|
||||
* List<Customer> l0 = Ebean.find(Customer.class)
|
||||
* .select("id, name")
|
||||
* .join("orders", "status, totalAmount")
|
||||
* List<Customer> l0 = Ebean.find(Customer.class)
|
||||
* .select("id, name")
|
||||
* .fetch("orders", "status, totalAmount")
|
||||
* .where()
|
||||
* .gt("id", 0)
|
||||
* .gt("orders.totalAmount", 10)
|
||||
* .gt("id", 0)
|
||||
* .gt("orders.totalAmount", 10)
|
||||
* .findList();
|
||||
*
|
||||
* </pre>
|
||||
* }</pre>
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -94,10 +95,12 @@ public @interface Formula {
|
||||
* user.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
*
|
||||
* join (select user_id, count(*) as topic_count from f_topic group by user_id) as _tc on _tc.user_id = ${ta}.id
|
||||
* </pre>
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
String join() default "";
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an entity bean as having history support.
|
||||
* <p>
|
||||
* In Postgres for example this means there is an associated history table which is
|
||||
* typically automatically populated via database triggers.
|
||||
* </p>
|
||||
*/
|
||||
@Target({ ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface History {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a property as being excluded from history.
|
||||
* <p>
|
||||
* This means the property values are not maintained in the history table. Typically this
|
||||
* would be placed on relatively large properties (Clobs, Blobs, large varchar columns etc)
|
||||
* that are considered not interesting enough to maintain history on excluding them reduces
|
||||
* underlying database costs.
|
||||
* </p>
|
||||
* <p>
|
||||
* When placed on a ManyToMany this means that the intersection table does not have history
|
||||
* support.
|
||||
* </p>
|
||||
*/
|
||||
@Target({ ElementType.FIELD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface HistoryExclude {
|
||||
|
||||
}
|
||||
@@ -14,11 +14,11 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Index {
|
||||
|
||||
/**
|
||||
* Name of the index
|
||||
*
|
||||
* @return index name
|
||||
*/
|
||||
String value() default "";
|
||||
/**
|
||||
* Name of the index
|
||||
*
|
||||
* @return index name
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Similar to Jackson JsonIgnore but provides the option to just ignore serialize or deserialize.
|
||||
* <p>
|
||||
* This provides the same features as Expose but from the opposite perspective which is probably
|
||||
* more common and more familiar to Jackson users.
|
||||
* </p>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface JsonIgnore {
|
||||
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is written out in the JSON while
|
||||
* serializing. If {@code false}, the field marked with this annotation is skipped from the
|
||||
* serialized output. Defaults to {@code false}.
|
||||
*/
|
||||
boolean serialize() default false;
|
||||
|
||||
/**
|
||||
* If {@code true}, the field marked with this annotation is deserialized from the JSON.
|
||||
* If {@code false}, the field marked with this annotation is skipped during deserialization.
|
||||
* Defaults to {@code false}.
|
||||
*/
|
||||
boolean deserialize() default false;
|
||||
}
|
||||
@@ -34,4 +34,4 @@ public @interface NamedUpdate {
|
||||
*/
|
||||
boolean notifyCache() default true;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,4 +17,4 @@ public @interface NamedUpdates {
|
||||
*/
|
||||
NamedUpdate[] value();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ public @interface PrivateOwned {
|
||||
*/
|
||||
boolean cascadeRemove() default true;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ public @interface Sql {
|
||||
*/
|
||||
SqlSelect[] select() default { @SqlSelect };
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -295,4 +295,4 @@ public @interface SqlSelect {
|
||||
* Set this to true to have debug output when Ebean parses the sql-select.
|
||||
*/
|
||||
boolean debug() default false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,4 +125,4 @@ public @interface Transactional {
|
||||
*/
|
||||
Class<? extends Throwable>[] noRollbackFor() default {};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ public @interface UpdateMode {
|
||||
*/
|
||||
boolean updateChangesOnly() default true;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,4 +13,4 @@ import java.lang.annotation.Target;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface UpdatedTimestamp {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* For a timestamp property that is set to the datetime when the entity is
|
||||
* created/inserted.
|
||||
* <p>
|
||||
* This is effectively an alias for @CreatedTimestamp and added to hint
|
||||
* towards a better naming convention (WhenCreated, WhenModified).
|
||||
* </p>
|
||||
* <p>
|
||||
* An alternative to using this annotation would be to use insertable=false,
|
||||
* updateable=false with @Column and have the DB insert the current time
|
||||
* (default value on the DB column is SYSTIME etc).
|
||||
* </p>
|
||||
* <p>
|
||||
* The downside to this approach is that the inserted entity does not have the
|
||||
* timestamp value after the insert has occurred. You need to fetch the entity
|
||||
* back to get the inserted timestamp if you want to used it.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @WhenCreated
|
||||
* Timestamp whenCreated;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WhenCreated {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* For a timestamp property that is set to the datetime when the entity was last modified.
|
||||
* <p>
|
||||
* This is effectively an alias for @UpdatedTimestamp and added to hint
|
||||
* towards a better naming convention (WhenCreated, WhenModified).
|
||||
* </p>
|
||||
* </p>
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WhenModified {
|
||||
|
||||
}
|
||||
@@ -9,26 +9,29 @@ import java.lang.annotation.Target;
|
||||
* Add an Literal to add to the where clause when a many property (List, Set or
|
||||
* Map) is loaded or refreshed.
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
*
|
||||
* // on a OneToMany property...
|
||||
*
|
||||
* @OneToMany
|
||||
* @Where(clause = "deleted='y'")
|
||||
* List<Topic> topics;
|
||||
* </pre>
|
||||
* @OneToMany
|
||||
* @Where(clause = "deleted='y'")
|
||||
* List<Topic> topics;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* Note that you can include "${ta}" as a place holder for the table alias if
|
||||
* you need to include the table alias in the clause.
|
||||
* </p>
|
||||
*
|
||||
* <pre class="code">
|
||||
* <pre>{@code
|
||||
* // ... including the ${ta} table alias placeholder...
|
||||
*
|
||||
* @OneToMany
|
||||
* @Where(clause = "${ta}.deleted='y'")
|
||||
* List<Topic> topics;
|
||||
* </pre>
|
||||
* @OneToMany
|
||||
* @Where(clause = "${ta}.deleted='y'")
|
||||
* List<Topic> topics;
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* This will be added to the where clause when lazy loading the OneToMany
|
||||
@@ -48,4 +51,4 @@ public @interface Where {
|
||||
*/
|
||||
String clause();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Mapped onto a entity bean property that represents the user id of
|
||||
* who created the entity>
|
||||
* <p>
|
||||
* To use this annotation you need to implement CurrentUserProvider.
|
||||
* The type of the bean property should match the type returned by
|
||||
* CurrentUserProvider.
|
||||
*</p>
|
||||
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @WhoCreated
|
||||
* String whoCreated;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WhoCreated {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avaje.ebean.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Mapped onto a entity bean property that represents the user id of
|
||||
* who last modified the entity>
|
||||
* <p>
|
||||
* To use this annotation you need to implement CurrentUserProvider.
|
||||
* The type of the bean property should match the type returned by
|
||||
* CurrentUserProvider.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Example:</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* @WhoModified
|
||||
* String whoModified;
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WhoModified {
|
||||
|
||||
}
|
||||
@@ -608,7 +608,7 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
} else if (embeddedDirty != null && embeddedDirty[i]) {
|
||||
// an embedded property has been changed - recurse
|
||||
EntityBean embeddedBean = (EntityBean)owner._ebean_getField(i);
|
||||
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, getProperty(i)+".");
|
||||
embeddedBean._ebean_getIntercept().addDirtyPropertyValues(dirtyValues, getProperty(i) + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,6 +638,20 @@ public final class EntityBeanIntercept implements Serializable {
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a loaded property hash.
|
||||
*/
|
||||
public int getLoadedPropertyHash() {
|
||||
int hash = 37;
|
||||
int len = getPropertyLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (isLoadedProperty(i)) {
|
||||
hash = hash * 31 + (i+1);
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of property names for changed properties.
|
||||
*/
|
||||
|
||||
@@ -48,12 +48,6 @@ public interface ServerCache {
|
||||
*/
|
||||
Object put(Object id, Object value);
|
||||
|
||||
/**
|
||||
* Put the value in the cache but only if a matching value is not already in
|
||||
* the cache.
|
||||
*/
|
||||
Object putIfAbsent(Object id, Object value);
|
||||
|
||||
/**
|
||||
* Remove a entry from the cache given its id.
|
||||
*/
|
||||
|
||||
+24
-5
@@ -10,6 +10,7 @@ public class ServerCacheOptions {
|
||||
private int maxSize;
|
||||
private int maxIdleSecs;
|
||||
private int maxSecsToLive;
|
||||
private int trimFrequency;
|
||||
|
||||
/**
|
||||
* Construct with no set options.
|
||||
@@ -25,15 +26,17 @@ public class ServerCacheOptions {
|
||||
this.maxSize = cacheTuning.maxSize();
|
||||
this.maxIdleSecs = cacheTuning.maxIdleSecs();
|
||||
this.maxSecsToLive = cacheTuning.maxSecsToLive();
|
||||
this.trimFrequency = cacheTuning.trimFrequency();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create merging default options with the deployment specified ones.
|
||||
*/
|
||||
public ServerCacheOptions(ServerCacheOptions d) {
|
||||
this.maxSize = d.getMaxSize();
|
||||
this.maxIdleSecs = d.getMaxIdleSecs();
|
||||
this.maxSecsToLive = d.getMaxIdleSecs();
|
||||
public ServerCacheOptions(ServerCacheOptions defaults) {
|
||||
this.maxSize = defaults.getMaxSize();
|
||||
this.maxIdleSecs = defaults.getMaxIdleSecs();
|
||||
this.maxSecsToLive = defaults.getMaxIdleSecs();
|
||||
this.trimFrequency = defaults.getTrimFrequency();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +53,9 @@ public class ServerCacheOptions {
|
||||
if (maxSecsToLive == 0) {
|
||||
maxSecsToLive = defaults.getMaxSecsToLive();
|
||||
}
|
||||
if (trimFrequency == 0) {
|
||||
trimFrequency = defaults.getTrimFrequency();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +67,7 @@ public class ServerCacheOptions {
|
||||
copy.maxSize = maxSize;
|
||||
copy.maxIdleSecs = maxIdleSecs;
|
||||
copy.maxSecsToLive = maxSecsToLive;
|
||||
|
||||
copy.trimFrequency = trimFrequency;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -107,4 +113,17 @@ public class ServerCacheOptions {
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trim frequency in seconds.
|
||||
*/
|
||||
public int getTrimFrequency() {
|
||||
return trimFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the trim frequency in seconds.
|
||||
*/
|
||||
public void setTrimFrequency(int trimFrequency) {
|
||||
this.trimFrequency = trimFrequency;
|
||||
}
|
||||
}
|
||||
|
||||
+175
-23
@@ -5,9 +5,9 @@ package com.avaje.ebean.cache;
|
||||
* <p>
|
||||
* These can be monitored to review the effectiveness of a particular cache.
|
||||
* </p>
|
||||
*
|
||||
* @author rbygrave
|
||||
*
|
||||
* <p>
|
||||
* Depending on the cache implementation not all the statistics may be collected.
|
||||
* </p>
|
||||
*/
|
||||
public class ServerCacheStatistics {
|
||||
|
||||
@@ -17,21 +17,63 @@ public class ServerCacheStatistics {
|
||||
|
||||
protected int size;
|
||||
|
||||
protected int hitCount;
|
||||
protected long hitCount;
|
||||
|
||||
protected int missCount;
|
||||
protected long missCount;
|
||||
|
||||
protected long insertCount;
|
||||
|
||||
protected long updateCount;
|
||||
|
||||
protected long removeCount;
|
||||
|
||||
protected long clearCount;
|
||||
|
||||
protected long evictionRunCount;
|
||||
|
||||
protected long evictionRunMicros;
|
||||
|
||||
protected long evictByIdle;
|
||||
|
||||
protected long evictByTTL;
|
||||
|
||||
protected long evictByLRU;
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(cacheName);
|
||||
sb.append(" maxSize:").append(maxSize);
|
||||
sb.append(" size:").append(size);
|
||||
sb.append(" hitRatio:").append(getHitRatio());
|
||||
sb.append(" hitCount:").append(hitCount);
|
||||
sb.append(" missCount:").append(missCount);
|
||||
sb.append(" maxSize:").append(maxSize);
|
||||
sb.append(" hit:").append(hitCount);
|
||||
sb.append(" miss:").append(missCount);
|
||||
sb.append(" insert:").append(insertCount);
|
||||
sb.append(" update:").append(updateCount);
|
||||
sb.append(" remove:").append(removeCount);
|
||||
sb.append(" clear:").append(clearCount);
|
||||
sb.append(" evictByIdle:").append(evictByIdle);
|
||||
sb.append(" evictByTTL:").append(evictByTTL);
|
||||
sb.append(" evictByLRU:").append(evictByLRU);
|
||||
sb.append(" evictionRunCount:").append(evictionRunCount);
|
||||
sb.append(" evictionRunMicros:").append(evictionRunMicros);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int from 0 to 100 (percentage) for the hit ratio.
|
||||
* <p>
|
||||
* A hit ratio of 100 means every get request against the cache hits an entry.
|
||||
* </p>
|
||||
*/
|
||||
public int getHitRatio() {
|
||||
long totalCount = hitCount + missCount;
|
||||
if (totalCount == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return (int)(hitCount * 100 / totalCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the cache.
|
||||
*/
|
||||
@@ -49,28 +91,28 @@ public class ServerCacheStatistics {
|
||||
/**
|
||||
* Return the hit count. The number of successful gets.
|
||||
*/
|
||||
public int getHitCount() {
|
||||
public long getHitCount() {
|
||||
return hitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the hit count.
|
||||
*/
|
||||
public void setHitCount(int hitCount) {
|
||||
public void setHitCount(long hitCount) {
|
||||
this.hitCount = hitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the miss count. The number of gets that returned null.
|
||||
*/
|
||||
public int getMissCount() {
|
||||
public long getMissCount() {
|
||||
return missCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the miss count.
|
||||
*/
|
||||
public void setMissCount(int missCount) {
|
||||
public void setMissCount(long missCount) {
|
||||
this.missCount = missCount;
|
||||
}
|
||||
|
||||
@@ -107,18 +149,128 @@ public class ServerCacheStatistics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int from 0 to 100 (percentage) for the hit ratio.
|
||||
* <p>
|
||||
* A hit ratio of 100 means every get request against the cache hits an entry.
|
||||
* </p>
|
||||
* Set the put insert count.
|
||||
*/
|
||||
public int getHitRatio() {
|
||||
int totalCount = hitCount + missCount;
|
||||
if (totalCount == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return hitCount * 100 / totalCount;
|
||||
}
|
||||
public void setInsertCount(long insertCount) {
|
||||
this.insertCount = insertCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the put insert count.
|
||||
*/
|
||||
public long getInsertCount() {
|
||||
return insertCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the put update count.
|
||||
*/
|
||||
public void setUpdateCount(long updateCount) {
|
||||
this.updateCount = updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the put update count.
|
||||
*/
|
||||
public long getUpdateCount() {
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the remove count.
|
||||
*/
|
||||
public void setRemoveCount(long removeCount) {
|
||||
this.removeCount = removeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the remove count.
|
||||
*/
|
||||
public long getRemoveCount() {
|
||||
return removeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clear count.
|
||||
*/
|
||||
public void setClearCount(long clearCount) {
|
||||
this.clearCount = clearCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the clear count.
|
||||
*/
|
||||
public long getClearCount() {
|
||||
return clearCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the eviction run count.
|
||||
*/
|
||||
public void setEvictionRunCount(long evictCount) {
|
||||
this.evictionRunCount = evictCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the eviction run count.
|
||||
*/
|
||||
public long getEvictionRunCount() {
|
||||
return evictionRunCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the eviction run time in micros.
|
||||
*/
|
||||
public void setEvictionRunMicros(long evictionRunMicros) {
|
||||
this.evictionRunMicros = evictionRunMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the eviction run time in micros.
|
||||
*/
|
||||
public long getEvictionRunMicros() {
|
||||
return evictionRunMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the count of entries evicted due to idle time.
|
||||
*/
|
||||
public void setEvictByIdle(long evictByIdle) {
|
||||
this.evictByIdle = evictByIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of entries evicted due to idle time.
|
||||
*/
|
||||
public long getEvictByIdle() {
|
||||
return evictByIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the count of entries evicted due to time to live.
|
||||
*/
|
||||
public void setEvictByTTL(long evictByTTL) {
|
||||
this.evictByTTL = evictByTTL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of entries evicted due to time to live.
|
||||
*/
|
||||
public long getEvictByTTL() {
|
||||
return evictByTTL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the count of entries evicted due to time least recently used.
|
||||
*/
|
||||
public void setEvictByLRU(long evictByLRU) {
|
||||
this.evictByLRU = evictByLRU;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of entries evicted due to time least recently used.
|
||||
*/
|
||||
public long getEvictByLRU() {
|
||||
return evictByLRU;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,9 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
if (list == null) {
|
||||
list = new ArrayList<E>();
|
||||
}
|
||||
list.add((E) bean);
|
||||
if (bean != null) {
|
||||
list.add((E) bean);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkEmptyLazyLoad() {
|
||||
@@ -154,7 +156,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(50);
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
sb.append("BeanList ");
|
||||
if (isReadOnly()) {
|
||||
sb.append("readOnly ");
|
||||
@@ -348,7 +350,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
boolean changed = false;
|
||||
Iterator<?> it = c.iterator();
|
||||
while (it.hasNext()) {
|
||||
Object o = (Object) it.next();
|
||||
Object o = it.next();
|
||||
if (list.remove(o)) {
|
||||
modifyRemoval(o);
|
||||
changed = true;
|
||||
@@ -366,7 +368,7 @@ public final class BeanList<E> extends AbstractBeanCollection<E> implements List
|
||||
boolean changed = false;
|
||||
Iterator<E> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
Object o = (Object) it.next();
|
||||
Object o = it.next();
|
||||
if (!c.contains(o)) {
|
||||
it.remove();
|
||||
modifyRemoval(o);
|
||||
|
||||
@@ -52,12 +52,20 @@ public final class BeanMap<K, E> extends AbstractBeanCollection<E> implements Ma
|
||||
return !touched && (map == null || map.isEmpty());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void internalPutNull() {
|
||||
if (map == null) {
|
||||
map = new LinkedHashMap<K, E>();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void internalPut(Object key, Object bean) {
|
||||
if (map == null) {
|
||||
map = new LinkedHashMap<K, E>();
|
||||
}
|
||||
map.put((K)key, (E)bean);
|
||||
if (key != null) {
|
||||
map.put((K) key, (E) bean);
|
||||
}
|
||||
}
|
||||
|
||||
public void internalAdd(Object bean) {
|
||||
|
||||
@@ -62,7 +62,9 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
if (set == null) {
|
||||
set = new LinkedHashSet<E>();
|
||||
}
|
||||
set.add((E) bean);
|
||||
if (bean != null) {
|
||||
set.add((E) bean);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,15 +145,8 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying set.
|
||||
*/
|
||||
public Object getActualCollection() {
|
||||
return set;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer(50);
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
sb.append("BeanSet ");
|
||||
if (isReadOnly()) {
|
||||
sb.append("readOnly ");
|
||||
@@ -274,7 +269,7 @@ public final class BeanSet<E> extends AbstractBeanCollection<E> implements Set<E
|
||||
boolean changed = false;
|
||||
Iterator<?> it = c.iterator();
|
||||
while (it.hasNext()) {
|
||||
Object o = (Object) it.next();
|
||||
Object o = it.next();
|
||||
if (set.remove(o)) {
|
||||
modifyRemoval(o);
|
||||
changed = true;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.avaje.ebean.config;
|
||||
|
||||
/**
|
||||
* Provides the current user in order to support 'Who created', 'Who modified' and other audit features.
|
||||
*/
|
||||
public interface CurrentUserProvider {
|
||||
|
||||
/**
|
||||
* Return the current user id.
|
||||
* <p>
|
||||
* The type returned should match the type of the properties annotated
|
||||
* with @WhoCreated and @WhoModified. These are typically String, Long or UUID.
|
||||
* </p>
|
||||
*/
|
||||
Object currentUser();
|
||||
}
|
||||
@@ -26,4 +26,22 @@ public abstract class JsonConfig {
|
||||
ISO8601
|
||||
}
|
||||
|
||||
|
||||
public enum Include {
|
||||
|
||||
/**
|
||||
* Include all values including null and empty collections.
|
||||
*/
|
||||
ALL,
|
||||
|
||||
/**
|
||||
* Exclude null values (include empty collections).
|
||||
*/
|
||||
NON_NULL,
|
||||
|
||||
/**
|
||||
* Exclude null values and empty collections.
|
||||
*/
|
||||
NON_EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,12 @@ public class ServerConfig {
|
||||
*/
|
||||
private String classPathReaderClassName;
|
||||
|
||||
/**
|
||||
* This is used to populate @WhoCreated, @WhoModified and
|
||||
* support other audit features (who executed a query etc).
|
||||
*/
|
||||
private CurrentUserProvider currentUserProvider;
|
||||
|
||||
/**
|
||||
* Config controlling the autofetch behaviour.
|
||||
*/
|
||||
@@ -123,6 +129,12 @@ public class ServerConfig {
|
||||
*/
|
||||
private JsonConfig.DateTime jsonDateTime = JsonConfig.DateTime.MILLIS;
|
||||
|
||||
/**
|
||||
* For writing JSON specify if null values or empty collections should be exluded.
|
||||
* By default all values are included.
|
||||
*/
|
||||
private JsonConfig.Include jsonInclude = JsonConfig.Include.ALL;
|
||||
|
||||
/**
|
||||
* The database platform name. Used to imply a DatabasePlatform to use.
|
||||
*/
|
||||
@@ -138,6 +150,18 @@ public class ServerConfig {
|
||||
*/
|
||||
private int databaseSequenceBatchSize = 20;
|
||||
|
||||
/**
|
||||
* Suffix appended to the base table to derive the view that contains the union
|
||||
* of the base table and the history table in order to support asOf queries.
|
||||
*/
|
||||
private String asOfViewSuffix = "_with_history";
|
||||
|
||||
/**
|
||||
* Column used to support history and 'As of' queries. This column is a timestamp range
|
||||
* or equivalent.
|
||||
*/
|
||||
private String asOfSysPeriod = "sys_period";
|
||||
|
||||
/**
|
||||
* Use for transaction scoped batch mode.
|
||||
*/
|
||||
@@ -219,7 +243,12 @@ public class ServerConfig {
|
||||
* Behaviour of update to include on the change properties.
|
||||
*/
|
||||
private boolean updateChangesOnly = true;
|
||||
|
||||
|
||||
/**
|
||||
* Behaviour of updates in JDBC batch to by default include all properties.
|
||||
*/
|
||||
private boolean updateAllPropertiesInBatch = true;
|
||||
|
||||
/**
|
||||
* Default behaviour for updates when cascade save on a O2M or M2M to delete any missing children.
|
||||
*/
|
||||
@@ -231,6 +260,7 @@ public class ServerConfig {
|
||||
private boolean uuidStoreAsBinary;
|
||||
|
||||
|
||||
private List<BeanFindController> findControllers = new ArrayList<BeanFindController>();
|
||||
private List<BeanPersistController> persistControllers = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPersistListener> persistListeners = new ArrayList<BeanPersistListener>();
|
||||
private List<BeanQueryAdapter> queryAdapters = new ArrayList<BeanQueryAdapter>();
|
||||
@@ -291,6 +321,8 @@ public class ServerConfig {
|
||||
private int queryCacheMaxSize = 1000;
|
||||
private int queryCacheMaxIdleTime = 600;
|
||||
private int queryCacheMaxTimeToLive = 60*60*6;
|
||||
private Object objectMapper;
|
||||
private boolean diffFlatMode;
|
||||
|
||||
/**
|
||||
* Construct a Server Configuration for programmatically creating an EbeanServer.
|
||||
@@ -302,7 +334,7 @@ public class ServerConfig {
|
||||
/**
|
||||
* Return the Jackson JsonFactory to use.
|
||||
* <p>
|
||||
* If not set a default implmentation will be used.
|
||||
* If not set a default implementation will be used.
|
||||
*/
|
||||
public JsonFactory getJsonFactory() {
|
||||
return jsonFactory;
|
||||
@@ -311,7 +343,7 @@ public class ServerConfig {
|
||||
/**
|
||||
* Set the Jackson JsonFactory to use.
|
||||
* <p>
|
||||
* If not set a default implmentation will be used.
|
||||
* If not set a default implementation will be used.
|
||||
*/
|
||||
public void setJsonFactory(JsonFactory jsonFactory) {
|
||||
this.jsonFactory = jsonFactory;
|
||||
@@ -331,6 +363,23 @@ public class ServerConfig {
|
||||
this.jsonDateTime = jsonDateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JSON include mode used when writing JSON.
|
||||
*/
|
||||
public JsonConfig.Include getJsonInclude() {
|
||||
return jsonInclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JSON include mode used when writing JSON.
|
||||
* <p>
|
||||
* Set to NON_NULL or NON_EMPTY to suppress nulls or null & empty collections respectively.
|
||||
* </p>
|
||||
*/
|
||||
public void setJsonInclude(JsonConfig.Include jsonInclude) {
|
||||
this.jsonInclude = jsonInclude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the EbeanServer.
|
||||
*/
|
||||
@@ -409,6 +458,22 @@ public class ServerConfig {
|
||||
this.defaultServer = defaultServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CurrentUserProvider. This is used to populate @WhoCreated, @WhoModified and
|
||||
* support other audit features (who executed a query etc).
|
||||
*/
|
||||
public CurrentUserProvider getCurrentUserProvider() {
|
||||
return currentUserProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CurrentUserProvider. This is used to populate @WhoCreated, @WhoModified and
|
||||
* support other audit features (who executed a query etc).
|
||||
*/
|
||||
public void setCurrentUserProvider(CurrentUserProvider currentUserProvider) {
|
||||
this.currentUserProvider = currentUserProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PersistBatch mode to use by default at the transaction level.
|
||||
* <p>
|
||||
@@ -554,6 +619,38 @@ public class ServerConfig {
|
||||
this.databaseSequenceBatchSize = databaseSequenceBatchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the suffix appended to the base table to derive the view that contains the union
|
||||
* of the base table and the history table in order to support asOf queries.
|
||||
*/
|
||||
public String getAsOfViewSuffix() {
|
||||
return asOfViewSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the suffix appended to the base table to derive the view that contains the union
|
||||
* of the base table and the history table in order to support asOf queries.
|
||||
*/
|
||||
public void setAsOfViewSuffix(String asOfViewSuffix) {
|
||||
this.asOfViewSuffix = asOfViewSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database column used to support history and 'As of' queries. This column is a timestamp range
|
||||
* or equivalent.
|
||||
*/
|
||||
public String getAsOfSysPeriod() {
|
||||
return asOfSysPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the database column used to support history and 'As of' queries. This column is a timestamp range
|
||||
* or equivalent.
|
||||
*/
|
||||
public void setAsOfSysPeriod(String asOfSysPeriod) {
|
||||
this.asOfSysPeriod = asOfSysPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we are running in a JTA Transaction manager.
|
||||
*/
|
||||
@@ -1424,7 +1521,26 @@ public class ServerConfig {
|
||||
public void setUpdateChangesOnly(boolean updateChangesOnly) {
|
||||
this.updateChangesOnly = updateChangesOnly;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if updates in JDBC batch default to include all properties by default.
|
||||
*/
|
||||
public boolean isUpdateAllPropertiesInBatch() {
|
||||
return updateAllPropertiesInBatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to false if by default updates in JDBC batch should not include all properties.
|
||||
* <p>
|
||||
* This mode can be explicitly set per transaction.
|
||||
* </p>
|
||||
*
|
||||
* @see com.avaje.ebean.Transaction#setUpdateAllLoadedProperties(boolean)
|
||||
*/
|
||||
public void setUpdateAllPropertiesInBatch(boolean updateAllPropertiesInBatch) {
|
||||
this.updateAllPropertiesInBatch = updateAllPropertiesInBatch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if updates by default delete missing children when cascading save to a OneToMany or
|
||||
* ManyToMany. When not set this defaults to true.
|
||||
@@ -1539,6 +1655,14 @@ public class ServerConfig {
|
||||
persistControllers.add(beanPersistController);
|
||||
}
|
||||
|
||||
public List<BeanFindController> getFindControllers() {
|
||||
return findControllers;
|
||||
}
|
||||
|
||||
public void setFindControllers(List<BeanFindController> findControllers) {
|
||||
this.findControllers = findControllers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BeanPersistController instances.
|
||||
*/
|
||||
@@ -1735,6 +1859,7 @@ public class ServerConfig {
|
||||
autoCommitMode = p.getBoolean("autoCommitMode", autoCommitMode);
|
||||
useJtaTransactionManager = p.getBoolean("useJtaTransactionManager", useJtaTransactionManager);
|
||||
|
||||
currentUserProvider = createInstance(p, CurrentUserProvider.class, "currentUserProvider");
|
||||
disableClasspathSearch = p.getBoolean("disableClasspathSearch", disableClasspathSearch);
|
||||
databasePlatform = createInstance(p, DatabasePlatform.class, "databasePlatform");
|
||||
encryptKeyManager = createInstance(p, EncryptKeyManager.class, "encryptKeyManager");
|
||||
@@ -1759,6 +1884,7 @@ public class ServerConfig {
|
||||
collectQueryStatsByNode = p.getBoolean("collectQueryStatsByNode", collectQueryStatsByNode);
|
||||
collectQueryOrigins = p.getBoolean("collectQueryOrigins", collectQueryOrigins);
|
||||
|
||||
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
|
||||
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
|
||||
|
||||
boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren);
|
||||
@@ -1774,8 +1900,11 @@ public class ServerConfig {
|
||||
int batchSize = p.getInt("batch.size", persistBatchSize);
|
||||
persistBatchSize = p.getInt("persistBatchSize", batchSize);
|
||||
|
||||
persistenceContextScope = PersistenceContextScope.valueOf(p.get("persistenceContextScope","TRANSACTION"));
|
||||
persistenceContextScope = PersistenceContextScope.valueOf(p.get("persistenceContextScope", "TRANSACTION"));
|
||||
|
||||
diffFlatMode = p.getBoolean("diffFlatMode", diffFlatMode);
|
||||
asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
|
||||
asOfSysPeriod = p.get("asOfSysPeriod", asOfSysPeriod);
|
||||
dataSourceJndiName = p.get("dataSourceJndiName", dataSourceJndiName);
|
||||
databaseSequenceBatchSize = p.getInt("databaseSequenceBatchSize", databaseSequenceBatchSize);
|
||||
databaseBooleanTrue = p.get("databaseBooleanTrue", databaseBooleanTrue);
|
||||
@@ -1787,6 +1916,7 @@ public class ServerConfig {
|
||||
lazyLoadBatchSize = p.getInt("lazyLoadBatchSize", lazyLoadBatchSize);
|
||||
queryBatchSize = p.getInt("queryBatchSize", queryBatchSize);
|
||||
|
||||
jsonInclude = p.getEnum(JsonConfig.Include.class, "jsonInclude", jsonInclude);
|
||||
String jsonDateTimeFormat = p.get("jsonDateTime", null);
|
||||
if (jsonDateTimeFormat != null) {
|
||||
jsonDateTime = JsonConfig.DateTime.valueOf(jsonDateTimeFormat);
|
||||
@@ -1818,8 +1948,7 @@ public class ServerConfig {
|
||||
|
||||
String classNames = properties.get("classes", null);
|
||||
if (classNames == null) {
|
||||
|
||||
return null;
|
||||
return classes;
|
||||
}
|
||||
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
@@ -1864,4 +1993,40 @@ public class ServerConfig {
|
||||
|
||||
return databasePlatform.isDisallowBatchOnCascade() ? PersistBatch.NONE : persistBatchOnCascade;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Jackson ObjectMapper.
|
||||
* <p>
|
||||
* Note that this is not strongly typed as Jackson ObjectMapper is an optional dependency.
|
||||
* </p>
|
||||
*/
|
||||
public Object getObjectMapper() {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Jackson ObjectMapper.
|
||||
* <p>
|
||||
* Note that this is not strongly typed as Jackson ObjectMapper is an optional dependency.
|
||||
* </p>
|
||||
*/
|
||||
public void setObjectMapper(Object objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if diff should return flat properties with dot notation rather than
|
||||
* embedded beans or reference beans (when the associated bean id is different).
|
||||
*/
|
||||
public boolean isDiffFlatMode() {
|
||||
return diffFlatMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true if diff should return flat properties with dot notation rather than
|
||||
* embedded beans or reference beans (when the associated bean id is different).
|
||||
*/
|
||||
public void setDiffFlatMode(boolean diffFlatMode) {
|
||||
this.diffFlatMode = diffFlatMode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,12 @@ public class DatabasePlatform {
|
||||
COMMIT
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to true for MySql, no other jdbc drivers need this workaround.
|
||||
*/
|
||||
protected boolean useExtraTransactionOnIterateSecondaryQueries;
|
||||
|
||||
/**
|
||||
* The behaviour used when ending a read only transaction at read committed isolation level.
|
||||
*/
|
||||
@@ -74,6 +80,11 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected DbIdentity dbIdentity = new DbIdentity();
|
||||
|
||||
/**
|
||||
* The history support for this database platform.
|
||||
*/
|
||||
protected DbHistorySupport historySupport;
|
||||
|
||||
/**
|
||||
* The JDBC type to map booleans to (by default).
|
||||
*/
|
||||
@@ -153,6 +164,17 @@ public class DatabasePlatform {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the JDBC driver does not allow additional queries to execute
|
||||
* when a resultSet is being 'streamed' as is the case with findEach() etc.
|
||||
* <p>
|
||||
* Honestly, this is a workaround for a stupid MySql JDBC driver limitation.
|
||||
* </p>
|
||||
*/
|
||||
public boolean useExtraTransactionOnIterateSecondaryQueries() {
|
||||
return useExtraTransactionOnIterateSecondaryQueries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a DB Sequence based IdGenerator.
|
||||
*
|
||||
@@ -198,6 +220,20 @@ public class DatabasePlatform {
|
||||
this.dbEncrypt = dbEncrypt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the history support for this database platform.
|
||||
*/
|
||||
public DbHistorySupport getHistorySupport() {
|
||||
return historySupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the history support for this database platform.
|
||||
*/
|
||||
public void setHistorySupport(DbHistorySupport historySupport) {
|
||||
this.historySupport = historySupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mapping of JDBC to DB types.
|
||||
*
|
||||
|
||||
@@ -7,6 +7,9 @@ public class Db2SqlLimiter implements SqlLimiter {
|
||||
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("select ");
|
||||
if (request.isDistinct()) {
|
||||
sb.append("distinct ");
|
||||
}
|
||||
sb.append(request.getDbSql());
|
||||
|
||||
int maxRows = request.getMaxRows();
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* History support for the database platform.
|
||||
*/
|
||||
public interface DbHistorySupport {
|
||||
|
||||
/**
|
||||
* Return the 'as of' predicate added for the given table alias.
|
||||
*
|
||||
* @param tableAlias The table alias this predicate is added for
|
||||
* @param sysPeriod The name of the 'sys_period' column used for effective date time range.
|
||||
* @return The predicate containing a single ? bind parameter which will be bound to the 'as at' timestamp value
|
||||
*/
|
||||
String getAsOfPredicate(String tableAlias, String sysPeriod);
|
||||
|
||||
/**
|
||||
* Return the column for the system period lower bound that will be included in findVersions() queries.
|
||||
*
|
||||
* @param tableAlias the table alias which will typically be 't0'
|
||||
* @param sysPeriod the name of the sys_period column
|
||||
*/
|
||||
String getSysPeriodLower(String tableAlias, String sysPeriod);
|
||||
|
||||
/**
|
||||
* Return the column for the system period upper bound that will be included in findVersions() queries.
|
||||
*
|
||||
* @param tableAlias the table alias which will typically be 't0'
|
||||
* @param sysPeriod the name of the sys_period column
|
||||
*/
|
||||
String getSysPeriodUpper(String tableAlias, String sysPeriod);
|
||||
|
||||
}
|
||||
@@ -8,6 +8,36 @@ package com.avaje.ebean.config.dbplatform;
|
||||
*/
|
||||
public class DbType {
|
||||
|
||||
/**
|
||||
* Type to map Map content to Postgres HSTORE.
|
||||
*/
|
||||
public static final int HSTORE = 5000;
|
||||
|
||||
/**
|
||||
* Type to map JSON content to Clob or Postgres JSON type.
|
||||
*/
|
||||
public static final int JSON = 5001;
|
||||
|
||||
/**
|
||||
* Type to map JSON content to Clob or Postgres JSONB type.
|
||||
*/
|
||||
public static final int JSONB = 5002;
|
||||
|
||||
/**
|
||||
* Type to map JSON content to VARCHAR.
|
||||
*/
|
||||
public static final int JSONVarchar = 5003;
|
||||
|
||||
/**
|
||||
* Type to map JSON content to Clob.
|
||||
*/
|
||||
public static final int JSONClob = 5004;
|
||||
|
||||
/**
|
||||
* Type to map JSON content to Blob.
|
||||
*/
|
||||
public static final int JSONBlob = 5005;
|
||||
|
||||
/**
|
||||
* The data type name (VARCHAR, INTEGER ...)
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,13 @@ public class DbTypeMap {
|
||||
|
||||
put(Types.BLOB, new DbType("blob"));
|
||||
put(Types.CLOB, new DbType("clob"));
|
||||
|
||||
put(DbType.JSON, new DbType("clob")); // Postgres maps this to JSON
|
||||
put(DbType.JSONB, new DbType("clob")); // Postgres maps this to JSONB
|
||||
put(DbType.JSONClob, new DbType("clob"));
|
||||
put(DbType.JSONBlob, new DbType("blob"));
|
||||
put(DbType.JSONVarchar, new DbType("varchar", 1000));
|
||||
|
||||
put(Types.LONGVARBINARY, new DbType("longvarbinary"));
|
||||
put(Types.LONGVARCHAR, new DbType("lonvarchar"));
|
||||
put(Types.VARBINARY, new DbType("varbinary", 255));
|
||||
|
||||
@@ -20,6 +20,7 @@ public class MySqlPlatform extends DatabasePlatform {
|
||||
public MySqlPlatform() {
|
||||
super();
|
||||
this.name = "mysql";
|
||||
this.useExtraTransactionOnIterateSecondaryQueries = true;
|
||||
this.likeClause = "like ? escape''";
|
||||
this.selectCountWithAlias = true;
|
||||
this.dbEncrypt = new MySqlDbEncrypt();
|
||||
|
||||
@@ -21,6 +21,7 @@ public class Postgres8Platform extends DatabasePlatform {
|
||||
this.clobDbType = Types.VARCHAR;
|
||||
|
||||
this.dbEncrypt = new PostgresDbEncrypt();
|
||||
this.historySupport = new PostgresHistorySupport();
|
||||
|
||||
this.dbIdentity.setSupportsGetGeneratedKeys(false);
|
||||
this.dbIdentity.setIdType(IdType.SEQUENCE);
|
||||
@@ -47,15 +48,13 @@ public class Postgres8Platform extends DatabasePlatform {
|
||||
|
||||
dbDdlSyntax.setDropTableCascade("cascade");
|
||||
dbDdlSyntax.setDropIfExists("if exists");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Postgres specific sequence IdGenerator.
|
||||
*/
|
||||
@Override
|
||||
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds,
|
||||
String seqName, int batchSize) {
|
||||
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
|
||||
return new PostgresSequenceIdGenerator(be, ds, seqName, batchSize);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.avaje.ebean.config.dbplatform;
|
||||
|
||||
/**
|
||||
* Postgres support for history features.
|
||||
*/
|
||||
public class PostgresHistorySupport implements DbHistorySupport {
|
||||
|
||||
/**
|
||||
* Build and return the 'as of' predicate for a given table alias.
|
||||
* <p>
|
||||
* Each @History entity involved in the query has this predicate added using the related table alias.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public String getAsOfPredicate(String asOfTableAlias, String asOfSysPeriod) {
|
||||
|
||||
// for Postgres we are using the 'timestamp with timezone range' data type
|
||||
// as our sys_period column so hence the predicate below
|
||||
StringBuilder sb = new StringBuilder(40);
|
||||
sb.append(asOfTableAlias).append(".").append(asOfSysPeriod).append(" @> ?::timestamptz");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSysPeriodLower(String tableAlias, String sysPeriod) {
|
||||
return "lower("+tableAlias+"."+sysPeriod+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSysPeriodUpper(String tableAlias, String sysPeriod) {
|
||||
return "upper("+tableAlias+"."+sysPeriod+")";
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,6 @@ import java.sql.Types;
|
||||
*/
|
||||
public class PostgresPlatform extends DatabasePlatform {
|
||||
|
||||
/**
|
||||
* Unique jdbc type id defined for hstore type.
|
||||
*/
|
||||
public static final int TYPE_HSTORE = 4001;
|
||||
|
||||
public PostgresPlatform() {
|
||||
super();
|
||||
this.name = "postgres";
|
||||
@@ -32,6 +27,7 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
this.clobDbType = Types.VARCHAR;
|
||||
|
||||
this.dbEncrypt = new PostgresDbEncrypt();
|
||||
this.historySupport = new PostgresHistorySupport();
|
||||
|
||||
// Use Identity and getGeneratedKeys
|
||||
this.dbIdentity.setIdType(IdType.IDENTITY);
|
||||
@@ -43,8 +39,10 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
this.openQuote = "\"";
|
||||
this.closeQuote = "\"";
|
||||
|
||||
dbTypeMap.put(TYPE_HSTORE, new DbType("hstore"));
|
||||
|
||||
dbTypeMap.put(DbType.HSTORE, new DbType("hstore"));
|
||||
dbTypeMap.put(DbType.JSON, new DbType("json"));
|
||||
dbTypeMap.put(DbType.JSONB, new DbType("jsonb"));
|
||||
|
||||
dbTypeMap.put(Types.INTEGER, new DbType("integer", false));
|
||||
dbTypeMap.put(Types.DOUBLE, new DbType("float"));
|
||||
dbTypeMap.put(Types.TINYINT, new DbType("smallint"));
|
||||
@@ -60,15 +58,14 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
|
||||
dbDdlSyntax.setDropTableCascade("cascade");
|
||||
dbDdlSyntax.setDropIfExists("if exists");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a Postgres specific sequence IdGenerator.
|
||||
*/
|
||||
@Override
|
||||
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds,
|
||||
String seqName, int batchSize) {
|
||||
public IdGenerator createSequenceIdGenerator(BackgroundExecutor be, DataSource ds, String seqName, int batchSize) {
|
||||
|
||||
return new PostgresSequenceIdGenerator(be, ds, seqName, batchSize);
|
||||
}
|
||||
|
||||
+23
-3
@@ -15,12 +15,32 @@ import com.avaje.ebean.bean.BeanCollection;
|
||||
* com.avaje.ebean.meta and finders in com.avaje.ebean.server.meta.
|
||||
* </p>
|
||||
*/
|
||||
public interface BeanFinder<T> {
|
||||
public interface BeanFindController {
|
||||
|
||||
/**
|
||||
* Return true if this BeanPersistController should be registered for events
|
||||
* on this entity type.
|
||||
*/
|
||||
boolean isRegisterFor(Class<?> cls);
|
||||
|
||||
/**
|
||||
* Return true if this controller should intercept and process this find request.
|
||||
*
|
||||
* Return false to allow the default behavior to process the request.
|
||||
*/
|
||||
boolean isInterceptFind(BeanQueryRequest<?> request);
|
||||
|
||||
/**
|
||||
* Find a bean using its id or unique predicate.
|
||||
*/
|
||||
T find(BeanQueryRequest<T> request);
|
||||
<T> T find(BeanQueryRequest<T> request);
|
||||
|
||||
/**
|
||||
* Return true if this controller should intercept and process this findMany request.
|
||||
*
|
||||
* Return false to allow the default behavior to process the request.
|
||||
*/
|
||||
boolean isInterceptFindMany(BeanQueryRequest<?> request);
|
||||
|
||||
/**
|
||||
* Return a List, Set or Map for the given find request.
|
||||
@@ -29,6 +49,6 @@ public interface BeanFinder<T> {
|
||||
* get the return type right.
|
||||
* </p>
|
||||
*/
|
||||
BeanCollection<T> findMany(BeanQueryRequest<T> request);
|
||||
<T> BeanCollection<T> findMany(BeanQueryRequest<T> request);
|
||||
|
||||
}
|
||||
@@ -35,14 +35,29 @@ public class EJson {
|
||||
public static void write(Object object, JsonGenerator jsonGenerator) throws IOException {
|
||||
EJsonWriter.write(object, jsonGenerator);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the json and return as a Map additionally specifying if the returned map should
|
||||
* be modify aware meaning that it can detect when it has been modified.
|
||||
*/
|
||||
public static Map<String,Object> parseObject(String json, boolean modifyAware) throws IOException {
|
||||
return EJsonReader.parseObject(json, modifyAware);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the json and return as a Map.
|
||||
*/
|
||||
public static Map<String,Object> parseObject(String json) throws IOException {
|
||||
return EJsonReader.parseObject(json);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the json and return as a Map taking a reader.
|
||||
*/
|
||||
public static Map<String,Object> parseObject(Reader reader, boolean modifyAware) throws IOException {
|
||||
return EJsonReader.parseObject(reader, modifyAware);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the json and return as a Map taking a reader.
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,10 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import com.avaje.ebeaninternal.server.type.ModifyAwareFlag;
|
||||
import com.avaje.ebeaninternal.server.type.ModifyAwareList;
|
||||
import com.avaje.ebeaninternal.server.type.ModifyAwareMap;
|
||||
import com.avaje.ebeaninternal.server.type.ModifyAwareOwner;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
@@ -16,7 +20,12 @@ import com.fasterxml.jackson.core.JsonToken;
|
||||
class EJsonReader {
|
||||
|
||||
static JsonFactory json = new JsonFactory();
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> parseObject(String json, boolean modifyAware) throws IOException {
|
||||
return (Map<String, Object>) parse(json, modifyAware);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> parseObject(String json) throws IOException {
|
||||
return (Map<String, Object>) parse(json);
|
||||
@@ -26,7 +35,12 @@ class EJsonReader {
|
||||
static Map<String, Object> parseObject(Reader reader) throws IOException {
|
||||
return (Map<String, Object>) parse(reader);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> parseObject(Reader reader, boolean modifyAware) throws IOException {
|
||||
return (Map<String, Object>) parse(reader, modifyAware);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> parseObject(JsonParser parser) throws IOException {
|
||||
return (Map<String, Object>) parse(parser);
|
||||
@@ -34,7 +48,7 @@ class EJsonReader {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static Map<String, Object> parseObject(JsonParser parser, JsonToken token) throws IOException {
|
||||
return (Map<String, Object>)parse(parser, token);
|
||||
return (Map<String, Object>)parse(parser, token, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -56,40 +70,58 @@ class EJsonReader {
|
||||
return parse(new StringReader(json));
|
||||
}
|
||||
|
||||
static Object parse(String json, boolean modifyAware) throws IOException {
|
||||
return parse(new StringReader(json), modifyAware);
|
||||
}
|
||||
|
||||
static Object parse(Reader reader) throws IOException {
|
||||
return parse(json.createParser(reader));
|
||||
}
|
||||
|
||||
static Object parse(JsonParser parser) throws IOException {
|
||||
return parse(parser, null);
|
||||
static Object parse(Reader reader, boolean modifyAware) throws IOException {
|
||||
return parse(json.createParser(reader), modifyAware);
|
||||
}
|
||||
|
||||
static Object parse(JsonParser parser, JsonToken token) throws IOException {
|
||||
return new EJsonReader(parser).parseJson(token);
|
||||
static Object parse(JsonParser parser) throws IOException {
|
||||
return parse(parser, null, false);
|
||||
}
|
||||
|
||||
static Object parse(JsonParser parser, boolean modifyAware) throws IOException {
|
||||
return parse(parser, null, modifyAware);
|
||||
}
|
||||
|
||||
static Object parse(JsonParser parser, JsonToken token, boolean modifyAware) throws IOException {
|
||||
return new EJsonReader(parser, modifyAware).parseJson(token);
|
||||
}
|
||||
|
||||
private final JsonParser parser;
|
||||
|
||||
private final boolean modifyAware;
|
||||
|
||||
private final ModifyAwareFlag modifyAwareOwner;
|
||||
|
||||
private int depth;
|
||||
|
||||
private Stack stack;
|
||||
|
||||
private Context currentContext;
|
||||
|
||||
EJsonReader(JsonParser parser) {
|
||||
EJsonReader(JsonParser parser, boolean modifyAware) {
|
||||
this.parser = parser;
|
||||
this.modifyAware = modifyAware;
|
||||
this.modifyAwareOwner = (modifyAware) ? new ModifyAwareFlag() : null;
|
||||
}
|
||||
|
||||
private void startArray() {
|
||||
depth++;
|
||||
stack.push(currentContext);
|
||||
currentContext = new ArrayContext();
|
||||
currentContext = modifyAware ? new ArrayContext(modifyAwareOwner) : new ArrayContext();
|
||||
}
|
||||
|
||||
private void startObject() {
|
||||
depth++;
|
||||
stack.push(currentContext);
|
||||
currentContext = new ObjectContext();
|
||||
currentContext = modifyAware ? new ObjectContext(modifyAwareOwner) : new ObjectContext();
|
||||
}
|
||||
|
||||
private void endArray() {
|
||||
@@ -105,6 +137,9 @@ class EJsonReader {
|
||||
if (!stack.isEmpty()) {
|
||||
currentContext = stack.pop(currentContext);
|
||||
}
|
||||
if (modifyAwareOwner != null) {
|
||||
modifyAwareOwner.resetMarkedDirty();
|
||||
}
|
||||
}
|
||||
|
||||
private void setValue(Object value) {
|
||||
@@ -235,10 +270,18 @@ class EJsonReader {
|
||||
|
||||
private static class ObjectContext extends Context {
|
||||
|
||||
private final Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
private final Map<String, Object> map;
|
||||
|
||||
private String key;
|
||||
|
||||
ObjectContext() {
|
||||
map = new LinkedHashMap<String, Object>();
|
||||
}
|
||||
|
||||
ObjectContext(ModifyAwareOwner owner) {
|
||||
map = new ModifyAwareMap<String, Object>(owner, new LinkedHashMap<String, Object>());
|
||||
}
|
||||
|
||||
public void popContext(Context temp) {
|
||||
setValue(temp.getValue());
|
||||
}
|
||||
@@ -262,7 +305,15 @@ class EJsonReader {
|
||||
|
||||
private static class ArrayContext extends Context {
|
||||
|
||||
private final List<Object> values = new ArrayList<Object>();
|
||||
private final List<Object> values;
|
||||
|
||||
ArrayContext() {
|
||||
values = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
ArrayContext(ModifyAwareOwner owner) {
|
||||
values = new ModifyAwareList<Object>(owner, new ArrayList<Object>());
|
||||
}
|
||||
|
||||
public void popContext(Context temp) {
|
||||
values.add(temp.getValue());
|
||||
|
||||
@@ -21,6 +21,13 @@ public interface JsonContext {
|
||||
*/
|
||||
<T> T toBean(Class<T> rootType, String json) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json string input into a Bean of a specific type additionally using JsonReadOptions.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> T toBean(Class<T> rootType, String json, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json reader input into a Bean of a specific type.
|
||||
*
|
||||
@@ -28,6 +35,13 @@ public interface JsonContext {
|
||||
*/
|
||||
<T> T toBean(Class<T> rootType, Reader json) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json reader input into a Bean of a specific type additionally using JsonReadOptions.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> T toBean(Class<T> rootType, Reader json, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json parser input into a Bean of a specific type.
|
||||
*
|
||||
@@ -35,6 +49,13 @@ public interface JsonContext {
|
||||
*/
|
||||
<T> T toBean(Class<T> cls, JsonParser parser) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json parser input into a Bean of a specific type additionally using JsonReadOptions..
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> T toBean(Class<T> cls, JsonParser parser, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json string input into a list of beans of a specific type.
|
||||
*
|
||||
@@ -42,6 +63,13 @@ public interface JsonContext {
|
||||
*/
|
||||
<T> List<T> toList(Class<T> rootType, String json) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json string input into a list of beans of a specific type additionally using JsonReadOptions.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> List<T> toList(Class<T> rootType, String json, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json reader input into a list of beans of a specific type.
|
||||
*
|
||||
@@ -49,12 +77,26 @@ public interface JsonContext {
|
||||
*/
|
||||
<T> List<T> toList(Class<T> rootType, Reader json) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json reader input into a list of beans of a specific type additionally using JsonReadOptions.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> List<T> toList(Class<T> rootType, Reader json, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json parser input into a list of beans of a specific type.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> List<T> toList(Class<T> cls, JsonParser src) throws JsonIOException;
|
||||
<T> List<T> toList(Class<T> cls, JsonParser json) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Convert json parser input into a list of beans of a specific type additionally using JsonReadOptions.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
*/
|
||||
<T> List<T> toList(Class<T> cls, JsonParser json, JsonReadOptions options) throws JsonIOException;
|
||||
|
||||
/**
|
||||
* Use the genericType to determine if this should be converted into a List or
|
||||
@@ -121,8 +163,6 @@ public interface JsonContext {
|
||||
/**
|
||||
* Deprecated in favour of using PathProperties by itself.
|
||||
* Write json to the JsonGenerator using the JsonWriteOptions.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
void toJson(Object value, JsonGenerator generator, JsonWriteOptions options) throws JsonIOException;
|
||||
|
||||
@@ -131,7 +171,6 @@ public interface JsonContext {
|
||||
* With additional options.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
* @deprecated
|
||||
*/
|
||||
void toJson(Object value, Writer writer, JsonWriteOptions options) throws JsonIOException;
|
||||
|
||||
@@ -140,7 +179,6 @@ public interface JsonContext {
|
||||
* Convert a bean or collection to json string.
|
||||
*
|
||||
* @throws JsonIOException When IOException occurs
|
||||
* @deprecated
|
||||
*/
|
||||
String toJson(Object value, JsonWriteOptions options) throws JsonIOException;
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides for custom handling of json content as it is read.
|
||||
* <p>
|
||||
* This visit method is called after all the known properties of the bean have
|
||||
* been processed. Any JSON elements that could not be mapped to known bean
|
||||
* properties are available in the unmapped Map.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> The type of entity bean
|
||||
*/
|
||||
public interface JsonReadBeanVisitor<T> {
|
||||
|
||||
/**
|
||||
* Visit the bean that has just been processed.
|
||||
* <p>
|
||||
* This provides a method of customising the bean and processing any custom
|
||||
* JSON content.
|
||||
* </p>
|
||||
*
|
||||
* @param bean the bean being processed
|
||||
* @param unmapped Map of any JSON elements that didn't map to known bean properties
|
||||
*/
|
||||
void visit(T bean, Map<String, Object> unmapped);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Provides the ability to customise the reading of JSON content.
|
||||
* <p>
|
||||
* You can register JsonReadBeanVisitors to customise the processing of the
|
||||
* beans as they are processed and handle any custom JSON elements that
|
||||
* could not be mapped to bean properties.
|
||||
* </p>
|
||||
*/
|
||||
public class JsonReadOptions {
|
||||
|
||||
protected Map<String, JsonReadBeanVisitor<?>> visitorMap;
|
||||
|
||||
protected Object objectMapper;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public JsonReadOptions() {
|
||||
this.visitorMap = new LinkedHashMap<String, JsonReadBeanVisitor<?>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the map of JsonReadBeanVisitor's.
|
||||
*/
|
||||
public Map<String, JsonReadBeanVisitor<?>> getVisitorMap() {
|
||||
return visitorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonReadBeanVisitor for the root level.
|
||||
*/
|
||||
public JsonReadOptions addRootVisitor(JsonReadBeanVisitor<?> visitor) {
|
||||
return addVisitor(null, visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JsonReadBeanVisitor for a given path.
|
||||
*/
|
||||
public JsonReadOptions addVisitor(String path, JsonReadBeanVisitor<?> visitor) {
|
||||
visitorMap.put(path, visitor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the ServerConfig).
|
||||
*/
|
||||
public Object getObjectMapper() {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Jackson ObjectMapper to use (if not wanted to use the objectMapper set on the ServerConfig).
|
||||
*/
|
||||
public void setObjectMapper(Object objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
package com.avaje.ebean.text.json;
|
||||
|
||||
import com.avaje.ebean.config.JsonConfig;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
|
||||
/**
|
||||
* Deprecated in favour of just using PathProperties.
|
||||
*
|
||||
* Provides options for customising the JSON write process.
|
||||
* <p>
|
||||
* You can explicitly state which properties to include in the JSON output for
|
||||
* the root level and each path.
|
||||
* </p>
|
||||
* @deprecated
|
||||
*/
|
||||
public class JsonWriteOptions {
|
||||
|
||||
protected PathProperties pathProperties;
|
||||
|
||||
protected Object objectMapper;
|
||||
|
||||
protected JsonConfig.Include include;
|
||||
|
||||
/**
|
||||
* Parse and return a PathProperties from nested string format like
|
||||
* (a,b,c(d,e),f(g)) where "c" is a path containing "d" and "e" and "f" is a
|
||||
@@ -51,4 +53,35 @@ public class JsonWriteOptions {
|
||||
return pathProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the include mode for this request.
|
||||
*/
|
||||
public JsonConfig.Include getInclude() {
|
||||
return include;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the include mode for this request.
|
||||
*/
|
||||
public void setInclude(JsonConfig.Include include) {
|
||||
this.include = include;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the jackson object mapper to use.
|
||||
* <p/>
|
||||
* If null the ObjectMapper from serverConfig will be used.
|
||||
*/
|
||||
public Object getObjectMapper() {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the jackson object mapper to use.
|
||||
* <p/>
|
||||
* If null the ObjectMapper from serverConfig will be used.
|
||||
*/
|
||||
public void setObjectMapper(Object objectMapper) {
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,88 +6,108 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Helper to find classes taking into account the context class loader.
|
||||
*
|
||||
* @author rbygrave
|
||||
*/
|
||||
public class ClassUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClassUtil.class);
|
||||
|
||||
private static boolean preferContext = true;
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClassUtil.class);
|
||||
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
public static Class<?> forName(String name) throws ClassNotFoundException {
|
||||
return forName(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
public static Class<?> forName(String name, Class<?> caller) throws ClassNotFoundException {
|
||||
|
||||
if (caller == null){
|
||||
caller = ClassUtil.class;
|
||||
}
|
||||
ClassLoadContext ctx = ClassLoadContext.of(caller, preferContext);
|
||||
|
||||
return ctx.forName(name);
|
||||
}
|
||||
|
||||
private static boolean preferContext = true;
|
||||
|
||||
public static ClassLoader getClassLoader(Class<?> caller, boolean preferContext) {
|
||||
|
||||
if (caller == null){
|
||||
caller = ClassUtil.class;
|
||||
}
|
||||
ClassLoadContext ctx = ClassLoadContext.of(caller, preferContext);
|
||||
ClassLoader classLoader = ctx.getDefault(preferContext);
|
||||
if (ctx.isAmbiguous()){
|
||||
logger.info("Ambigous ClassLoader (Context vs Caller) chosen "+classLoader);
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
public static Class<?> forName(String name) throws ClassNotFoundException {
|
||||
return forName(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className) {
|
||||
return isPresent(className, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className, Class<?> caller) {
|
||||
try {
|
||||
forName(className, caller);
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
// Class or one of its dependencies is not present...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Load a class taking into account a context class loader (if present).
|
||||
*/
|
||||
public static Class<?> forName(String name, Class<?> caller) throws ClassNotFoundException {
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className) {
|
||||
return newInstance(className,null);
|
||||
if (caller == null) {
|
||||
caller = ClassUtil.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className, Class<?> caller) {
|
||||
|
||||
try {
|
||||
Class<?> cls = forName(className, caller);
|
||||
return cls.newInstance();
|
||||
} catch (Exception e){
|
||||
String msg = "Error constructing "+className;
|
||||
throw new IllegalArgumentException(msg, e);
|
||||
}
|
||||
ClassLoadContext ctx = ClassLoadContext.of(caller, preferContext);
|
||||
|
||||
return ctx.forName(name);
|
||||
}
|
||||
|
||||
|
||||
public static ClassLoader getClassLoader(Class<?> caller, boolean preferContext) {
|
||||
|
||||
if (caller == null) {
|
||||
caller = ClassUtil.class;
|
||||
}
|
||||
ClassLoadContext ctx = ClassLoadContext.of(caller, preferContext);
|
||||
ClassLoader classLoader = ctx.getDefault(preferContext);
|
||||
if (ctx.isAmbiguous()) {
|
||||
logger.info("Ambigous ClassLoader (Context vs Caller) chosen " + classLoader);
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if javax validation annotations like Size and NotNull are present.
|
||||
*/
|
||||
public static boolean isJavaxValidationAnnotationsPresent() {
|
||||
return isPresent("javax.validation.constraints.NotNull", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson annotations like JsonIgnore are present.
|
||||
*/
|
||||
public static boolean isJacksonAnnotationsPresent() {
|
||||
return isPresent("com.fasterxml.jackson.annotation.JsonIgnore", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if Jackson ObjectMapper is present.
|
||||
*/
|
||||
public static boolean isJacksonObjectMapperPresent() {
|
||||
return isPresent("com.fasterxml.jackson.databind.ObjectMapper", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className) {
|
||||
return isPresent(className, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given class is present.
|
||||
*/
|
||||
public static boolean isPresent(String className, Class<?> caller) {
|
||||
try {
|
||||
forName(className, caller);
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
// Class or one of its dependencies is not present...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className) {
|
||||
return newInstance(className, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new instance of the class using the default constructor.
|
||||
*/
|
||||
public static Object newInstance(String className, Class<?> caller) {
|
||||
|
||||
try {
|
||||
Class<?> cls = forName(className, caller);
|
||||
return cls.newInstance();
|
||||
} catch (Exception e) {
|
||||
String msg = "Error constructing " + className;
|
||||
throw new IllegalArgumentException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,16 @@ import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
*/
|
||||
public interface LoadBeanBuffer {
|
||||
|
||||
public int getBatchSize();
|
||||
int getBatchSize();
|
||||
|
||||
public List<EntityBeanIntercept> getBatch();
|
||||
List<EntityBeanIntercept> getBatch();
|
||||
|
||||
public BeanDescriptor<?> getBeanDescriptor();
|
||||
BeanDescriptor<?> getBeanDescriptor();
|
||||
|
||||
public PersistenceContext getPersistenceContext();
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
public String getFullPath();
|
||||
String getFullPath();
|
||||
|
||||
public void configureQuery(SpiQuery<?> query, String lazyLoadProperty);
|
||||
void configureQuery(SpiQuery<?> query, String lazyLoadProperty);
|
||||
|
||||
}
|
||||
@@ -14,13 +14,13 @@ public interface LoadContext {
|
||||
/**
|
||||
* Return the minimum batch size when using QueryIterator with query joins.
|
||||
*/
|
||||
public int getSecondaryQueriesMinBatchSize(OrmQueryRequest<?> parentRequest, int defaultQueryBatch);
|
||||
int getSecondaryQueriesMinBatchSize(OrmQueryRequest<?> parentRequest, int defaultQueryBatch);
|
||||
|
||||
/**
|
||||
* Execute any secondary (+query) queries if there are any defined.
|
||||
* @param parentRequest the originating query request
|
||||
*/
|
||||
public void executeSecondaryQueries(OrmQueryRequest<?> parentRequest);
|
||||
void executeSecondaryQueries(OrmQueryRequest<?> parentRequest);
|
||||
|
||||
/**
|
||||
* Register any secondary queries (+query or +lazy) with their
|
||||
@@ -30,17 +30,17 @@ public interface LoadContext {
|
||||
* defined query for +query and +lazy execution.
|
||||
* </p>
|
||||
*/
|
||||
public void registerSecondaryQueries(SpiQuery<?> query);
|
||||
void registerSecondaryQueries(SpiQuery<?> query);
|
||||
|
||||
/**
|
||||
* Return the node for a given path which is used by autofetch profiling.
|
||||
*/
|
||||
public ObjectGraphNode getObjectGraphNode(String path);
|
||||
ObjectGraphNode getObjectGraphNode(String path);
|
||||
|
||||
/**
|
||||
* Return the persistence context used by this query and future lazy loading.
|
||||
*/
|
||||
public PersistenceContext getPersistenceContext();
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
/**
|
||||
* Set the persistence context used by this query and future lazy loading.
|
||||
@@ -48,16 +48,16 @@ public interface LoadContext {
|
||||
* Used by query iterator when processing large result sets.
|
||||
* </p>
|
||||
*/
|
||||
public void resetPersistenceContext(PersistenceContext persistenceContext);
|
||||
void resetPersistenceContext(PersistenceContext persistenceContext);
|
||||
|
||||
/**
|
||||
* Register a Bean for lazy loading.
|
||||
*/
|
||||
public void register(String path, EntityBeanIntercept ebi);
|
||||
void register(String path, EntityBeanIntercept ebi);
|
||||
|
||||
/**
|
||||
* Register a collection for lazy loading.
|
||||
*/
|
||||
public void register(String path, BeanCollection<?> bc);
|
||||
void register(String path, BeanCollection<?> bc);
|
||||
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssocMany;
|
||||
*/
|
||||
public interface LoadManyBuffer {
|
||||
|
||||
public int getBatchSize();
|
||||
int getBatchSize();
|
||||
|
||||
public List<BeanCollection<?>> getBatch();
|
||||
List<BeanCollection<?>> getBatch();
|
||||
|
||||
public BeanPropertyAssocMany<?> getBeanProperty();
|
||||
BeanPropertyAssocMany<?> getBeanProperty();
|
||||
|
||||
public ObjectGraphNode getObjectGraphNode();
|
||||
ObjectGraphNode getObjectGraphNode();
|
||||
|
||||
public BeanDescriptor<?> getBeanDescriptor();
|
||||
BeanDescriptor<?> getBeanDescriptor();
|
||||
|
||||
public PersistenceContext getPersistenceContext();
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
public String getFullPath();
|
||||
String getFullPath();
|
||||
|
||||
public void configureQuery(SpiQuery<?> query);
|
||||
void configureQuery(SpiQuery<?> query);
|
||||
|
||||
}
|
||||
@@ -48,4 +48,11 @@ public abstract class LoadRequest {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the parent query is a findIterate() type query.
|
||||
* So one of - findIterate(), findEach(), findEachWhile() or findVisit().
|
||||
*/
|
||||
public boolean isParentFindIterate() {
|
||||
return parentRequest != null && parentRequest.getQuery().getType() == SpiQuery.Type.ITERATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,5 +14,5 @@ public interface LoadSecondaryQuery {
|
||||
/**
|
||||
* Execute the secondary query with a given batch size.
|
||||
*/
|
||||
public void loadSecondaryQuery(OrmQueryRequest<?> parentRequest);
|
||||
void loadSecondaryQuery(OrmQueryRequest<?> parentRequest);
|
||||
}
|
||||
|
||||
@@ -152,6 +152,16 @@ public class ScopedTransaction implements SpiTransaction {
|
||||
transaction.setPersistCascade(persistCascade);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateAllLoadedProperties(boolean updateAllLoaded) {
|
||||
transaction.setUpdateAllLoadedProperties(updateAllLoaded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isUpdateAllLoadedProperties() {
|
||||
return transaction.isUpdateAllLoadedProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBatchMode(boolean useBatch) {
|
||||
transaction.setBatchMode(useBatch);
|
||||
|
||||
@@ -10,5 +10,5 @@ public interface SpiBackgroundExecutor extends BackgroundExecutor {
|
||||
/**
|
||||
* Shutdown any associated thread pools.
|
||||
*/
|
||||
public void shutdown();
|
||||
void shutdown();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.avaje.ebean.CallableSql;
|
||||
|
||||
public interface SpiCallableSql extends CallableSql {
|
||||
|
||||
public BindParams getBindParams();
|
||||
BindParams getBindParams();
|
||||
|
||||
public TransactionEventTable getTransactionEventTable();
|
||||
TransactionEventTable getTransactionEventTable();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.avaje.ebean.config.dbplatform.DatabasePlatform;
|
||||
* author: Richard Vowles - http://gplus.to/RichardVowles
|
||||
*/
|
||||
public interface SpiEbeanPlugin {
|
||||
|
||||
/**
|
||||
* initializes the plugin.
|
||||
*
|
||||
@@ -16,7 +17,10 @@ public interface SpiEbeanPlugin {
|
||||
* @param dbPlatform - the database we are using - this is available from the server, but it is provided for convenience
|
||||
* @param serverConfig - the configured server information. It allows access to pre-collected information (but not the collector PropertySource, yet)
|
||||
*/
|
||||
public void setup(SpiEbeanServer server, DatabasePlatform dbPlatform, ServerConfig serverConfig);
|
||||
void setup(SpiEbeanServer server, DatabasePlatform dbPlatform, ServerConfig serverConfig);
|
||||
|
||||
public void execute(boolean online);
|
||||
/**
|
||||
* Execute the plugin (generate DDL for example).
|
||||
*/
|
||||
void execute(boolean online);
|
||||
}
|
||||
|
||||
@@ -26,22 +26,27 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
/**
|
||||
* For internal use, shutdown of the server invoked by JVM Shutdown.
|
||||
*/
|
||||
public void shutdownManaged();
|
||||
void shutdownManaged();
|
||||
|
||||
/**
|
||||
* Return true if query origins should be collected.
|
||||
*/
|
||||
public boolean isCollectQueryOrigins();
|
||||
|
||||
boolean isCollectQueryOrigins();
|
||||
|
||||
/**
|
||||
* Return true if updates in JDBC batch should include all columns if unspecified on the transaction.
|
||||
*/
|
||||
boolean isUpdateAllPropertiesInBatch();
|
||||
|
||||
/**
|
||||
* Return the server configuration.
|
||||
*/
|
||||
public ServerConfig getServerConfig();
|
||||
ServerConfig getServerConfig();
|
||||
|
||||
/**
|
||||
* Return the DatabasePlatform for this server.
|
||||
*/
|
||||
public DatabasePlatform getDatabasePlatform();
|
||||
DatabasePlatform getDatabasePlatform();
|
||||
|
||||
/**
|
||||
* Return a JDBC driver specific handler for batching.
|
||||
@@ -49,7 +54,7 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
* Required for Oracle specific batch handling.
|
||||
* </p>
|
||||
*/
|
||||
public PstmtBatch getPstmtBatch();
|
||||
PstmtBatch getPstmtBatch();
|
||||
|
||||
/**
|
||||
* Create an object to represent the current CallStack.
|
||||
@@ -58,47 +63,47 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
* graph costing.
|
||||
* </p>
|
||||
*/
|
||||
public CallStack createCallStack();
|
||||
CallStack createCallStack();
|
||||
|
||||
/**
|
||||
* Return the PersistenceContextScope to use defined at query or server level.
|
||||
*/
|
||||
public PersistenceContextScope getPersistenceContextScope(SpiQuery<?> query);
|
||||
PersistenceContextScope getPersistenceContextScope(SpiQuery<?> query);
|
||||
|
||||
/**
|
||||
* Return the DDL generator.
|
||||
*/
|
||||
public DdlGenerator getDdlGenerator();
|
||||
DdlGenerator getDdlGenerator();
|
||||
|
||||
/**
|
||||
* Return the AutoFetchListener.
|
||||
*/
|
||||
public AutoFetchManager getAutoFetchManager();
|
||||
AutoFetchManager getAutoFetchManager();
|
||||
|
||||
/**
|
||||
* Clear the query execution statistics.
|
||||
*/
|
||||
public void clearQueryStatistics();
|
||||
void clearQueryStatistics();
|
||||
|
||||
/**
|
||||
* Return all the descriptors.
|
||||
*/
|
||||
public List<BeanDescriptor<?>> getBeanDescriptors();
|
||||
List<BeanDescriptor<?>> getBeanDescriptors();
|
||||
|
||||
/**
|
||||
* Return the BeanDescriptor for a given type of bean.
|
||||
*/
|
||||
public <T> BeanDescriptor<T> getBeanDescriptor(Class<T> type);
|
||||
<T> BeanDescriptor<T> getBeanDescriptor(Class<T> type);
|
||||
|
||||
/**
|
||||
* Return BeanDescriptor using it's unique id.
|
||||
*/
|
||||
public BeanDescriptor<?> getBeanDescriptorById(String descriptorId);
|
||||
BeanDescriptor<?> getBeanDescriptorById(String descriptorId);
|
||||
|
||||
/**
|
||||
* Return BeanDescriptors mapped to this table.
|
||||
*/
|
||||
public List<BeanDescriptor<?>> getBeanDescriptors(String tableName);
|
||||
List<BeanDescriptor<?>> getBeanDescriptors(String tableName);
|
||||
|
||||
/**
|
||||
* Process committed changes from another framework.
|
||||
@@ -108,7 +113,7 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
* this to maintain its cache and text indexes appropriately.
|
||||
* </p>
|
||||
*/
|
||||
public void externalModification(TransactionEventTable event);
|
||||
void externalModification(TransactionEventTable event);
|
||||
|
||||
/**
|
||||
* Create a ServerTransaction.
|
||||
@@ -116,44 +121,44 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
* To specify to use the default transaction isolation use a value of -1.
|
||||
* </p>
|
||||
*/
|
||||
public SpiTransaction createServerTransaction(boolean isExplicit, int isolationLevel);
|
||||
SpiTransaction createServerTransaction(boolean isExplicit, int isolationLevel);
|
||||
|
||||
/**
|
||||
* Return the current transaction or null if there is no current transaction.
|
||||
*/
|
||||
public SpiTransaction getCurrentServerTransaction();
|
||||
SpiTransaction getCurrentServerTransaction();
|
||||
|
||||
/**
|
||||
* Create a ScopeTrans for a method for the given scope definition.
|
||||
*/
|
||||
public ScopeTrans createScopeTrans(TxScope txScope);
|
||||
ScopeTrans createScopeTrans(TxScope txScope);
|
||||
|
||||
/**
|
||||
* Create a ServerTransaction for query purposes.
|
||||
*/
|
||||
public SpiTransaction createQueryTransaction();
|
||||
SpiTransaction createQueryTransaction();
|
||||
|
||||
/**
|
||||
* An event from another server in the cluster used to notify local
|
||||
* BeanListeners of remote inserts updates and deletes.
|
||||
*/
|
||||
public void remoteTransactionEvent(RemoteTransactionEvent event);
|
||||
void remoteTransactionEvent(RemoteTransactionEvent event);
|
||||
|
||||
/**
|
||||
* Create a query request object.
|
||||
*/
|
||||
public <T> SpiOrmQueryRequest<T> createQueryRequest(BeanDescriptor<T> desc, SpiQuery<T> q,
|
||||
<T> SpiOrmQueryRequest<T> createQueryRequest(BeanDescriptor<T> desc, SpiQuery<T> q,
|
||||
Transaction t);
|
||||
|
||||
/**
|
||||
* Compile a query.
|
||||
*/
|
||||
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t);
|
||||
<T> CQuery<T> compileQuery(Query<T> query, Transaction t);
|
||||
|
||||
/**
|
||||
* Return the queryEngine for this server.
|
||||
*/
|
||||
public CQueryEngine getQueryEngine();
|
||||
CQueryEngine getQueryEngine();
|
||||
|
||||
/**
|
||||
* Execute the findId's query but without copying the query.
|
||||
@@ -162,37 +167,37 @@ public interface SpiEbeanServer extends EbeanServer, BeanLoader, BeanCollectionL
|
||||
* the query has finished (if executing in a background thread).
|
||||
* </p>
|
||||
*/
|
||||
public <T> List<Object> findIdsWithCopy(Query<T> query, Transaction t);
|
||||
<T> List<Object> findIdsWithCopy(Query<T> query, Transaction t);
|
||||
|
||||
/**
|
||||
* Execute the findRowCount query but without copying the query.
|
||||
*/
|
||||
public <T> int findRowCountWithCopy(Query<T> query, Transaction t);
|
||||
<T> int findRowCountWithCopy(Query<T> query, Transaction t);
|
||||
|
||||
/**
|
||||
* Load a batch of Associated One Beans.
|
||||
*/
|
||||
public void loadBean(LoadBeanRequest loadRequest);
|
||||
void loadBean(LoadBeanRequest loadRequest);
|
||||
|
||||
/**
|
||||
* Lazy load a batch of Many's.
|
||||
*/
|
||||
public void loadMany(LoadManyRequest loadRequest);
|
||||
void loadMany(LoadManyRequest loadRequest);
|
||||
|
||||
/**
|
||||
* Return the default batch size for lazy loading.
|
||||
*/
|
||||
public int getLazyLoadBatchSize();
|
||||
int getLazyLoadBatchSize();
|
||||
|
||||
/**
|
||||
* Return true if the type is known as an Entity or Xml type or a List Set or
|
||||
* Map of known bean types.
|
||||
*/
|
||||
public boolean isSupportedType(java.lang.reflect.Type genericType);
|
||||
boolean isSupportedType(java.lang.reflect.Type genericType);
|
||||
|
||||
/**
|
||||
* Collect query statistics by ObjectGraphNode. Used for Lazy loading reporting.
|
||||
*/
|
||||
public void collectQueryStats(ObjectGraphNode objectGraphNode, long loadedBeanCount, long timeMicros);
|
||||
void collectQueryStats(ObjectGraphNode objectGraphNode, long loadedBeanCount, long timeMicros);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public interface SpiExpression extends Expression {
|
||||
* Predicates on Many properties require an extra independent join clause.
|
||||
* </p>
|
||||
*/
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins);
|
||||
void containsMany(BeanDescriptor<?> desc, ManyWhereJoins whereManyJoins);
|
||||
|
||||
/**
|
||||
* Calculate a hash value used to identify a query for AutoFetch tuning.
|
||||
@@ -25,7 +25,7 @@ public interface SpiExpression extends Expression {
|
||||
* from an AutoFetch perspective and get different tuning.
|
||||
* </p>
|
||||
*/
|
||||
public void queryAutoFetchHash(HashQueryPlanBuilder builder);
|
||||
void queryAutoFetchHash(HashQueryPlanBuilder builder);
|
||||
|
||||
/**
|
||||
* Calculate a hash value for the expression.
|
||||
@@ -36,12 +36,12 @@ public interface SpiExpression extends Expression {
|
||||
* case the query execution plan can be reused.
|
||||
* </p>
|
||||
*/
|
||||
public void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder);
|
||||
void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder);
|
||||
|
||||
/**
|
||||
* Return the hash value for the values that will be bound.
|
||||
*/
|
||||
public int queryBindHash();
|
||||
int queryBindHash();
|
||||
|
||||
/**
|
||||
* Add some sql to the query.
|
||||
@@ -56,7 +56,7 @@ public interface SpiExpression extends Expression {
|
||||
* @param request
|
||||
* the associated request.
|
||||
*/
|
||||
public void addSql(SpiExpressionRequest request);
|
||||
void addSql(SpiExpressionRequest request);
|
||||
|
||||
/**
|
||||
* Add the parameter values to be set against query. For each ? place holder
|
||||
@@ -65,5 +65,5 @@ public interface SpiExpression extends Expression {
|
||||
* @param request
|
||||
* the associated request.
|
||||
*/
|
||||
public void addBindValues(SpiExpressionRequest request);
|
||||
void addBindValues(SpiExpressionRequest request);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ public interface SpiExpressionFactory extends ExpressionFactory {
|
||||
/**
|
||||
* Create another expression factory with a given sub path.
|
||||
*/
|
||||
public ExpressionFactory createExpressionFactory();
|
||||
ExpressionFactory createExpressionFactory();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ public interface SpiExpressionList<T> extends ExpressionList<T> {
|
||||
/**
|
||||
* Return the underlying list of expressions.
|
||||
*/
|
||||
public List<SpiExpression> getUnderlyingList();
|
||||
List<SpiExpression> getUnderlyingList();
|
||||
|
||||
/**
|
||||
* Return a copy of the ExpressionList with the path trimmed for filterMany() expressions.
|
||||
*/
|
||||
public SpiExpressionList<?> trimPath(int prefixTrim);
|
||||
SpiExpressionList<?> trimPath(int prefixTrim);
|
||||
|
||||
/**
|
||||
* Restore the ExpressionFactory after deserialisation.
|
||||
*/
|
||||
public void setExpressionFactory(ExpressionFactory expr);
|
||||
void setExpressionFactory(ExpressionFactory expr);
|
||||
|
||||
/**
|
||||
* Process "Many" properties populating ManyWhereJoins.
|
||||
@@ -34,12 +34,12 @@ public interface SpiExpressionList<T> extends ExpressionList<T> {
|
||||
* Predicates on Many properties require an extra independent join clause.
|
||||
* </p>
|
||||
*/
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoins);
|
||||
void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoins);
|
||||
|
||||
/**
|
||||
* Return true if this list is empty.
|
||||
*/
|
||||
public boolean isEmpty();
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Concatenate the expression sql into a String.
|
||||
@@ -48,7 +48,7 @@ public interface SpiExpressionList<T> extends ExpressionList<T> {
|
||||
* with bind parameters.
|
||||
* </p>
|
||||
*/
|
||||
public String buildSql(SpiExpressionRequest request);
|
||||
String buildSql(SpiExpressionRequest request);
|
||||
|
||||
/**
|
||||
* Combine the expression bind values into a list.
|
||||
@@ -59,12 +59,12 @@ public interface SpiExpressionList<T> extends ExpressionList<T> {
|
||||
*
|
||||
* @return the list of all the bind values in order.
|
||||
*/
|
||||
public ArrayList<Object> buildBindValues(SpiExpressionRequest request);
|
||||
ArrayList<Object> buildBindValues(SpiExpressionRequest request);
|
||||
|
||||
/**
|
||||
* Calculate a hash based on the expressions but excluding the actual bind
|
||||
* values.
|
||||
*/
|
||||
public void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder);
|
||||
void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder);
|
||||
|
||||
}
|
||||
|
||||
@@ -13,45 +13,45 @@ public interface SpiExpressionRequest {
|
||||
/**
|
||||
* Parse the logical property name to the deployment name.
|
||||
*/
|
||||
public String parseDeploy(String logicalProp);
|
||||
String parseDeploy(String logicalProp);
|
||||
|
||||
/**
|
||||
* Return the bean descriptor for the root type.
|
||||
*/
|
||||
public BeanDescriptor<?> getBeanDescriptor();
|
||||
BeanDescriptor<?> getBeanDescriptor();
|
||||
|
||||
/**
|
||||
* Return the associated QueryRequest.
|
||||
*/
|
||||
public SpiOrmQueryRequest<?> getQueryRequest();
|
||||
SpiOrmQueryRequest<?> getQueryRequest();
|
||||
|
||||
/**
|
||||
* Append to the expression sql.
|
||||
*/
|
||||
public SpiExpressionRequest append(String sql);
|
||||
SpiExpressionRequest append(String sql);
|
||||
|
||||
/**
|
||||
* Add a bind value to this request.
|
||||
*/
|
||||
public void addBindValue(Object bindValue);
|
||||
void addBindValue(Object bindValue);
|
||||
|
||||
/**
|
||||
* Return the accumulated expression sql for all expressions in this request.
|
||||
*/
|
||||
public String getSql();
|
||||
String getSql();
|
||||
|
||||
/**
|
||||
* Return the ordered list of bind values for all expressions in this request.
|
||||
*/
|
||||
public ArrayList<Object> getBindValues();
|
||||
ArrayList<Object> getBindValues();
|
||||
|
||||
/**
|
||||
* Increments the parameter index and returns that value.
|
||||
*/
|
||||
public int nextParameter();
|
||||
int nextParameter();
|
||||
|
||||
/**
|
||||
* Append a DB Like clause.
|
||||
*/
|
||||
public void appendLike();
|
||||
void appendLike();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,68 +10,68 @@ import com.avaje.ebean.SqlQueryListener;
|
||||
*/
|
||||
public interface SpiSqlQuery extends SqlQuery {
|
||||
|
||||
/**
|
||||
* Return the named or positioned parameters.
|
||||
*/
|
||||
public BindParams getBindParams();
|
||||
/**
|
||||
* Return the named or positioned parameters.
|
||||
*/
|
||||
BindParams getBindParams();
|
||||
|
||||
/**
|
||||
* return the query.
|
||||
*/
|
||||
public String getQuery();
|
||||
/**
|
||||
* return the query.
|
||||
*/
|
||||
String getQuery();
|
||||
|
||||
/**
|
||||
* Return the queryListener.
|
||||
*/
|
||||
public SqlQueryListener getListener();
|
||||
|
||||
/**
|
||||
* Return the first row to fetch.
|
||||
*/
|
||||
public int getFirstRow();
|
||||
|
||||
/**
|
||||
* Return the maximum number of rows to fetch.
|
||||
*/
|
||||
public int getMaxRows();
|
||||
|
||||
/**
|
||||
* Return the number of rows after which background fetching occurs.
|
||||
*/
|
||||
public int getBackgroundFetchAfter();
|
||||
|
||||
/**
|
||||
* Return the key property for maps.
|
||||
*/
|
||||
public String getMapKey();
|
||||
|
||||
/**
|
||||
* Return the query timeout.
|
||||
*/
|
||||
public int getTimeout();
|
||||
/**
|
||||
* Return the queryListener.
|
||||
*/
|
||||
SqlQueryListener getListener();
|
||||
|
||||
/**
|
||||
* Return the hint for Statement.setFetchSize().
|
||||
*/
|
||||
public int getBufferFetchSizeHint();
|
||||
/**
|
||||
* Return the first row to fetch.
|
||||
*/
|
||||
int getFirstRow();
|
||||
|
||||
/**
|
||||
* Return true if this is a future fetch type query.
|
||||
*/
|
||||
public boolean isFutureFetch();
|
||||
/**
|
||||
* Return the maximum number of rows to fetch.
|
||||
*/
|
||||
int getMaxRows();
|
||||
|
||||
/**
|
||||
* Set to true if this is a future fetch type query.
|
||||
*/
|
||||
public void setFutureFetch(boolean futureFetch);
|
||||
/**
|
||||
* Return the number of rows after which background fetching occurs.
|
||||
*/
|
||||
int getBackgroundFetchAfter();
|
||||
|
||||
/**
|
||||
* Set the PreparedStatement for the purposes of supporting cancel.
|
||||
*/
|
||||
public void setPreparedStatement(PreparedStatement pstmt);
|
||||
|
||||
/**
|
||||
* Return true if the query has been cancelled.
|
||||
*/
|
||||
public boolean isCancelled();
|
||||
/**
|
||||
* Return the key property for maps.
|
||||
*/
|
||||
String getMapKey();
|
||||
|
||||
/**
|
||||
* Return the query timeout.
|
||||
*/
|
||||
int getTimeout();
|
||||
|
||||
/**
|
||||
* Return the hint for Statement.setFetchSize().
|
||||
*/
|
||||
int getBufferFetchSizeHint();
|
||||
|
||||
/**
|
||||
* Return true if this is a future fetch type query.
|
||||
*/
|
||||
boolean isFutureFetch();
|
||||
|
||||
/**
|
||||
* Set to true if this is a future fetch type query.
|
||||
*/
|
||||
void setFutureFetch(boolean futureFetch);
|
||||
|
||||
/**
|
||||
* Set the PreparedStatement for the purposes of supporting cancel.
|
||||
*/
|
||||
void setPreparedStatement(PreparedStatement pstmt);
|
||||
|
||||
/**
|
||||
* Return true if the query has been cancelled.
|
||||
*/
|
||||
boolean isCancelled();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.avaje.ebean.SqlUpdate;
|
||||
|
||||
public interface SpiSqlUpdate extends SqlUpdate {
|
||||
|
||||
public BindParams getBindParams();
|
||||
BindParams getBindParams();
|
||||
|
||||
public void setGeneratedSql(String sql);
|
||||
void setGeneratedSql(String sql);
|
||||
}
|
||||
|
||||
@@ -20,45 +20,45 @@ public interface SpiTransaction extends Transaction {
|
||||
/**
|
||||
* End the transaction when had query only use.
|
||||
*/
|
||||
public void endQueryOnly();
|
||||
void endQueryOnly();
|
||||
|
||||
/**
|
||||
* Return the string prefix with the transactin id and label used in logging.
|
||||
*/
|
||||
public String getLogPrefix();
|
||||
String getLogPrefix();
|
||||
|
||||
/**
|
||||
* Return true if generated SQL and Bind values should be logged to the
|
||||
* transaction log.
|
||||
*/
|
||||
public boolean isLogSql();
|
||||
boolean isLogSql();
|
||||
|
||||
/**
|
||||
* Return true if summary level events should be logged to the transaction
|
||||
* log.
|
||||
*/
|
||||
public boolean isLogSummary();
|
||||
boolean isLogSummary();
|
||||
|
||||
/**
|
||||
* Log a message to the SQL logger.
|
||||
*/
|
||||
public void logSql(String msg);
|
||||
void logSql(String msg);
|
||||
|
||||
/**
|
||||
* Log a message to the SUMMARY logger.
|
||||
*/
|
||||
public void logSummary(String msg);
|
||||
void logSummary(String msg);
|
||||
|
||||
/**
|
||||
* Register a "Derived Relationship" (that requires an additional update).
|
||||
*/
|
||||
public void registerDerivedRelationship(DerivedRelationshipData assocBean);
|
||||
void registerDerivedRelationship(DerivedRelationshipData assocBean);
|
||||
|
||||
/**
|
||||
* Return the list of "Derived Relationships" that must be maintained after
|
||||
* insert.
|
||||
*/
|
||||
public List<DerivedRelationshipData> getDerivedRelationship(Object bean);
|
||||
List<DerivedRelationshipData> getDerivedRelationship(Object bean);
|
||||
|
||||
/**
|
||||
* Add a deleting bean to the registered list.
|
||||
@@ -66,22 +66,22 @@ public interface SpiTransaction extends Transaction {
|
||||
* This is to handle bi-directional relationships where both sides Cascade.
|
||||
* </p>
|
||||
*/
|
||||
public void registerDeleteBean(Integer hash);
|
||||
void registerDeleteBean(Integer hash);
|
||||
|
||||
/**
|
||||
* Unregister the hash of the bean.
|
||||
*/
|
||||
public void unregisterDeleteBean(Integer hash);
|
||||
void unregisterDeleteBean(Integer hash);
|
||||
|
||||
/**
|
||||
* Return true if this is a bean that has already been saved/deleted.
|
||||
*/
|
||||
public boolean isRegisteredDeleteBean(Integer hash);
|
||||
boolean isRegisteredDeleteBean(Integer hash);
|
||||
|
||||
/**
|
||||
* Unregister the persisted bean.
|
||||
*/
|
||||
public void unregisterBean(Object bean);
|
||||
void unregisterBean(Object bean);
|
||||
|
||||
/**
|
||||
* Return true if this is a bean that has already been persisted in the
|
||||
@@ -91,13 +91,19 @@ public interface SpiTransaction extends Transaction {
|
||||
* This will register the bean if it is not already.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isRegisteredBean(Object bean);
|
||||
boolean isRegisteredBean(Object bean);
|
||||
|
||||
/**
|
||||
* Returns a String used to identify the transaction. This id is used for
|
||||
* Transaction logging.
|
||||
*/
|
||||
public String getId();
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Return true if this transaction has updateAllLoadedProperties set.
|
||||
* If null is returned the server default is used (set on ServerConfig).
|
||||
*/
|
||||
Boolean isUpdateAllLoadedProperties();
|
||||
|
||||
/**
|
||||
* Return the batchSize specifically set for this transaction or 0.
|
||||
@@ -105,7 +111,7 @@ public interface SpiTransaction extends Transaction {
|
||||
* Returning 0 implies to use the system wide default batch size.
|
||||
* </p>
|
||||
*/
|
||||
public int getBatchSize();
|
||||
int getBatchSize();
|
||||
|
||||
/**
|
||||
* Modify and return the current 'depth' of the transaction.
|
||||
@@ -119,18 +125,18 @@ public interface SpiTransaction extends Transaction {
|
||||
* executed first during save.
|
||||
* </p>
|
||||
*/
|
||||
public int depth(int diff);
|
||||
int depth(int diff);
|
||||
|
||||
/**
|
||||
* Return the current depth.
|
||||
*/
|
||||
public int depth();
|
||||
int depth();
|
||||
|
||||
/**
|
||||
* Return true if this transaction was created explicitly via
|
||||
* <code>Ebean.beginTransaction()</code>.
|
||||
*/
|
||||
public boolean isExplicit();
|
||||
boolean isExplicit();
|
||||
|
||||
/**
|
||||
* Get the object that holds the event details.
|
||||
@@ -140,29 +146,29 @@ public interface SpiTransaction extends Transaction {
|
||||
* around the cluster (if you have a cluster).
|
||||
* </p>
|
||||
*/
|
||||
public TransactionEvent getEvent();
|
||||
TransactionEvent getEvent();
|
||||
|
||||
/**
|
||||
* Whether persistCascade is on for save and delete.
|
||||
*/
|
||||
public boolean isPersistCascade();
|
||||
boolean isPersistCascade();
|
||||
|
||||
/**
|
||||
* Return true if this request should be batched. Conversely returns false
|
||||
* if this request should be executed immediately.
|
||||
*/
|
||||
public boolean isBatchThisRequest(PersistRequest.Type type);
|
||||
boolean isBatchThisRequest(PersistRequest.Type type);
|
||||
|
||||
/**
|
||||
* Return the queue used to batch up persist requests.
|
||||
*/
|
||||
public BatchControl getBatchControl();
|
||||
BatchControl getBatchControl();
|
||||
|
||||
/**
|
||||
* Set the queue used to batch up persist requests. There should only be one
|
||||
* PersistQueue set per transaction.
|
||||
*/
|
||||
public void setBatchControl(BatchControl control);
|
||||
void setBatchControl(BatchControl control);
|
||||
|
||||
/**
|
||||
* Return the persistence context associated with this transaction.
|
||||
@@ -172,7 +178,7 @@ public interface SpiTransaction extends Transaction {
|
||||
* behaviour.
|
||||
* </p>
|
||||
*/
|
||||
public PersistenceContext getPersistenceContext();
|
||||
PersistenceContext getPersistenceContext();
|
||||
|
||||
/**
|
||||
* Set the persistence context to this transaction.
|
||||
@@ -185,47 +191,46 @@ public interface SpiTransaction extends Transaction {
|
||||
* PersistenceContext with multiple transactions.
|
||||
* </p>
|
||||
*/
|
||||
public void setPersistenceContext(PersistenceContext context);
|
||||
void setPersistenceContext(PersistenceContext context);
|
||||
|
||||
/**
|
||||
* Return the underlying Connection for internal use.
|
||||
* <p>
|
||||
* If the connection is made public from Transaction and the user code calls
|
||||
* If the connection is made from Transaction and the user code calls
|
||||
* that method we can no longer trust the query only status of a
|
||||
* Transaction.
|
||||
* </p>
|
||||
*/
|
||||
public Connection getInternalConnection();
|
||||
Connection getInternalConnection();
|
||||
|
||||
/**
|
||||
* Return true if the manyToMany intersection should be persisted for this particular relationship direction.
|
||||
*/
|
||||
public boolean isSaveAssocManyIntersection(String intersectionTable, String beanName);
|
||||
boolean isSaveAssocManyIntersection(String intersectionTable, String beanName);
|
||||
|
||||
/**
|
||||
* Return true if batch mode got escalated for this request (and associated cascades).
|
||||
*/
|
||||
public boolean checkBatchEscalationOnCascade(PersistRequestBean<?> request);
|
||||
boolean checkBatchEscalationOnCascade(PersistRequestBean<?> request);
|
||||
|
||||
/**
|
||||
* If batch mode was turned on for the request then flush the batch.
|
||||
*/
|
||||
public void flushBatchOnCascade();
|
||||
void flushBatchOnCascade();
|
||||
|
||||
/**
|
||||
* Mark the transaction explicitly as not being query only.
|
||||
*/
|
||||
public void markNotQueryOnly();
|
||||
void markNotQueryOnly();
|
||||
|
||||
/**
|
||||
* Potentially escalate batch mode on saving or deleting a collection.
|
||||
*/
|
||||
public void checkBatchEscalationOnCollection();
|
||||
void checkBatchEscalationOnCollection();
|
||||
|
||||
/**
|
||||
* Flush batch if we escalated batch mode on saving or deleting a collection.
|
||||
*/
|
||||
public void flushBatchOnCollection();
|
||||
|
||||
void flushBatchOnCollection();
|
||||
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ package com.avaje.ebeaninternal.api;
|
||||
|
||||
public interface SpiTransactionScopeManager {
|
||||
|
||||
public void replace(SpiTransaction t);
|
||||
void replace(SpiTransaction t);
|
||||
}
|
||||
|
||||
@@ -11,66 +11,66 @@ public interface SpiUpdate<T> extends Update<T> {
|
||||
* The type of the update request.
|
||||
*/
|
||||
enum OrmUpdateType {
|
||||
INSERT{
|
||||
INSERT {
|
||||
public String toString() {
|
||||
return "Insert";
|
||||
}
|
||||
},
|
||||
UPDATE{
|
||||
UPDATE {
|
||||
public String toString() {
|
||||
return "Update";
|
||||
}
|
||||
},
|
||||
DELETE{
|
||||
},
|
||||
DELETE {
|
||||
public String toString() {
|
||||
return "Delete";
|
||||
}
|
||||
},
|
||||
UNKNOWN{
|
||||
UNKNOWN {
|
||||
public String toString() {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of bean being updated.
|
||||
*/
|
||||
public Class<?> getBeanType();
|
||||
Class<?> getBeanType();
|
||||
|
||||
/**
|
||||
* Return the type of this - insert, update or delete.
|
||||
*/
|
||||
public OrmUpdateType getOrmUpdateType();
|
||||
OrmUpdateType getOrmUpdateType();
|
||||
|
||||
/**
|
||||
* Return the name of the table being modified.
|
||||
*/
|
||||
public String getBaseTable();
|
||||
String getBaseTable();
|
||||
|
||||
/**
|
||||
* Return the update statement. This could be either sql or an orm update with bean types and property names.
|
||||
*/
|
||||
public String getUpdateStatement();
|
||||
String getUpdateStatement();
|
||||
|
||||
/**
|
||||
* Return the timeout in seconds.
|
||||
*/
|
||||
public int getTimeout();
|
||||
int getTimeout();
|
||||
|
||||
/**
|
||||
* Return true if the cache should be notified to invalidate objects.
|
||||
*/
|
||||
public boolean isNotifyCache();
|
||||
boolean isNotifyCache();
|
||||
|
||||
/**
|
||||
* Return the bind parameters.
|
||||
*/
|
||||
public BindParams getBindParams();
|
||||
BindParams getBindParams();
|
||||
|
||||
/**
|
||||
* Set the generated sql used.
|
||||
*/
|
||||
public void setGeneratedSql(String sql);
|
||||
void setGeneratedSql(String sql);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import com.avaje.ebeaninternal.server.persist.dmlbind.Bindable;
|
||||
* <p>
|
||||
* The plans are cached by the BeanDescriptors.
|
||||
* </>
|
||||
*
|
||||
* @author rbygrave
|
||||
*/
|
||||
public interface SpiUpdatePlan {
|
||||
|
||||
@@ -28,48 +26,42 @@ public interface SpiUpdatePlan {
|
||||
* deployment.
|
||||
* </p>
|
||||
*/
|
||||
public boolean isEmptySetClause();
|
||||
boolean isEmptySetClause();
|
||||
|
||||
/**
|
||||
* Bind given the request and bean. The bean could be the oldValues bean
|
||||
* when binding a update or delete where clause with ALL concurrency mode.
|
||||
*/
|
||||
public void bindSet(DmlHandler bind, EntityBean bean) throws SQLException;
|
||||
void bindSet(DmlHandler bind, EntityBean bean) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return the time this plan was created.
|
||||
*/
|
||||
public long getTimeCreated();
|
||||
long getTimeCreated();
|
||||
|
||||
/**
|
||||
* Return the time this plan was last used.
|
||||
*/
|
||||
public Long getTimeLastUsed();
|
||||
Long getTimeLastUsed();
|
||||
|
||||
/**
|
||||
* Return the hash key for this plan.
|
||||
*/
|
||||
public Integer getKey();
|
||||
Integer getKey();
|
||||
|
||||
/**
|
||||
* Return the concurrency mode for this plan.
|
||||
*/
|
||||
public ConcurrencyMode getMode();
|
||||
ConcurrencyMode getMode();
|
||||
|
||||
/**
|
||||
* Return the update SQL statement.
|
||||
*/
|
||||
public String getSql();
|
||||
String getSql();
|
||||
|
||||
/**
|
||||
* Return the set of bindable update properties.
|
||||
*/
|
||||
public Bindable getSet();
|
||||
|
||||
// /**
|
||||
// * Return the properties that where changed and should be included in the
|
||||
// * update statement.
|
||||
// */
|
||||
// public Set<String> getProperties();
|
||||
Bindable getSet();
|
||||
|
||||
}
|
||||
@@ -65,10 +65,10 @@ public class TransactionEvent implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* For BeanListeners the requests they are interested in.
|
||||
* Return the list of PersistRequestBean's for this transaction.
|
||||
*/
|
||||
public TransactionEventBeans getEventBeans() {
|
||||
return eventBeans;
|
||||
public List<PersistRequestBean<?>> getPersistRequestBeans() {
|
||||
return (eventBeans == null) ? null : eventBeans.getRequests();
|
||||
}
|
||||
|
||||
public TransactionEventTable getEventTables() {
|
||||
|
||||
+354
-341
@@ -1,22 +1,18 @@
|
||||
package com.avaje.ebeaninternal.server.cache;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.avaje.ebean.BackgroundExecutor;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.cache.ServerCache;
|
||||
import com.avaje.ebean.cache.ServerCacheOptions;
|
||||
import com.avaje.ebean.cache.ServerCacheStatistics;
|
||||
import com.avaje.ebeaninternal.server.util.LongAdder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* The default cache implementation.
|
||||
@@ -27,375 +23,392 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public class DefaultServerCache implements ServerCache {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DefaultServerCache.class);
|
||||
protected static final Logger logger = LoggerFactory.getLogger(DefaultServerCache.class);
|
||||
|
||||
private static final CacheEntryComparator comparator = new CacheEntryComparator();
|
||||
|
||||
private final ConcurrentHashMap<Object, CacheEntry> map = new ConcurrentHashMap<Object, CacheEntry>();
|
||||
|
||||
private final AtomicInteger missCount = new AtomicInteger();
|
||||
|
||||
private final AtomicInteger removedHitCount = new AtomicInteger();
|
||||
|
||||
private final Object monitor = new Object();
|
||||
|
||||
private final String name;
|
||||
|
||||
private int maxSize;
|
||||
|
||||
private long trimFrequency;
|
||||
|
||||
private int maxIdleSecs;
|
||||
|
||||
private int maxSecsToLive;
|
||||
|
||||
public DefaultServerCache(String name, ServerCacheOptions options) {
|
||||
this(name, options.getMaxSize(), options.getMaxIdleSecs(), options.getMaxSecsToLive());
|
||||
}
|
||||
|
||||
public DefaultServerCache(String name, int maxSize, int maxIdleSecs, int maxSecsToLive) {
|
||||
this.name = name;
|
||||
this.maxSize = maxSize;
|
||||
this.maxIdleSecs = maxIdleSecs;
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
this.trimFrequency = 60;
|
||||
|
||||
}
|
||||
|
||||
public void init(EbeanServer server) {
|
||||
|
||||
TrimTask trim = new TrimTask();
|
||||
|
||||
BackgroundExecutor executor = server.getBackgroundExecutor();
|
||||
executor.executePeriodically(trim, trimFrequency, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public ServerCacheStatistics getStatistics(boolean reset) {
|
||||
|
||||
ServerCacheStatistics s = new ServerCacheStatistics();
|
||||
s.setCacheName(name);
|
||||
s.setMaxSize(maxSize);
|
||||
|
||||
// these counters won't necessarily be consistent with
|
||||
// respect to each other as activity can occur while
|
||||
// they are being calculated
|
||||
int mc = reset ? missCount.getAndSet(0) : missCount.get();
|
||||
int hc = getHitCount(reset);
|
||||
int size = size();
|
||||
|
||||
s.setSize(size);
|
||||
s.setHitCount(hc);
|
||||
s.setMissCount(mc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public int getHitRatio() {
|
||||
|
||||
int mc = missCount.get();
|
||||
int hc = getHitCount(false);
|
||||
|
||||
int totalCount = hc + mc;
|
||||
if (totalCount == 0){
|
||||
return 0;
|
||||
} else {
|
||||
return hc * 100 / totalCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getHitCount(boolean reset) {
|
||||
|
||||
int hc = reset ? removedHitCount.getAndSet(0) : removedHitCount.get();
|
||||
|
||||
for (CacheEntry cacheEntry : map.values()) {
|
||||
hc += cacheEntry.getHitCount(reset);
|
||||
}
|
||||
|
||||
return hc;
|
||||
}
|
||||
/**
|
||||
* Compare by last access time (for LRU eviction).
|
||||
*/
|
||||
public static final CompareByLastAccess BY_LAST_ACCESS = new CompareByLastAccess();
|
||||
|
||||
|
||||
public ServerCacheOptions getOptions() {
|
||||
synchronized (monitor) {
|
||||
ServerCacheOptions o = new ServerCacheOptions();
|
||||
o.setMaxIdleSecs(maxIdleSecs);
|
||||
o.setMaxSize(maxSize);
|
||||
o.setMaxSecsToLive(maxSecsToLive);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOptions(ServerCacheOptions o) {
|
||||
synchronized (monitor) {
|
||||
maxIdleSecs = o.getMaxIdleSecs();
|
||||
maxSize = o.getMaxSize();
|
||||
maxSecsToLive = o.getMaxSecsToLive();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the max cache size.
|
||||
*/
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
/**
|
||||
* The underlying map (ConcurrentHashMap or similar)
|
||||
*/
|
||||
protected final Map<Object, CacheEntry> map;
|
||||
|
||||
/**
|
||||
* Set the max cache size.
|
||||
*/
|
||||
public void setMaxSize(int maxSize) {
|
||||
synchronized (monitor) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
}
|
||||
// LongAdder is a highly concurrent low latency counter (back ported from Java8)
|
||||
protected final LongAdder missCount = new LongAdder();
|
||||
protected final LongAdder hitCount = new LongAdder();
|
||||
protected final LongAdder insertCount = new LongAdder();
|
||||
protected final LongAdder updateCount = new LongAdder();
|
||||
protected final LongAdder removeCount = new LongAdder();
|
||||
protected final LongAdder clearCount = new LongAdder();
|
||||
|
||||
/**
|
||||
* Return the max idle time.
|
||||
*/
|
||||
public long getMaxIdleSecs() {
|
||||
return maxIdleSecs;
|
||||
}
|
||||
protected final LongAdder evictByIdle = new LongAdder();
|
||||
protected final LongAdder evictByTTL = new LongAdder();
|
||||
protected final LongAdder evictByLRU = new LongAdder();
|
||||
protected final LongAdder evictCount = new LongAdder();
|
||||
protected final LongAdder evictMicros = new LongAdder();
|
||||
|
||||
/**
|
||||
* Set the max idle time.
|
||||
*/
|
||||
public void setMaxIdleSecs(int maxIdleSecs) {
|
||||
synchronized (monitor) {
|
||||
this.maxIdleSecs = maxIdleSecs;
|
||||
}
|
||||
}
|
||||
protected final Object monitor = new Object();
|
||||
|
||||
/**
|
||||
* Return the maximum time to live.
|
||||
*/
|
||||
public long getMaxSecsToLive() {
|
||||
return maxSecsToLive;
|
||||
}
|
||||
protected final String name;
|
||||
|
||||
/**
|
||||
* Set the maximum time to live.
|
||||
*/
|
||||
public void setMaxSecsToLive(int maxSecsToLive) {
|
||||
synchronized (monitor) {
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the cache.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
protected int maxSize;
|
||||
|
||||
/**
|
||||
* Clear the cache.
|
||||
*/
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
protected int trimFrequency;
|
||||
|
||||
/**
|
||||
* Return a value from the cache.
|
||||
*/
|
||||
public Object get(Object key) {
|
||||
|
||||
CacheEntry entry = map.get(key);
|
||||
|
||||
if (entry == null){
|
||||
missCount.incrementAndGet();
|
||||
return null;
|
||||
|
||||
} else {
|
||||
// get value incrementing last
|
||||
// access time and hitCount
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
protected int maxIdleSecs;
|
||||
|
||||
/**
|
||||
* Put a value into the cache.
|
||||
*/
|
||||
public Object put(Object key, Object value) {
|
||||
// put new entry with create time
|
||||
CacheEntry entry = map.put(key, new CacheEntry(key, value));
|
||||
if (entry == null){
|
||||
return null;
|
||||
} else {
|
||||
int removedHits = entry.getHitCount(true);
|
||||
removedHitCount.addAndGet(removedHits);
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
protected int maxSecsToLive;
|
||||
|
||||
/**
|
||||
* Put a value into the cache but only if absent.
|
||||
*/
|
||||
public Object putIfAbsent(Object key, Object value) {
|
||||
CacheEntry entry = map.putIfAbsent(key, new CacheEntry(key, value));
|
||||
if (entry == null){
|
||||
return null;
|
||||
} else {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Construct using a ConcurrentHashMap and cache options.
|
||||
*/
|
||||
public DefaultServerCache(String name, ServerCacheOptions options) {
|
||||
this(name, new ConcurrentHashMap<Object, CacheEntry>(), options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an entry from the cache.
|
||||
*/
|
||||
public Object remove(Object key) {
|
||||
CacheEntry entry = map.remove(key);
|
||||
if (entry == null){
|
||||
return null;
|
||||
} else {
|
||||
int removedHits = entry.getHitCount(true);
|
||||
removedHitCount.addAndGet(removedHits);
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Construct passing in name, map and base eviction controls as ServerCacheOptions.
|
||||
*/
|
||||
public DefaultServerCache(String name, Map<Object, CacheEntry> map, ServerCacheOptions options) {
|
||||
this(name, map, options.getMaxSize(), options.getMaxIdleSecs(), options.getMaxSecsToLive(), options.getTrimFrequency());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of elements in the cache.
|
||||
*/
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
/**
|
||||
* Construct passing in name, map and base eviction controls.
|
||||
*/
|
||||
public DefaultServerCache(String name, Map<Object, CacheEntry> map, int maxSize, int maxIdleSecs, int maxSecsToLive, int trimFrequency) {
|
||||
this.name = name;
|
||||
this.map = map;
|
||||
this.maxSize = maxSize;
|
||||
this.maxIdleSecs = maxIdleSecs;
|
||||
this.maxSecsToLive = maxSecsToLive;
|
||||
this.trimFrequency = trimFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* The task used to periodically trim the cache.
|
||||
*/
|
||||
private class TrimTask implements Runnable {
|
||||
@Override
|
||||
public void init(EbeanServer server) {
|
||||
|
||||
public void run() {
|
||||
EvictionRunnable trim = new EvictionRunnable();
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
if (logger.isTraceEnabled()){
|
||||
logger.trace("trimming cache " + name);
|
||||
}
|
||||
|
||||
int trimmedByIdle = 0;
|
||||
int trimmedByTTL = 0;
|
||||
int trimmedByLRU = 0;
|
||||
// default to trimming the cache every 60 seconds
|
||||
long trimFreqSecs = (trimFrequency == 0) ? 60 : trimFrequency;
|
||||
|
||||
boolean trimMaxSize = maxSize > 0 && maxSize < size();
|
||||
BackgroundExecutor executor = server.getBackgroundExecutor();
|
||||
executor.executePeriodically(trim, trimFreqSecs, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
ArrayList<CacheEntry> activeList = new ArrayList<CacheEntry>();
|
||||
@Override
|
||||
public ServerCacheStatistics getStatistics(boolean reset) {
|
||||
|
||||
long idleExpire = System.currentTimeMillis() - (maxIdleSecs*1000);
|
||||
long ttlExpire = System.currentTimeMillis() - (maxSecsToLive*1000);
|
||||
ServerCacheStatistics cacheStats = new ServerCacheStatistics();
|
||||
cacheStats.setCacheName(name);
|
||||
cacheStats.setMaxSize(maxSize);
|
||||
|
||||
Iterator<CacheEntry> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
CacheEntry cacheEntry = it.next();
|
||||
if (maxIdleSecs > 0 && idleExpire > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
// these counters won't necessarily be consistent with
|
||||
// respect to each other as activity can occur while
|
||||
// they are being calculated here but they should be good enough
|
||||
// and we don't want to reduce concurrent use to make them consistent
|
||||
long clear = reset ? clearCount.sumThenReset() : clearCount.sum();
|
||||
long remove = reset ? removeCount.sumThenReset() : removeCount.sum();
|
||||
long update = reset ? updateCount.sumThenReset() : updateCount.sum();
|
||||
long insert = reset ? insertCount.sumThenReset() : insertCount.sum();
|
||||
long miss = reset ? missCount.sumThenReset() : missCount.sum();
|
||||
long hit = reset ? hitCount.sumThenReset() : hitCount.sum();
|
||||
|
||||
} else if (maxSecsToLive > 0 && ttlExpire > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
long evict = reset ? evictCount.sumThenReset() : evictCount.sum();
|
||||
long evictTime = reset ? evictMicros.sumThenReset() : evictMicros.sum();
|
||||
long evictIdle = reset ? evictByIdle.sumThenReset() : evictByIdle.sum();
|
||||
long evictTTL = reset ? evictByTTL.sumThenReset() : evictByTTL.sum();
|
||||
long evictLRU = reset ? evictByLRU.sumThenReset() : evictByLRU.sum();
|
||||
|
||||
} else if (trimMaxSize) {
|
||||
activeList.add(cacheEntry);
|
||||
}
|
||||
}
|
||||
int size = size();
|
||||
|
||||
if (trimMaxSize) {
|
||||
trimmedByLRU = activeList.size() - maxSize;
|
||||
cacheStats.setSize(size);
|
||||
cacheStats.setHitCount(hit);
|
||||
cacheStats.setMissCount(miss);
|
||||
cacheStats.setInsertCount(insert);
|
||||
cacheStats.setUpdateCount(update);
|
||||
cacheStats.setRemoveCount(remove);
|
||||
cacheStats.setClearCount(clear);
|
||||
|
||||
if (trimmedByLRU > 0) {
|
||||
// sort into last access time ascending
|
||||
Collections.sort(activeList, comparator);
|
||||
for (int i = maxSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
map.remove(activeList.get(i).getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long exeTime = System.currentTimeMillis() - startTime;
|
||||
|
||||
if (logger.isDebugEnabled()){
|
||||
logger.debug("Executed trim of cache " + name + " in ["+exeTime
|
||||
+"]millis idle[" + trimmedByIdle + "] timeToLive["
|
||||
+ trimmedByTTL + "] accessTime["
|
||||
+ trimmedByLRU + "]");
|
||||
}
|
||||
cacheStats.setEvictionRunCount(evict);
|
||||
cacheStats.setEvictionRunMicros(evictTime);
|
||||
cacheStats.setEvictByIdle(evictIdle);
|
||||
cacheStats.setEvictByTTL(evictTTL);
|
||||
cacheStats.setEvictByLRU(evictLRU);
|
||||
|
||||
}
|
||||
return cacheStats;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public int getHitRatio() {
|
||||
|
||||
/**
|
||||
* Comparator for sorting by last access time.
|
||||
*/
|
||||
private static class CacheEntryComparator implements Comparator<CacheEntry>, Serializable {
|
||||
long mc = missCount.sum();
|
||||
long hc = hitCount.sum();
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
long totalCount = hc + mc;
|
||||
if (totalCount == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return (int) (hc * 100 / totalCount);
|
||||
}
|
||||
}
|
||||
|
||||
public int compare(CacheEntry o1, CacheEntry o2) {
|
||||
|
||||
return o1.getLastAccessLong().compareTo(o2.getLastAccessLong());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the values to additionally hold createTime and lastAccessTime.
|
||||
*/
|
||||
public static class CacheEntry {
|
||||
/**
|
||||
* Return the options controlling the cache.
|
||||
*/
|
||||
@Override
|
||||
public ServerCacheOptions getOptions() {
|
||||
synchronized (monitor) {
|
||||
ServerCacheOptions options = new ServerCacheOptions();
|
||||
options.setMaxIdleSecs(maxIdleSecs);
|
||||
options.setMaxSize(maxSize);
|
||||
options.setMaxSecsToLive(maxSecsToLive);
|
||||
options.setTrimFrequency(trimFrequency);
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
private final Object key;
|
||||
private final Object value;
|
||||
private final long createTime;
|
||||
private final AtomicInteger hitCount = new AtomicInteger();
|
||||
private Long lastAccessTime;
|
||||
/**
|
||||
* Set the options controlling the cache
|
||||
*/
|
||||
@Override
|
||||
public void setOptions(ServerCacheOptions options) {
|
||||
synchronized (monitor) {
|
||||
maxIdleSecs = options.getMaxIdleSecs();
|
||||
maxSize = options.getMaxSize();
|
||||
maxSecsToLive = options.getMaxSecsToLive();
|
||||
}
|
||||
}
|
||||
|
||||
public CacheEntry(Object key, Object value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
this.lastAccessTime = Long.valueOf(createTime);
|
||||
}
|
||||
/**
|
||||
* Return the name of the cache.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
/**
|
||||
* Clear the cache.
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
clearCount.increment();
|
||||
map.clear();
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
// object assignment is atomic
|
||||
hitCount.incrementAndGet();
|
||||
this.lastAccessTime = Long.valueOf(System.currentTimeMillis());
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Return a value from the cache.
|
||||
*/
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
|
||||
public long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
CacheEntry entry = map.get(key);
|
||||
if (entry == null) {
|
||||
missCount.increment();
|
||||
return null;
|
||||
|
||||
public long getLastAccessTime() {
|
||||
return lastAccessTime.longValue();
|
||||
}
|
||||
} else {
|
||||
// Important that hitCount.increment() MUST be low latency under concurrent
|
||||
// use hence must use LongAdder or better here
|
||||
hitCount.increment();
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public Long getLastAccessLong() {
|
||||
return lastAccessTime;
|
||||
}
|
||||
/**
|
||||
* Put a value into the cache.
|
||||
*/
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
CacheEntry entry = map.put(key, new CacheEntry(key, value));
|
||||
if (entry == null) {
|
||||
insertCount.increment();
|
||||
return null;
|
||||
} else {
|
||||
updateCount.increment();
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
public int getHitCount(boolean reset) {
|
||||
if (reset){
|
||||
return hitCount.getAndSet(0);
|
||||
/**
|
||||
* Remove an entry from the cache.
|
||||
*/
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
CacheEntry entry = map.remove(key);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
} else {
|
||||
removeCount.increment();
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of elements in the cache.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size to trim to based on the max size.
|
||||
* <p>
|
||||
* This returns 90% of the max size.
|
||||
* </p>
|
||||
*/
|
||||
protected int getTrimSize() {
|
||||
return (maxSize * 90 / 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the eviction based on Idle time, Time to live and LRU last access.
|
||||
*/
|
||||
public void runEviction() {
|
||||
|
||||
long trimForMaxSize;
|
||||
if (maxSize == 0) {
|
||||
trimForMaxSize = 0;
|
||||
} else {
|
||||
trimForMaxSize = size() - maxSize;
|
||||
}
|
||||
|
||||
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
|
||||
// nothing to trim on this cache
|
||||
return;
|
||||
}
|
||||
|
||||
long startNanos = System.nanoTime();
|
||||
|
||||
long trimmedByIdle = 0;
|
||||
long trimmedByTTL = 0;
|
||||
long trimmedByLRU = 0;
|
||||
|
||||
ArrayList<CacheEntry> activeList = new ArrayList<CacheEntry>();
|
||||
|
||||
long idleExpire = System.currentTimeMillis() - (maxIdleSecs * 1000);
|
||||
long ttlExpire = System.currentTimeMillis() - (maxSecsToLive * 1000);
|
||||
|
||||
Iterator<CacheEntry> it = map.values().iterator();
|
||||
while (it.hasNext()) {
|
||||
CacheEntry cacheEntry = it.next();
|
||||
if (maxIdleSecs > 0 && idleExpire > cacheEntry.getLastAccessTime()) {
|
||||
it.remove();
|
||||
trimmedByIdle++;
|
||||
|
||||
} else if (maxSecsToLive > 0 && ttlExpire > cacheEntry.getCreateTime()) {
|
||||
it.remove();
|
||||
trimmedByTTL++;
|
||||
|
||||
} else if (trimForMaxSize > 0) {
|
||||
activeList.add(cacheEntry);
|
||||
}
|
||||
}
|
||||
|
||||
if (trimForMaxSize > 0) {
|
||||
trimmedByLRU = activeList.size() - maxSize;
|
||||
if (trimmedByLRU > 0) {
|
||||
// sort into last access time ascending
|
||||
Collections.sort(activeList, BY_LAST_ACCESS);
|
||||
int trimSize = getTrimSize();
|
||||
for (int i = trimSize; i < activeList.size(); i++) {
|
||||
// remove if still in the cache
|
||||
map.remove(activeList.get(i).getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long exeNanos = System.nanoTime() - startNanos;
|
||||
long exeMicros = TimeUnit.MICROSECONDS.convert(exeNanos, TimeUnit.NANOSECONDS);
|
||||
|
||||
// increment the eviction statistics
|
||||
evictMicros.add(exeMicros);
|
||||
evictCount.increment();
|
||||
evictByIdle.add(trimmedByIdle);
|
||||
evictByTTL.add(trimmedByTTL);
|
||||
evictByLRU.add(trimmedByLRU);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}]"
|
||||
, name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runnable that calls the eviction routine.
|
||||
*/
|
||||
public class EvictionRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
runEviction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator for sorting by last access time.
|
||||
*/
|
||||
public static class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public int compare(CacheEntry entry1, CacheEntry entry2) {
|
||||
return Long.compare(entry1.getLastAccessTime(), entry2.getLastAccessTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the value to additionally hold createTime and lastAccessTime and hit counter.
|
||||
*/
|
||||
public static class CacheEntry {
|
||||
|
||||
private final Object key;
|
||||
private final Object value;
|
||||
private final long createTime;
|
||||
private long lastAccessTime;
|
||||
|
||||
public CacheEntry(Object key, Object value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
this.lastAccessTime = createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry key.
|
||||
*/
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entry value.
|
||||
*/
|
||||
public Object getValue() {
|
||||
// long assignment should be atomic these days (Ref Cliff Click)
|
||||
lastAccessTime = System.currentTimeMillis();
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time the entry was created.
|
||||
*/
|
||||
public long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time the entry was last accessed.
|
||||
*/
|
||||
public long getLastAccessTime() {
|
||||
return lastAccessTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
return hitCount.get();
|
||||
}
|
||||
}
|
||||
public int getHitCount() {
|
||||
return hitCount.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -8,18 +9,13 @@ import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.avaje.ebean.event.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
import com.avaje.ebean.config.ServerConfig;
|
||||
import com.avaje.ebean.event.BeanFinder;
|
||||
import com.avaje.ebean.event.BeanPersistController;
|
||||
import com.avaje.ebean.event.BeanPersistListener;
|
||||
import com.avaje.ebean.event.BeanQueryAdapter;
|
||||
import com.avaje.ebean.event.ServerConfigStartup;
|
||||
import com.avaje.ebean.event.TransactionEventListener;
|
||||
import com.avaje.ebeaninternal.server.type.ScalarType;
|
||||
import com.avaje.ebeaninternal.server.util.ClassPathSearchMatcher;
|
||||
|
||||
@@ -29,364 +25,360 @@ import com.avaje.ebeaninternal.server.util.ClassPathSearchMatcher;
|
||||
*/
|
||||
public class BootupClasses implements ClassPathSearchMatcher {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BootupClasses.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(BootupClasses.class);
|
||||
|
||||
private ArrayList<Class<?>> embeddableList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> embeddableList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> entityList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> entityList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> scalarTypeList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> scalarTypeList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> scalarConverterList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> scalarConverterList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> compoundTypeList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> beanControllerList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> compoundTypeList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> transactionEventListenerList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> beanControllerList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> beanFinderList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> transactionEventListenerList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> beanListenerList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> beanFindControllerList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> beanQueryAdapterList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> beanQueryAdapterList = new ArrayList<Class<?>>();
|
||||
private ArrayList<Class<?>> beanListenerList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> serverConfigStartupList = new ArrayList<Class<?>>();
|
||||
private ArrayList<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<ServerConfigStartup>();
|
||||
|
||||
private ArrayList<Class<?>> serverConfigStartupList = new ArrayList<Class<?>>();
|
||||
private ArrayList<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<ServerConfigStartup>();
|
||||
private List<BeanFindController> findControllerInstances = new ArrayList<BeanFindController>();
|
||||
private List<BeanPersistController> persistControllerInstances = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPersistListener> persistListenerInstances = new ArrayList<BeanPersistListener>();
|
||||
private List<BeanQueryAdapter> queryAdapterInstances = new ArrayList<BeanQueryAdapter>();
|
||||
private List<TransactionEventListener> transactionEventListenerInstances = new ArrayList<TransactionEventListener>();
|
||||
|
||||
private List<BeanPersistController> persistControllerInstances = new ArrayList<BeanPersistController>();
|
||||
private List<BeanPersistListener> persistListenerInstances = new ArrayList<BeanPersistListener>();
|
||||
private List<BeanQueryAdapter> queryAdapterInstances = new ArrayList<BeanQueryAdapter>();
|
||||
private List<TransactionEventListener> transactionEventListenerInstances = new ArrayList<TransactionEventListener>();
|
||||
public BootupClasses() {
|
||||
}
|
||||
|
||||
public BootupClasses() {
|
||||
public BootupClasses(List<Class<?>> list) {
|
||||
if (list != null) {
|
||||
for (Class<?> cls : list) {
|
||||
isMatch(cls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run any ServerConfigStartup listeners.
|
||||
*/
|
||||
public void runServerConfigStartup(ServerConfig serverConfig) {
|
||||
|
||||
for (Class<?> cls : serverConfigStartupList) {
|
||||
try {
|
||||
ServerConfigStartup newInstance = (ServerConfigStartup) cls.newInstance();
|
||||
newInstance.onStart(serverConfig);
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanQueryAdapter " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addQueryAdapters(List<BeanQueryAdapter> queryAdapterInstances) {
|
||||
if (queryAdapterInstances != null) {
|
||||
for (BeanQueryAdapter a : queryAdapterInstances) {
|
||||
this.queryAdapterInstances.add(a);
|
||||
// don't automatically instantiate
|
||||
this.beanQueryAdapterList.remove(a.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanPersistController instances.
|
||||
*/
|
||||
public void addPersistControllers(List<BeanPersistController> beanControllerInstances) {
|
||||
if (beanControllerInstances != null) {
|
||||
for (BeanPersistController c : beanControllerInstances) {
|
||||
this.persistControllerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanControllerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanFindController instances.
|
||||
*/
|
||||
public void addFindControllers(List<BeanFindController> findControllers) {
|
||||
if (findControllers != null) {
|
||||
for (BeanFindController c : findControllers) {
|
||||
this.findControllerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanFindControllerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add TransactionEventListeners instances.
|
||||
*/
|
||||
public void addTransactionEventListeners(List<TransactionEventListener> transactionEventListeners) {
|
||||
if (transactionEventListeners != null) {
|
||||
for (TransactionEventListener c : transactionEventListeners) {
|
||||
this.transactionEventListenerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.transactionEventListenerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addPersistListeners(List<BeanPersistListener> listenerInstances) {
|
||||
if (listenerInstances != null) {
|
||||
for (BeanPersistListener l : listenerInstances) {
|
||||
this.persistListenerInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.beanListenerList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addServerConfigStartup(List<ServerConfigStartup> startupInstances) {
|
||||
if (startupInstances != null) {
|
||||
for (ServerConfigStartup l : startupInstances) {
|
||||
this.serverConfigStartupInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.serverConfigStartupList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<BeanQueryAdapter> getBeanQueryAdapters() {
|
||||
// add class registered BeanQueryAdapter to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanQueryAdapterList) {
|
||||
try {
|
||||
BeanQueryAdapter newInstance = (BeanQueryAdapter) cls.newInstance();
|
||||
queryAdapterInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanQueryAdapter " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public BootupClasses(List<Class<?>> list) {
|
||||
if (list != null) {
|
||||
for (Class<?> cls : list) {
|
||||
isMatch(cls);
|
||||
}
|
||||
}
|
||||
return queryAdapterInstances;
|
||||
}
|
||||
|
||||
public List<BeanFindController> getBeanFindControllers() {
|
||||
// add class registered BeanFindController to the
|
||||
// list of created instances
|
||||
for (Class<?> cls : beanFindControllerList) {
|
||||
try {
|
||||
BeanFindController newInstance = (BeanFindController) cls.newInstance();
|
||||
findControllerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanPersistController " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private BootupClasses(BootupClasses parent) {
|
||||
this.embeddableList.addAll(parent.embeddableList);
|
||||
this.entityList.addAll(parent.entityList);
|
||||
this.scalarTypeList.addAll(parent.scalarTypeList);
|
||||
this.scalarConverterList.addAll(parent.scalarConverterList);
|
||||
this.compoundTypeList.addAll(parent.compoundTypeList);
|
||||
this.beanControllerList.addAll(parent.beanControllerList);
|
||||
this.transactionEventListenerList.addAll(parent.transactionEventListenerList);
|
||||
this.beanFinderList.addAll(parent.beanFinderList);
|
||||
this.beanListenerList.addAll(parent.beanListenerList);
|
||||
this.beanQueryAdapterList.addAll(parent.beanQueryAdapterList);
|
||||
this.serverConfigStartupList.addAll(parent.serverConfigStartupList);
|
||||
return findControllerInstances;
|
||||
}
|
||||
|
||||
public List<BeanPersistListener> getBeanPersistListeners() {
|
||||
// add class registered BeanPersistController to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanListenerList) {
|
||||
try {
|
||||
BeanPersistListener newInstance = (BeanPersistListener) cls.newInstance();
|
||||
persistListenerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanPersistController " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this object so that classes can be added to it.
|
||||
*/
|
||||
public BootupClasses createCopy() {
|
||||
return new BootupClasses(this);
|
||||
return persistListenerInstances;
|
||||
}
|
||||
|
||||
public List<BeanPersistController> getBeanPersistControllers() {
|
||||
// add class registered BeanPersistController to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanControllerList) {
|
||||
try {
|
||||
BeanPersistController newInstance = (BeanPersistController) cls.newInstance();
|
||||
persistControllerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanPersistController " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run any ServerConfigStartup listeners.
|
||||
*/
|
||||
public void runServerConfigStartup(ServerConfig serverConfig) {
|
||||
|
||||
for (Class<?> cls : serverConfigStartupList) {
|
||||
try {
|
||||
ServerConfigStartup newInstance = (ServerConfigStartup) cls.newInstance();
|
||||
newInstance.onStart(serverConfig);
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanQueryAdapter " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addQueryAdapters(List<BeanQueryAdapter> queryAdapterInstances) {
|
||||
if (queryAdapterInstances != null) {
|
||||
for (BeanQueryAdapter a : queryAdapterInstances) {
|
||||
this.queryAdapterInstances.add(a);
|
||||
// don't automatically instantiate
|
||||
this.beanQueryAdapterList.remove(a.getClass());
|
||||
}
|
||||
}
|
||||
return persistControllerInstances;
|
||||
}
|
||||
|
||||
public List<TransactionEventListener> getTransactionEventListeners() {
|
||||
// add class registered TransactionEventListener to the
|
||||
// already created instances
|
||||
for (Class<?> cls : transactionEventListenerList) {
|
||||
try {
|
||||
TransactionEventListener newInstance = (TransactionEventListener) cls.newInstance();
|
||||
transactionEventListenerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating TransactionEventListener " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add BeanPersistController instances.
|
||||
*/
|
||||
public void addPersistControllers(List<BeanPersistController> beanControllerInstances) {
|
||||
if (beanControllerInstances != null) {
|
||||
for (BeanPersistController c : beanControllerInstances) {
|
||||
this.persistControllerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.beanControllerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
return transactionEventListenerInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of Embeddable classes.
|
||||
*/
|
||||
public List<Class<?>> getEmbeddables() {
|
||||
return embeddableList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of entity classes.
|
||||
*/
|
||||
public List<Class<?>> getEntities() {
|
||||
return entityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarTypes found.
|
||||
*/
|
||||
public List<Class<?>> getScalarTypes() {
|
||||
return scalarTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public List<Class<?>> getScalarConverters() {
|
||||
return scalarConverterList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public List<Class<?>> getCompoundTypes() {
|
||||
return compoundTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of BeanControllers found.
|
||||
*/
|
||||
public List<Class<?>> getBeanControllers() {
|
||||
return beanControllerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of TransactionEventListeners found
|
||||
*/
|
||||
public List<Class<?>> getTransactionEventListenerList() {
|
||||
return transactionEventListenerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of BeanListeners found.
|
||||
*/
|
||||
public List<Class<?>> getBeanListeners() {
|
||||
return beanListenerList;
|
||||
}
|
||||
|
||||
public boolean isMatch(Class<?> cls) {
|
||||
|
||||
if (isEmbeddable(cls)) {
|
||||
embeddableList.add(cls);
|
||||
|
||||
} else if (isEntity(cls)) {
|
||||
entityList.add(cls);
|
||||
|
||||
} else {
|
||||
return isInterestingInterface(cls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add TransactionEventListeners instances.
|
||||
*/
|
||||
public void addTransactionEventListeners(List<TransactionEventListener> transactionEventListeners) {
|
||||
if (transactionEventListeners != null) {
|
||||
for (TransactionEventListener c : transactionEventListeners) {
|
||||
this.transactionEventListenerInstances.add(c);
|
||||
// don't automatically instantiate
|
||||
this.transactionEventListenerList.remove(c.getClass());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for interesting interfaces.
|
||||
* <p>
|
||||
* This includes ScalarType, BeanController, BeanFinder and BeanListener.
|
||||
* </p>
|
||||
*/
|
||||
private boolean isInterestingInterface(Class<?> cls) {
|
||||
|
||||
if (Modifier.isAbstract(cls.getModifiers())) {
|
||||
// do not include abstract classes as we can
|
||||
// not instantiate them
|
||||
return false;
|
||||
}
|
||||
boolean interesting = false;
|
||||
|
||||
if (BeanPersistController.class.isAssignableFrom(cls)) {
|
||||
beanControllerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
public void addPersistListeners(List<BeanPersistListener> listenerInstances) {
|
||||
if (listenerInstances != null) {
|
||||
for (BeanPersistListener l : listenerInstances) {
|
||||
this.persistListenerInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.beanListenerList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addServerConfigStartup(List<ServerConfigStartup> startupInstances) {
|
||||
if (startupInstances != null) {
|
||||
for (ServerConfigStartup l : startupInstances) {
|
||||
this.serverConfigStartupInstances.add(l);
|
||||
// don't automatically instantiate
|
||||
this.serverConfigStartupList.remove(l.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<BeanQueryAdapter> getBeanQueryAdapters() {
|
||||
// add class registered BeanQueryAdapter to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanQueryAdapterList) {
|
||||
try {
|
||||
BeanQueryAdapter newInstance = (BeanQueryAdapter) cls.newInstance();
|
||||
queryAdapterInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanQueryAdapter " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
return queryAdapterInstances;
|
||||
if (TransactionEventListener.class.isAssignableFrom(cls)) {
|
||||
transactionEventListenerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
public List<BeanPersistListener> getBeanPersistListeners() {
|
||||
// add class registered BeanPersistController to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanListenerList) {
|
||||
try {
|
||||
BeanPersistListener newInstance = (BeanPersistListener) cls.newInstance();
|
||||
persistListenerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanPersistController " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
return persistListenerInstances;
|
||||
if (ScalarType.class.isAssignableFrom(cls)) {
|
||||
scalarTypeList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
public List<BeanPersistController> getBeanPersistControllers() {
|
||||
// add class registered BeanPersistController to the
|
||||
// already created instances
|
||||
for (Class<?> cls : beanControllerList) {
|
||||
try {
|
||||
BeanPersistController newInstance = (BeanPersistController) cls.newInstance();
|
||||
persistControllerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating BeanPersistController " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
return persistControllerInstances;
|
||||
if (ScalarTypeConverter.class.isAssignableFrom(cls)) {
|
||||
scalarConverterList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
public List<TransactionEventListener> getTransactionEventListeners() {
|
||||
// add class registered TransactionEventListener to the
|
||||
// already created instances
|
||||
for (Class<?> cls : transactionEventListenerList) {
|
||||
try {
|
||||
TransactionEventListener newInstance = (TransactionEventListener) cls.newInstance();
|
||||
transactionEventListenerInstances.add(newInstance);
|
||||
} catch (Exception e) {
|
||||
String msg = "Error creating TransactionEventListener " + cls;
|
||||
logger.error(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
return transactionEventListenerInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of Embeddable classes.
|
||||
*/
|
||||
public ArrayList<Class<?>> getEmbeddables() {
|
||||
return embeddableList;
|
||||
if (CompoundType.class.isAssignableFrom(cls)) {
|
||||
compoundTypeList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of entity classes.
|
||||
*/
|
||||
public ArrayList<Class<?>> getEntities() {
|
||||
return entityList;
|
||||
if (BeanFindController.class.isAssignableFrom(cls)) {
|
||||
beanFindControllerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarTypes found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getScalarTypes() {
|
||||
return scalarTypeList;
|
||||
if (BeanPersistListener.class.isAssignableFrom(cls)) {
|
||||
beanListenerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getScalarConverters() {
|
||||
return scalarConverterList;
|
||||
if (BeanQueryAdapter.class.isAssignableFrom(cls)) {
|
||||
beanQueryAdapterList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of ScalarConverters found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getCompoundTypes() {
|
||||
return compoundTypeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of BeanControllers found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getBeanControllers() {
|
||||
return beanControllerList;
|
||||
if (ServerConfigStartup.class.isAssignableFrom(cls)) {
|
||||
serverConfigStartupList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of TransactionEventListeners found
|
||||
*/
|
||||
public ArrayList<Class<?>> getTransactionEventListenerList() {
|
||||
return transactionEventListenerList;
|
||||
return interesting;
|
||||
}
|
||||
|
||||
private boolean isEntity(Class<?> cls) {
|
||||
|
||||
Annotation ann = cls.getAnnotation(Entity.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
ann = cls.getAnnotation(Table.class);
|
||||
return ann != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of BeanFinders found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getBeanFinders() {
|
||||
return beanFinderList;
|
||||
}
|
||||
private boolean isEmbeddable(Class<?> cls) {
|
||||
|
||||
/**
|
||||
* Return the list of BeanListeners found.
|
||||
*/
|
||||
public ArrayList<Class<?>> getBeanListeners() {
|
||||
return beanListenerList;
|
||||
}
|
||||
|
||||
public boolean isMatch(Class<?> cls) {
|
||||
|
||||
if (isEmbeddable(cls)) {
|
||||
embeddableList.add(cls);
|
||||
|
||||
} else if (isEntity(cls)) {
|
||||
entityList.add(cls);
|
||||
|
||||
} else if (isInterestingInterface(cls)) {
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for interesting interfaces.
|
||||
* <p>
|
||||
* This includes ScalarType, BeanController, BeanFinder and BeanListener.
|
||||
* </p>
|
||||
*/
|
||||
private boolean isInterestingInterface(Class<?> cls) {
|
||||
|
||||
boolean interesting = false;
|
||||
|
||||
if (BeanPersistController.class.isAssignableFrom(cls)) {
|
||||
beanControllerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (TransactionEventListener.class.isAssignableFrom(cls)) {
|
||||
transactionEventListenerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ScalarType.class.isAssignableFrom(cls)) {
|
||||
scalarTypeList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ScalarTypeConverter.class.isAssignableFrom(cls)) {
|
||||
scalarConverterList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (CompoundType.class.isAssignableFrom(cls)) {
|
||||
compoundTypeList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanFinder.class.isAssignableFrom(cls)) {
|
||||
beanFinderList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanPersistListener.class.isAssignableFrom(cls)) {
|
||||
beanListenerList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (BeanQueryAdapter.class.isAssignableFrom(cls)) {
|
||||
beanQueryAdapterList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
if (ServerConfigStartup.class.isAssignableFrom(cls)){
|
||||
serverConfigStartupList.add(cls);
|
||||
interesting = true;
|
||||
}
|
||||
|
||||
return interesting;
|
||||
}
|
||||
|
||||
private boolean isEntity(Class<?> cls) {
|
||||
|
||||
Annotation ann = cls.getAnnotation(Entity.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
ann = cls.getAnnotation(Table.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isEmbeddable(Class<?> cls) {
|
||||
|
||||
Annotation ann = cls.getAnnotation(Embeddable.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Annotation ann = cls.getAnnotation(Embeddable.class);
|
||||
return ann != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,9 @@ public class DatabasePlatformFactory {
|
||||
if (dbName.equals("mysql")) {
|
||||
return new MySqlPlatform();
|
||||
}
|
||||
|
||||
if (dbName.equals("h2")) {
|
||||
return new H2Platform();
|
||||
}
|
||||
if (dbName.equals("sqlite")) {
|
||||
return new SQLitePlatform();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user