mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4306ce1ab | ||
|
|
444b656780 | ||
|
|
fcbba23441 | ||
|
|
18961047a1 | ||
|
|
34347fc3e1 | ||
|
|
189e0a2ea9 | ||
|
|
182e027521 | ||
|
|
f85fa2c21d | ||
|
|
5a5f479568 | ||
|
|
9ca2486c9c | ||
|
|
656b239925 | ||
|
|
5d46904341 | ||
|
|
f0dd069ed2 | ||
|
|
5bd454bdc0 | ||
|
|
eeebaf9a08 | ||
|
|
636a148509 | ||
|
|
170cd6051e | ||
|
|
522fc2384c | ||
|
|
6f214590aa | ||
|
|
0014ea3501 | ||
|
|
db3140512f | ||
|
|
8bfa331c61 | ||
|
|
456a1d8608 | ||
|
|
695d3374a8 | ||
|
|
5488d054bf |
@@ -9,7 +9,7 @@
|
||||
|
||||
<groupId>org.avaje.ebeanorm</groupId>
|
||||
<artifactId>avaje-ebeanorm</artifactId>
|
||||
<version>3.3.1-RC1</version>
|
||||
<version>3.3.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>avaje-ebeanorm</name>
|
||||
|
||||
@@ -36,11 +36,6 @@ import java.util.Map;
|
||||
*/
|
||||
public interface ExpressionFactory {
|
||||
|
||||
/**
|
||||
* Return the language for this expression factory.
|
||||
*/
|
||||
public String getLang();
|
||||
|
||||
/**
|
||||
* Equal To - property equal to the given value.
|
||||
*/
|
||||
|
||||
@@ -269,26 +269,6 @@ import java.util.Set;
|
||||
*/
|
||||
public interface Query<T> extends Serializable {
|
||||
|
||||
/**
|
||||
* How this query should use (or not) the Lucene Index if one is defined for
|
||||
* the bean type.
|
||||
*/
|
||||
public enum UseIndex {
|
||||
NO, DEFAULT, YES_IDS, YES_OBJECTS
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly specify how this query should use a Lucene Index if one is
|
||||
* defined for this bean type.
|
||||
*/
|
||||
public Query<T> setUseIndex(UseIndex useIndex);
|
||||
|
||||
/**
|
||||
* Return the setting for how this query should use a Lucene Index if one is
|
||||
* defined for this bean type.
|
||||
*/
|
||||
public UseIndex getUseIndex();
|
||||
|
||||
/**
|
||||
* Return the RawSql that was set to use for this query.
|
||||
*/
|
||||
@@ -1072,16 +1052,14 @@ public interface Query<T> extends Serializable {
|
||||
*/
|
||||
public String getGeneratedSql();
|
||||
|
||||
/**
|
||||
* Return the total hits matched for a lucene text search query.
|
||||
*/
|
||||
public int getTotalHits();
|
||||
|
||||
/**
|
||||
* executed the select with "for update" which should lock the record
|
||||
* "on read"
|
||||
*/
|
||||
public Query<T> setForUpdate(boolean forUpdate);
|
||||
|
||||
/**
|
||||
* Return true if this query has forUpdate set.
|
||||
*/
|
||||
public boolean isForUpdate();
|
||||
}
|
||||
|
||||
@@ -35,13 +35,6 @@ public interface Transaction extends Closeable {
|
||||
*/
|
||||
public static final int SERIALIZABLE = java.sql.Connection.TRANSACTION_SERIALIZABLE;
|
||||
|
||||
// /**
|
||||
// * You can call this after the transaction commit to wait for any changes to
|
||||
// * Lucene indexes to be made and committed. Note that generally this could
|
||||
// * be some time so it is not expected that you call this method generally.
|
||||
// */
|
||||
// public void waitForIndexUpdates();
|
||||
|
||||
/**
|
||||
* Return true if this transaction is read only.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
|
||||
/**
|
||||
* Specify the default cache use specific entity type.
|
||||
@@ -56,9 +55,4 @@ public @interface CacheStrategy {
|
||||
*/
|
||||
String warmingQuery() default "";
|
||||
|
||||
/**
|
||||
* Default setting for using a text index if it has been defined on this bean
|
||||
* type.
|
||||
*/
|
||||
UseIndex useIndex() default UseIndex.DEFAULT;
|
||||
};
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
package com.avaje.ebean.meta;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.avaje.ebean.bean.ObjectGraphOrigin;
|
||||
|
||||
/**
|
||||
* Statistics collected by AutoFetch profiling.
|
||||
*/
|
||||
@Entity
|
||||
public class MetaAutoFetchStatistic implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6640406753257176803L;
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private ObjectGraphOrigin origin;
|
||||
|
||||
private String beanType;
|
||||
|
||||
private int counter;
|
||||
|
||||
@Transient
|
||||
private List<QueryStats> queryStats;
|
||||
|
||||
@Transient
|
||||
private List<NodeUsageStats> nodeUsageStats;
|
||||
|
||||
public MetaAutoFetchStatistic() {
|
||||
}
|
||||
|
||||
public MetaAutoFetchStatistic(ObjectGraphOrigin origin, int counter, List<QueryStats> queryStats,
|
||||
List<NodeUsageStats> nodeUsageStats) {
|
||||
|
||||
this.origin = origin;
|
||||
this.beanType = origin == null ? null : origin.getBeanType();
|
||||
this.id = origin == null ? null : origin.getKey();
|
||||
this.counter = counter;
|
||||
this.queryStats = queryStats;
|
||||
this.nodeUsageStats = nodeUsageStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the query point key.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bean type.
|
||||
*/
|
||||
public String getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query point.
|
||||
*/
|
||||
public ObjectGraphOrigin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of profiled queries the statistics is based on.
|
||||
*/
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query execution statistics.
|
||||
*/
|
||||
public List<QueryStats> getQueryStats() {
|
||||
return queryStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the node usage statistics.
|
||||
*/
|
||||
public List<NodeUsageStats> getNodeUsageStats() {
|
||||
return nodeUsageStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME: This will likely be deprecated in favour of a separate object graph
|
||||
* cost.
|
||||
*/
|
||||
public static class QueryStats implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5517935732867671387L;
|
||||
|
||||
private final String path;
|
||||
|
||||
private final long exeCount;
|
||||
|
||||
private final long totalBeanLoaded;
|
||||
|
||||
private final long totalMicros;
|
||||
|
||||
public QueryStats(String path, long exeCount, long totalBeanLoaded, long totalMicros) {
|
||||
this.path = path;
|
||||
this.exeCount = exeCount;
|
||||
this.totalBeanLoaded = totalBeanLoaded;
|
||||
this.totalMicros = totalMicros;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path. This is empty string for the origin query and otherwise
|
||||
* the path for the associated lazy loading queries.
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of queries executed.
|
||||
*/
|
||||
public long getExeCount() {
|
||||
return exeCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of beans loaded by the query.
|
||||
*/
|
||||
public long getTotalBeanLoaded() {
|
||||
return totalBeanLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total time in microseconds of the queries.
|
||||
*/
|
||||
public long getTotalMicros() {
|
||||
return totalMicros;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
long avgMicros = exeCount == 0 ? 0 : totalMicros / exeCount;
|
||||
|
||||
return "queryExe path[" + path + "] count[" + exeCount + "] totalBeansLoaded["
|
||||
+ totalBeanLoaded + "] avgMicros[" + avgMicros + "] totalMicros[" + totalMicros
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects usages statistics for a given node in the object graph.
|
||||
*/
|
||||
public static class NodeUsageStats implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1786787832374844739L;
|
||||
|
||||
private final String path;
|
||||
|
||||
private final int profileCount;
|
||||
|
||||
private final int profileUsedCount;
|
||||
|
||||
private final String[] usedProperties;
|
||||
|
||||
public NodeUsageStats(String path, int profileCount, int profileUsedCount,
|
||||
String[] usedProperties) {
|
||||
this.path = path == null ? "" : path;
|
||||
this.profileCount = profileCount;
|
||||
this.profileUsedCount = profileUsedCount;
|
||||
this.usedProperties = usedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path. This is empty string for the origin and otherwise the
|
||||
* path for the associated nodes.
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of profiled beans for this node.
|
||||
*/
|
||||
public int getProfileCount() {
|
||||
return profileCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of profiled beans that where actually used for this node.
|
||||
* <p>
|
||||
* The difference between profiled and used could show uneven traversal of
|
||||
* the object graph. UI paging through results means the traversal for the
|
||||
* first x beans can be much higher than the last x beans.
|
||||
* </p>
|
||||
*/
|
||||
public int getProfileUsedCount() {
|
||||
return profileUsedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The properties used at this node.
|
||||
*/
|
||||
public String[] getUsedProperties() {
|
||||
return usedProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the properties as a Set rather than an Array.
|
||||
*/
|
||||
public Set<String> getUsedPropertiesSet() {
|
||||
LinkedHashSet<String> s = new LinkedHashSet<String>();
|
||||
for (int i = 0; i < usedProperties.length; i++) {
|
||||
s.add(usedProperties[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "path[" + path + "] profileCount[" + profileCount + "] used[" + profileUsedCount
|
||||
+ "] props" + Arrays.toString(usedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package com.avaje.ebean.meta;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import com.avaje.ebean.bean.ObjectGraphOrigin;
|
||||
|
||||
/**
|
||||
* "Tuned fetch" information used by AutoFetch.
|
||||
* <p>
|
||||
* Note that the queryPoint is effectively the Id field for this bean.
|
||||
* </p>
|
||||
* <p>
|
||||
* The queryPoint identifies both the query and call stack.
|
||||
* </p>
|
||||
*/
|
||||
@Entity
|
||||
public class MetaAutoFetchTunedQueryInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3119991928889170215L;
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String beanType;
|
||||
|
||||
/**
|
||||
* The profile query point (call stack and query).
|
||||
*/
|
||||
private ObjectGraphOrigin origin;
|
||||
|
||||
/**
|
||||
* The tuned query details with joins and properties.
|
||||
*/
|
||||
private String tunedDetail;
|
||||
|
||||
/**
|
||||
* The number of times profiling has been collected for this query point.
|
||||
*/
|
||||
private int profileCount;
|
||||
|
||||
/**
|
||||
* The number of queries tuned by this info.
|
||||
*/
|
||||
private int tunedCount;
|
||||
|
||||
private long lastTuneTime;
|
||||
|
||||
public MetaAutoFetchTunedQueryInfo() {
|
||||
|
||||
}
|
||||
|
||||
public MetaAutoFetchTunedQueryInfo(final ObjectGraphOrigin origin, String tunedDetail,
|
||||
int profileCount, int tunedCount, long lastTuneTime) {
|
||||
|
||||
this.origin = origin;
|
||||
this.beanType = origin == null ? null : origin.getBeanType();
|
||||
this.id = origin == null ? null : origin.getKey();
|
||||
this.tunedDetail = tunedDetail;
|
||||
this.profileCount = profileCount;
|
||||
this.tunedCount = tunedCount;
|
||||
this.lastTuneTime = lastTuneTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query point key.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of bean this is tuned for.
|
||||
*/
|
||||
public String getBeanType() {
|
||||
return beanType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query point.
|
||||
*/
|
||||
public ObjectGraphOrigin getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* The tuned query detail in string form.
|
||||
*/
|
||||
public String getTunedDetail() {
|
||||
return tunedDetail;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of profiled queries the tuned query is based on.
|
||||
*/
|
||||
public int getProfileCount() {
|
||||
return profileCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of queries tuned.
|
||||
*/
|
||||
public int getTunedCount() {
|
||||
return tunedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time of the last tune (that changed the query).
|
||||
*/
|
||||
public long getLastTuneTime() {
|
||||
return lastTuneTime;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "origin[" + origin + "] query[" + tunedDetail + "] profileCount[" + profileCount + "]";
|
||||
}
|
||||
}
|
||||
@@ -80,11 +80,6 @@ public interface SpiQuery<T> extends Query<T> {
|
||||
*/
|
||||
SUBQUERY
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total hits when querying against lucene.
|
||||
*/
|
||||
public void setTotalHits(int totalHits);
|
||||
|
||||
/**
|
||||
* Return true if select all properties was used to ensure the property
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
package com.avaje.ebeaninternal.server.autofetch;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.avaje.ebean.bean.NodeUsageCollector;
|
||||
import com.avaje.ebean.bean.ObjectGraphNode;
|
||||
import com.avaje.ebean.bean.ObjectGraphOrigin;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic.NodeUsageStats;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic.QueryStats;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebean.text.PathProperties.Props;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -53,30 +48,6 @@ public class Statistics implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public MetaAutoFetchStatistic createPublicMeta() {
|
||||
|
||||
synchronized (monitor) {
|
||||
|
||||
StatisticsQuery[] sourceQueryStats = queryStatsMap.values().toArray(new StatisticsQuery[queryStatsMap.size()]);
|
||||
List<QueryStats> destQueryStats = new ArrayList<QueryStats>(sourceQueryStats.length);
|
||||
|
||||
// copy the query statistics
|
||||
for (int i = 0; i < sourceQueryStats.length; i++) {
|
||||
destQueryStats.add(sourceQueryStats[i].createPublicMeta());
|
||||
}
|
||||
|
||||
StatisticsNodeUsage[] sourceNodeUsage = nodeUsageMap.values().toArray(new StatisticsNodeUsage[nodeUsageMap.size()]);
|
||||
List<NodeUsageStats> destNodeUsage = new ArrayList<NodeUsageStats>(sourceNodeUsage.length);
|
||||
|
||||
// copy the node usage statistics
|
||||
for (int i = 0; i < sourceNodeUsage.length; i++) {
|
||||
destNodeUsage.add(sourceNodeUsage[i].createPublicMeta());
|
||||
}
|
||||
|
||||
return new MetaAutoFetchStatistic(origin, counter, destQueryStats, destNodeUsage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of times the root query has executed.
|
||||
* <p>
|
||||
|
||||
@@ -5,16 +5,16 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.bean.NodeUsageCollector;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic.NodeUsageStats;
|
||||
import com.avaje.ebean.text.PathProperties;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanPropertyAssoc;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
import com.avaje.ebeaninternal.server.query.SplitName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Collects usages statistics for a given node in the object graph.
|
||||
@@ -44,13 +44,6 @@ public class StatisticsNodeUsage implements Serializable {
|
||||
this.queryTuningAddVersion = queryTuningAddVersion;
|
||||
}
|
||||
|
||||
public NodeUsageStats createPublicMeta() {
|
||||
synchronized(monitor){
|
||||
String[] usedProps = aggregateUsed.toArray(new String[aggregateUsed.size()]);
|
||||
return new NodeUsageStats(path, profileCount, profileUsedCount, usedProps);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildTunedFetch(PathProperties pathProps, BeanDescriptor<?> rootDesc) {
|
||||
|
||||
synchronized(monitor){
|
||||
|
||||
@@ -2,8 +2,6 @@ package com.avaje.ebeaninternal.server.autofetch;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic.QueryStats;
|
||||
|
||||
/**
|
||||
* Used to accumulate query execution statistics.
|
||||
*/
|
||||
@@ -22,10 +20,6 @@ public class StatisticsQuery implements Serializable {
|
||||
public StatisticsQuery(String path){
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public QueryStats createPublicMeta() {
|
||||
return new QueryStats(path, exeCount, totalBeanLoaded, totalMicros);
|
||||
}
|
||||
|
||||
public void add(long beansLoaded, long micros) {
|
||||
exeCount++;
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.avaje.ebeaninternal.server.autofetch;
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.avaje.ebean.bean.ObjectGraphOrigin;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchTunedQueryInfo;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
|
||||
|
||||
@@ -73,13 +72,6 @@ public class TunedQueryInfo implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of this tuned fetch data for public consumption.
|
||||
*/
|
||||
public MetaAutoFetchTunedQueryInfo createPublicMeta() {
|
||||
return new MetaAutoFetchTunedQueryInfo(origin, tunedDetail.toString(), profileCount, tunedCount, lastTuneTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of times profiling has been collected for this query
|
||||
* point.
|
||||
|
||||
@@ -2,6 +2,11 @@ package com.avaje.ebeaninternal.server.core;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
@@ -11,6 +16,8 @@ import com.avaje.ebeaninternal.api.SpiTransaction;
|
||||
*/
|
||||
public abstract class BeanRequest {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(BeanRequest.class);
|
||||
|
||||
/**
|
||||
* The server processing the request.
|
||||
*/
|
||||
@@ -84,7 +91,14 @@ public abstract class BeanRequest {
|
||||
*/
|
||||
public void rollbackTransIfRequired() {
|
||||
if (createdTransaction) {
|
||||
transaction.rollback();
|
||||
try {
|
||||
transaction.rollback();
|
||||
} catch (PersistenceException e) {
|
||||
// Just log this and carry on. A previous exception has been
|
||||
// thrown and if this rollback throws exception it likely means
|
||||
// that the connection is broken (and the datasource and db will cleanup)
|
||||
log.error("Error trying to rollack a transaction (after a prior exception thrown)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,16 +82,22 @@ public class BootupClassPathSearch {
|
||||
ClassPathSearchFilter filter = new ClassPathSearchFilter();
|
||||
filter.addDefaultExcludePackages();
|
||||
|
||||
if (packages != null) {
|
||||
if (packages != null && packages.size() > 0) {
|
||||
for (String packageName : packages) {
|
||||
filter.includePackage(packageName);
|
||||
}
|
||||
|
||||
// if they specified include packages, they don't want by default to include everything
|
||||
filter.setDefaultPackageMatch(false);
|
||||
}
|
||||
|
||||
if (jars != null) {
|
||||
if (jars != null && jars.size() > 0) {
|
||||
for (String jarName : jars) {
|
||||
filter.includeJar(jarName);
|
||||
}
|
||||
|
||||
// if they specified jars to specifically include, they don't want everything included
|
||||
filter.setDefaultJarMatch(false);
|
||||
}
|
||||
|
||||
return filter;
|
||||
|
||||
@@ -8,8 +8,9 @@ import java.util.List;
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.config.CompoundType;
|
||||
import com.avaje.ebean.config.ScalarTypeConverter;
|
||||
@@ -22,8 +23,6 @@ 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;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Interesting classes for a EbeanServer such as Embeddable, Entity,
|
||||
@@ -33,8 +32,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BootupClasses.class);
|
||||
|
||||
private ArrayList<Class<?>> xmlBeanList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> embeddableList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> entityList = new ArrayList<Class<?>>();
|
||||
@@ -55,8 +52,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
|
||||
private ArrayList<Class<?>> beanQueryAdapterList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> luceneIndexList = new ArrayList<Class<?>>();
|
||||
|
||||
private ArrayList<Class<?>> serverConfigStartupList = new ArrayList<Class<?>>();
|
||||
private ArrayList<ServerConfigStartup> serverConfigStartupInstances = new ArrayList<ServerConfigStartup>();
|
||||
|
||||
@@ -75,7 +70,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
}
|
||||
|
||||
private BootupClasses(BootupClasses parent) {
|
||||
this.xmlBeanList.addAll(parent.xmlBeanList);
|
||||
this.embeddableList.addAll(parent.embeddableList);
|
||||
this.entityList.addAll(parent.entityList);
|
||||
this.scalarTypeList.addAll(parent.scalarTypeList);
|
||||
@@ -86,7 +80,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
this.beanFinderList.addAll(parent.beanFinderList);
|
||||
this.beanListenerList.addAll(parent.beanListenerList);
|
||||
this.beanQueryAdapterList.addAll(parent.beanQueryAdapterList);
|
||||
this.luceneIndexList.addAll(parent.luceneIndexList);
|
||||
this.serverConfigStartupList.addAll(parent.serverConfigStartupList);
|
||||
}
|
||||
|
||||
@@ -304,13 +297,6 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
return beanListenerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of XML Beans.
|
||||
*/
|
||||
public ArrayList<Class<?>> getXmlBeanList() {
|
||||
return xmlBeanList;
|
||||
}
|
||||
|
||||
public void add(Iterator<Class<?>> it) {
|
||||
while (it.hasNext()) {
|
||||
Class<?> clazz = it.next();
|
||||
@@ -325,11 +311,7 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
|
||||
} else if (isEntity(cls)) {
|
||||
entityList.add(cls);
|
||||
|
||||
} else if (isXmlBean(cls)){
|
||||
entityList.add(cls);
|
||||
//xmlBeanList.add(cls);
|
||||
|
||||
|
||||
} else if (isInterestingInterface(cls)) {
|
||||
return true;
|
||||
|
||||
@@ -419,18 +401,4 @@ public class BootupClasses implements ClassPathSearchMatcher {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isXmlBean(Class<?> cls) {
|
||||
|
||||
Annotation ann = cls.getAnnotation(XmlRootElement.class);
|
||||
if (ann != null) {
|
||||
return true;
|
||||
}
|
||||
ann = cls.getAnnotation(XmlType.class);
|
||||
if (ann != null) {
|
||||
// Only looking for Beans and not Enums
|
||||
return !cls.isEnum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ public final class DefaultServer implements SpiEbeanServer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a query. Only valid for ORM queries (not LDAP)
|
||||
* Compile a query. Only valid for ORM queries.
|
||||
*/
|
||||
public <T> CQuery<T> compileQuery(Query<T> query, Transaction t) {
|
||||
SpiOrmQueryRequest<T> qr = createQueryRequest(Type.SUBQUERY, query, t);
|
||||
|
||||
@@ -80,10 +80,6 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
|
||||
graphContext.registerSecondaryQueries(query);
|
||||
}
|
||||
|
||||
public void setTotalHits(int totalHits) {
|
||||
query.setTotalHits(totalHits);
|
||||
}
|
||||
|
||||
public void executeSecondaryQueries(int defaultQueryBatch) {
|
||||
graphContext.executeSecondaryQueries(this, defaultQueryBatch);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import com.avaje.ebean.SqlUpdate;
|
||||
import com.avaje.ebean.Transaction;
|
||||
import com.avaje.ebean.annotation.ConcurrencyMode;
|
||||
@@ -97,7 +96,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
private final ConcurrentHashMap<String, BeanFkeyProperty> fkeyMap = new ConcurrentHashMap<String, BeanFkeyProperty>();
|
||||
|
||||
public enum EntityType {
|
||||
ORM, EMBEDDED, SQL, META, XMLELEMENT
|
||||
ORM, EMBEDDED, SQL
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +105,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
private final String serverName;
|
||||
|
||||
/**
|
||||
* Set to true if this is a LDAP domain object.
|
||||
* The nature/type of this bean.
|
||||
*/
|
||||
private final EntityType entityType;
|
||||
|
||||
@@ -346,12 +345,9 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
|
||||
private final String defaultSelectClause;
|
||||
private final Set<String> defaultSelectClauseSet;
|
||||
private final String[] defaultSelectDbArray;
|
||||
|
||||
private final String descriptorId;
|
||||
|
||||
private final UseIndex useIndex;
|
||||
|
||||
private SpiEbeanServer ebeanServer;
|
||||
|
||||
private ServerCache beanCache;
|
||||
@@ -372,7 +368,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
this.fullName = InternString.intern(deploy.getFullName());
|
||||
this.descriptorId = descriptorId;
|
||||
|
||||
this.useIndex = deploy.getUseIndex();
|
||||
this.typeManager = typeManager;
|
||||
this.beanType = deploy.getBeanType();
|
||||
this.factoryType = deploy.getFactoryType();
|
||||
@@ -390,7 +385,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
|
||||
this.defaultSelectClause = deploy.getDefaultSelectClause();
|
||||
this.defaultSelectClauseSet = deploy.parseDefaultSelectClause(defaultSelectClause);
|
||||
this.defaultSelectDbArray = deploy.getDefaultSelectDbArray(defaultSelectClauseSet);
|
||||
|
||||
this.idType = deploy.getIdType();
|
||||
this.idGenerator = deploy.getIdGenerator();
|
||||
@@ -569,14 +563,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default strategy for using a lucene index (if an index is
|
||||
* defined on this bean type).
|
||||
*/
|
||||
public UseIndex getUseIndex() {
|
||||
return useIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the Id properties first.
|
||||
* <p>
|
||||
@@ -808,13 +794,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
return defaultSelectClauseSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* For LDAP return array of (DB) attributes to include in query by default.
|
||||
*/
|
||||
public String[] getDefaultSelectDbArray() {
|
||||
return defaultSelectDbArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this object is the root level object in its entity
|
||||
* inheritance.
|
||||
@@ -858,8 +837,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if there is L2 caching (Lucene or Bean cache) for this bean
|
||||
* type.
|
||||
* Return true if there is L2 bean caching for this bean type.
|
||||
*/
|
||||
public boolean isUsingL2Cache() {
|
||||
return isBeanCaching();
|
||||
@@ -2403,13 +2381,6 @@ public class BeanDescriptor<T> implements MetaBeanInfo {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T createJsonBean() {
|
||||
if (EntityType.XMLELEMENT.equals(entityType)) {
|
||||
try {
|
||||
return beanType.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return (T)createEntityBean();
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +106,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
private final BeanManagerFactory beanManagerFactory;
|
||||
|
||||
private int enhancedClassCount;
|
||||
private int subclassClassCount;
|
||||
private final HashSet<String> subclassedEntities = new HashSet<String>();
|
||||
|
||||
|
||||
private final boolean updateChangesOnly;
|
||||
|
||||
private final BootupClasses bootupClasses;
|
||||
@@ -447,26 +445,8 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
logger.debug("BeanPersistControllers[" + cc + "] BeanFinders[" + fc + "] BeanPersistListeners[" + lc + "] BeanQueryAdapters[" + qa + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Log Warning if mixing subclass and enhancement.
|
||||
* <p>
|
||||
* If enhancement is used for some classes it is expected to be used for all
|
||||
* and vice versa.
|
||||
* </p>
|
||||
*/
|
||||
private void logStatus() {
|
||||
|
||||
String msg = "Entities enhanced[" + enhancedClassCount + "] subclassed[" + subclassClassCount + "]";
|
||||
logger.info(msg);
|
||||
|
||||
if (enhancedClassCount > 0) {
|
||||
if (subclassClassCount > 0) {
|
||||
String subclassEntityNames = subclassedEntities.toString();
|
||||
|
||||
String m = "Mixing enhanced and subclassed entities. Subclassed classes:" + subclassEntityNames;
|
||||
logger.warn(m);
|
||||
}
|
||||
}
|
||||
logger.info("Entities enhanced[" + enhancedClassCount + "]");
|
||||
}
|
||||
|
||||
private <T> BeanDescriptor<T> createEmbedded(Class<T> beanClass) {
|
||||
@@ -1462,25 +1442,13 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
|
||||
private void checkEnhanced(DeployBeanDescriptor<?> desc, Class<?> beanClass) {
|
||||
// the bean already implements EntityBean
|
||||
checkInheritedClasses(true, beanClass);
|
||||
|
||||
desc.setFactoryType(beanClass);
|
||||
if (!beanClass.getName().startsWith("com.avaje.ebean.meta")) {
|
||||
enhancedClassCount++;
|
||||
}
|
||||
enhancedClassCount++;
|
||||
}
|
||||
|
||||
private void checkSubclass(DeployBeanDescriptor<?> desc, Class<?> beanClass) {
|
||||
|
||||
checkInheritedClasses(false, beanClass);
|
||||
desc.checkReadAndWriteMethods();
|
||||
|
||||
EntityType entityType = desc.getEntityType();
|
||||
if (EntityType.XMLELEMENT.equals(entityType)) {
|
||||
desc.setFactoryType(beanClass);
|
||||
|
||||
} else {
|
||||
throw new PersistenceException("Entity type "+beanClass+" is not an enhanced entity bean. Subclassing is not longer supported in Ebean");
|
||||
}
|
||||
throw new PersistenceException("Entity type "+beanClass+" is not an enhanced entity bean. Subclassing is not longer supported in Ebean");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1049,19 +1049,6 @@ public class BeanProperty implements ElPropertyValue {
|
||||
return value;
|
||||
}
|
||||
|
||||
// private ArrayList<LuceneIndex> luceneIndexes;
|
||||
//
|
||||
// public void registerLuceneIndex(LuceneIndex luceneIndex) {
|
||||
// if (luceneIndexes == null) {
|
||||
// luceneIndexes = new ArrayList<LuceneIndex>();
|
||||
// }
|
||||
// luceneIndexes.add(luceneIndex);
|
||||
// }
|
||||
//
|
||||
// public boolean isDeltaRequired() {
|
||||
// return true;//luceneIndexes != null;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return true if by default this property is set to fetch eager.
|
||||
* Lob's usually default to fetch lazy.
|
||||
|
||||
@@ -6,9 +6,6 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -21,172 +18,156 @@ import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
*/
|
||||
public interface IdBinder {
|
||||
|
||||
/**
|
||||
* Initialise the binder.
|
||||
*/
|
||||
public void initialise();
|
||||
|
||||
/**
|
||||
* Convert the Id value as a Lucene string term.
|
||||
*/
|
||||
public String writeTerm(Object idValue);
|
||||
/**
|
||||
* Initialise the binder.
|
||||
*/
|
||||
public void initialise();
|
||||
|
||||
/**
|
||||
* Convert the Lucene string term into an Id value.
|
||||
*/
|
||||
public Object readTerm(String idTermValue);
|
||||
/**
|
||||
* Write the Id value to binary DataOuput.
|
||||
*/
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException;
|
||||
|
||||
/**
|
||||
* Write the Id value to binary DataOuput.
|
||||
*/
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException;
|
||||
/**
|
||||
* Read the Id value from the binary DataInput.
|
||||
*/
|
||||
public Object readData(DataInput dataInput) throws IOException;
|
||||
|
||||
/**
|
||||
* Read the Id value from the binary DataInput.
|
||||
*/
|
||||
public Object readData(DataInput dataInput) throws IOException;
|
||||
/**
|
||||
* Return the name(s) of the Id property(s). Comma delimited if there is more
|
||||
* than one.
|
||||
* <p>
|
||||
* This can be used to include in a query.
|
||||
* </p>
|
||||
*/
|
||||
public String getIdProperty();
|
||||
|
||||
/**
|
||||
* Adds RDN's to the LdapName using the id value.
|
||||
*/
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException;
|
||||
/**
|
||||
* Find a BeanProperty that is mapped to the database column.
|
||||
*/
|
||||
public BeanProperty findBeanProperty(String dbColumnName);
|
||||
|
||||
/**
|
||||
* Adds RDN's to the LdapName using the id value from the bean.
|
||||
*/
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException;
|
||||
/**
|
||||
* Return the number of scalar properties for this id.
|
||||
*/
|
||||
public int getPropertyCount();
|
||||
|
||||
/**
|
||||
* Return the name(s) of the Id property(s).
|
||||
* Comma delimited if there is more than one.
|
||||
* <p>
|
||||
* This can be used to include in a query.
|
||||
* </p>
|
||||
*/
|
||||
public String getIdProperty();
|
||||
/**
|
||||
* Return false if the id is a simple scalar and false if it is embedded or
|
||||
* concatenated.
|
||||
*/
|
||||
public boolean isComplexId();
|
||||
|
||||
/**
|
||||
* Find a BeanProperty that is mapped to the database column.
|
||||
*/
|
||||
public BeanProperty findBeanProperty(String dbColumnName);
|
||||
|
||||
/**
|
||||
* Return the number of scalar properties for this id.
|
||||
*/
|
||||
public int getPropertyCount();
|
||||
|
||||
/**
|
||||
* Return false if the id is a simple scalar and false if it is embedded or concatenated.
|
||||
*/
|
||||
public boolean isComplexId();
|
||||
|
||||
/**
|
||||
* Return the default order by that may need to be used if the query includes a many property.
|
||||
*/
|
||||
public String getDefaultOrderBy();
|
||||
|
||||
public String getOrderBy(String pathPrefix, boolean ascending);
|
||||
|
||||
/**
|
||||
* Return the values as an array of scalar bindable values.
|
||||
* <p>
|
||||
* For concatenated keys that use an Embedded bean or multiple id properties
|
||||
* this determines the field values are returns them as an Object array.
|
||||
* </p>
|
||||
* <p>
|
||||
* Added primarily for Query.addWhere().add(Expr.idEq()) support.
|
||||
* </p>
|
||||
*/
|
||||
public Object[] getBindValues(Object idValue);
|
||||
|
||||
/**
|
||||
* Return the id values for a given bean.
|
||||
*/
|
||||
public Object[] getIdValues(Object bean);
|
||||
|
||||
/**
|
||||
* Build a string of the logical expressions.
|
||||
* <p>
|
||||
* Typically used to build a id = ? string.
|
||||
* </p>
|
||||
*/
|
||||
public String getAssocOneIdExpr(String prefix, String operator);
|
||||
|
||||
/**
|
||||
* Return the logical id in expression taking into account embedded id's.
|
||||
*/
|
||||
public String getAssocIdInExpr(String prefix);
|
||||
/**
|
||||
* Return the default order by that may need to be used if the query includes
|
||||
* a many property.
|
||||
*/
|
||||
public String getDefaultOrderBy();
|
||||
|
||||
/**
|
||||
* Binds an id value to a prepared statement.
|
||||
*/
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException;
|
||||
public String getOrderBy(String pathPrefix, boolean ascending);
|
||||
|
||||
/**
|
||||
* Bind the id value to a SqlUpdate statement.
|
||||
*/
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value);
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value);
|
||||
|
||||
/**
|
||||
* Return the sql for binding the id using an IN clause.
|
||||
*/
|
||||
public String getBindIdInSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Return the binding expression (like "?" or "(?,?)")for the Id.
|
||||
*/
|
||||
public String getIdInValueExpr(int size);
|
||||
|
||||
/**
|
||||
* Same as getIdInValueExpr but for delete by id.
|
||||
*/
|
||||
public String getIdInValueExprDelete(int size);
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain);
|
||||
|
||||
/**
|
||||
* Read the id value from the result set and set it to the bean also returning it.
|
||||
*/
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException;
|
||||
/**
|
||||
* Return the values as an array of scalar bindable values.
|
||||
* <p>
|
||||
* For concatenated keys that use an Embedded bean or multiple id properties
|
||||
* this determines the field values are returns them as an Object array.
|
||||
* </p>
|
||||
* <p>
|
||||
* Added primarily for Query.addWhere().add(Expr.idEq()) support.
|
||||
* </p>
|
||||
*/
|
||||
public Object[] getBindValues(Object idValue);
|
||||
|
||||
/**
|
||||
* Ignore the appropriate number of scalar properties for this id.
|
||||
*/
|
||||
public void loadIgnore(DbReadContext ctx);
|
||||
|
||||
/**
|
||||
* Read the id value from the result set and return it.
|
||||
*/
|
||||
public Object read(DbReadContext ctx) throws SQLException;
|
||||
/**
|
||||
* Return the id values for a given bean.
|
||||
*/
|
||||
public Object[] getIdValues(Object bean);
|
||||
|
||||
/**
|
||||
* Append to the select clause.
|
||||
*/
|
||||
public void appendSelect(DbSqlContext ctx, boolean subQuery);
|
||||
|
||||
/**
|
||||
* Return the sql for binding the id to. This includes table alias and columns that make up the id.
|
||||
*/
|
||||
public String getBindIdSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Return the id properties in flat form.
|
||||
*/
|
||||
public BeanProperty[] getProperties();
|
||||
|
||||
/**
|
||||
* Cast or convert the Id value if necessary and optionally set it.
|
||||
* <p>
|
||||
* The Id value is not assumed to be the correct type so it is converted to
|
||||
* the correct type. Typically this is because we could get a Integer, Long
|
||||
* or BigDecimal depending on the JDBC driver and situation.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the bean is not null, then the value is set to the bean.
|
||||
* </p>
|
||||
*/
|
||||
public Object convertSetId(Object idValue, Object bean);
|
||||
/**
|
||||
* Build a string of the logical expressions.
|
||||
* <p>
|
||||
* Typically used to build a id = ? string.
|
||||
* </p>
|
||||
*/
|
||||
public String getAssocOneIdExpr(String prefix, String operator);
|
||||
|
||||
/**
|
||||
* Return the logical id in expression taking into account embedded id's.
|
||||
*/
|
||||
public String getAssocIdInExpr(String prefix);
|
||||
|
||||
/**
|
||||
* Binds an id value to a prepared statement.
|
||||
*/
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException;
|
||||
|
||||
/**
|
||||
* Bind the id value to a SqlUpdate statement.
|
||||
*/
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value);
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value);
|
||||
|
||||
/**
|
||||
* Return the sql for binding the id using an IN clause.
|
||||
*/
|
||||
public String getBindIdInSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Return the binding expression (like "?" or "(?,?)")for the Id.
|
||||
*/
|
||||
public String getIdInValueExpr(int size);
|
||||
|
||||
/**
|
||||
* Same as getIdInValueExpr but for delete by id.
|
||||
*/
|
||||
public String getIdInValueExprDelete(int size);
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain);
|
||||
|
||||
/**
|
||||
* Read the id value from the result set and set it to the bean also returning
|
||||
* it.
|
||||
*/
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException;
|
||||
|
||||
/**
|
||||
* Ignore the appropriate number of scalar properties for this id.
|
||||
*/
|
||||
public void loadIgnore(DbReadContext ctx);
|
||||
|
||||
/**
|
||||
* Read the id value from the result set and return it.
|
||||
*/
|
||||
public Object read(DbReadContext ctx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Append to the select clause.
|
||||
*/
|
||||
public void appendSelect(DbSqlContext ctx, boolean subQuery);
|
||||
|
||||
/**
|
||||
* Return the sql for binding the id to. This includes table alias and columns
|
||||
* that make up the id.
|
||||
*/
|
||||
public String getBindIdSql(String baseTableAlias);
|
||||
|
||||
/**
|
||||
* Return the id properties in flat form.
|
||||
*/
|
||||
public BeanProperty[] getProperties();
|
||||
|
||||
/**
|
||||
* Cast or convert the Id value if necessary and optionally set it.
|
||||
* <p>
|
||||
* The Id value is not assumed to be the correct type so it is converted to
|
||||
* the correct type. Typically this is because we could get a Integer, Long or
|
||||
* BigDecimal depending on the JDBC driver and situation.
|
||||
* </p>
|
||||
* <p>
|
||||
* If the bean is not null, then the value is set to the bean.
|
||||
* </p>
|
||||
*/
|
||||
public Object convertSetId(Object idValue, Object bean);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,6 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
@@ -99,23 +94,6 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getValue(id);
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
Object id = embIdProperty.getValue(bean);
|
||||
createLdapNameById(name, id);
|
||||
}
|
||||
|
||||
public BeanDescriptor<?> getIdBeanDescriptor() {
|
||||
return idDesc;
|
||||
}
|
||||
@@ -228,42 +206,6 @@ public final class IdBinderEmbedded implements IdBinder {
|
||||
return idInValueSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the lucene string term value into embedded id.
|
||||
*/
|
||||
public Object readTerm(String idTermValue) {
|
||||
|
||||
String[] split = idTermValue.split("|");
|
||||
if (split.length != props.length){
|
||||
String msg = "Failed to split ["+idTermValue+"] using | for id.";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
Object embId = idDesc.createBean();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getScalarType().parse(split[i]);
|
||||
props[i].setValue(embId, v);
|
||||
}
|
||||
return embId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the embedded id as a Lucene string term value.
|
||||
*/
|
||||
public String writeTerm(Object idValue) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getValue(idValue);
|
||||
String formatValue = props[i].getScalarType().format(v);
|
||||
if (i > 0){
|
||||
sb.append("|");
|
||||
}
|
||||
sb.append(formatValue);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean) {
|
||||
bean = embIdProperty.getValue(bean);
|
||||
Object[] bindvalues = new Object[props.length];
|
||||
|
||||
@@ -6,9 +6,6 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanProperty;
|
||||
@@ -21,132 +18,118 @@ import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
*/
|
||||
public final class IdBinderEmpty implements IdBinder {
|
||||
|
||||
private static final String bindIdSql = "";
|
||||
|
||||
private static final BeanProperty[] properties = new BeanProperty[0];
|
||||
|
||||
public IdBinderEmpty() {
|
||||
private static final String bindIdSql = "";
|
||||
|
||||
}
|
||||
public void initialise(){
|
||||
|
||||
}
|
||||
|
||||
public Object readTerm(String idTermValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String writeTerm(Object idValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getOrderBy(String pathPrefix, boolean ascending){
|
||||
return pathPrefix;
|
||||
}
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getIdProperty() {
|
||||
return null;
|
||||
}
|
||||
private static final BeanProperty[] properties = new BeanProperty[0];
|
||||
|
||||
public BeanProperty findBeanProperty(String dbColumnName) {
|
||||
return null;
|
||||
}
|
||||
public boolean isComplexId(){
|
||||
return true;
|
||||
}
|
||||
public IdBinderEmpty() {
|
||||
|
||||
}
|
||||
|
||||
public String getDefaultOrderBy() {
|
||||
// this should never happen?
|
||||
return "";
|
||||
}
|
||||
|
||||
public BeanProperty[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
public void initialise() {
|
||||
|
||||
public String getBindIdSql(String baseTableAlias) {
|
||||
return bindIdSql;
|
||||
}
|
||||
|
||||
public String getAssocOneIdExpr(String prefix, String operator){
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getAssocIdInExpr(String prefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value) {
|
||||
|
||||
}
|
||||
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
return getIdInValueExpr(size);
|
||||
}
|
||||
|
||||
public String getIdInValueExpr(int size) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getBindIdInSql(String baseTableAlias) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean){
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getBindValues(Object idValue){
|
||||
return new Object[]{idValue};
|
||||
}
|
||||
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value) {
|
||||
|
||||
}
|
||||
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
public void loadIgnore(DbReadContext ctx) {
|
||||
}
|
||||
public String getOrderBy(String pathPrefix, boolean ascending) {
|
||||
return pathPrefix;
|
||||
}
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getIdProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public BeanProperty findBeanProperty(String dbColumnName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isComplexId() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getDefaultOrderBy() {
|
||||
// this should never happen?
|
||||
return "";
|
||||
}
|
||||
|
||||
public BeanProperty[] getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public String getBindIdSql(String baseTableAlias) {
|
||||
return bindIdSql;
|
||||
}
|
||||
|
||||
public String getAssocOneIdExpr(String prefix, String operator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getAssocIdInExpr(String prefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addIdInBindValue(SpiExpressionRequest request, Object value) {
|
||||
|
||||
}
|
||||
|
||||
public String getIdInValueExprDelete(int size) {
|
||||
return getIdInValueExpr(size);
|
||||
}
|
||||
|
||||
public String getIdInValueExpr(int size) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getBindIdInSql(String baseTableAlias) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getIdValues(Object bean) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] getBindValues(Object idValue) {
|
||||
return new Object[] { idValue };
|
||||
}
|
||||
|
||||
public void bindId(DefaultSqlUpdate sqlUpdate, Object value) {
|
||||
|
||||
}
|
||||
|
||||
public void bindId(DataBind dataBind, Object value) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
public void loadIgnore(DbReadContext ctx) {
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object read(DbReadContext ctx) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void appendSelect(DbSqlContext ctx, boolean subQuery) {
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean) {
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataOutput) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
public Object readSet(DbReadContext ctx, Object bean) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object read(DbReadContext ctx) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void appendSelect(DbSqlContext ctx, boolean subQuery) {
|
||||
}
|
||||
|
||||
public Object convertSetId(Object idValue, Object bean){
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataOutput) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void writeData(DataOutput dataOutput, Object idValue) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
@@ -83,24 +80,6 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
|
||||
if (id instanceof Map<?,?> == false){
|
||||
throw new RuntimeException("Expecting a Map for concatinated key");
|
||||
}
|
||||
|
||||
Map<?,?> mapId = (Map<?,?>)id;
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
Object v = mapId.get(props[i].getName());
|
||||
if (v == null){
|
||||
throw new RuntimeException("No value in Map for key "+props[i].getName());
|
||||
}
|
||||
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildSelectExpressionChain(String prefix, List<String> selectChain) {
|
||||
|
||||
@@ -109,19 +88,11 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
Object v = props[i].getValue(bean);
|
||||
Rdn rdn = new Rdn(props[i].getDbColumn(), v);
|
||||
name.add(rdn);
|
||||
}
|
||||
}
|
||||
|
||||
public int getPropertyCount() {
|
||||
return props.length;
|
||||
}
|
||||
public int getPropertyCount() {
|
||||
return props.length;
|
||||
}
|
||||
|
||||
public String getIdProperty() {
|
||||
return idProperties;
|
||||
@@ -229,40 +200,6 @@ public final class IdBinderMultiple implements IdBinder {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object readTerm(String idTermValue) {
|
||||
|
||||
String[] split = idTermValue.split("|");
|
||||
if (split.length != props.length){
|
||||
String msg = "Failed to split ["+idTermValue+"] using | for id.";
|
||||
throw new PersistenceException(msg);
|
||||
}
|
||||
Map<String, Object> uidMap = new LinkedHashMap<String, Object>();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = props[i].getScalarType().parse(split[i]);
|
||||
uidMap.put(props[i].getName(), v);
|
||||
}
|
||||
return uidMap;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public String writeTerm(Object idValue) {
|
||||
|
||||
Map<String, ?> uidMap = (Map<String, ?>) idValue;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
Object v = uidMap.get(props[i].getName());
|
||||
String formatValue = props[i].getScalarType().format(v);
|
||||
if (i > 0){
|
||||
sb.append("|");
|
||||
}
|
||||
sb.append(formatValue);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Object readData(DataInput dataInput) throws IOException {
|
||||
|
||||
LinkedHashMap<String,Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
@@ -6,10 +6,6 @@ import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.core.DefaultSqlUpdate;
|
||||
import com.avaje.ebeaninternal.server.core.InternString;
|
||||
@@ -48,14 +44,6 @@ public final class IdBinderSimple implements IdBinder {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public Object readTerm(String idTermValue) {
|
||||
return scalarType.parse(idTermValue);
|
||||
}
|
||||
|
||||
public String writeTerm(Object idValue) {
|
||||
return scalarType.format(idValue);
|
||||
}
|
||||
|
||||
public String getOrderBy(String pathPrefix, boolean ascending){
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -73,16 +61,6 @@ public final class IdBinderSimple implements IdBinder {
|
||||
|
||||
idProperty.buildSelectExpressionChain(prefix, selectChain);
|
||||
}
|
||||
|
||||
public void createLdapNameById(LdapName name, Object id) throws InvalidNameException {
|
||||
Rdn rdn = new Rdn(idProperty.getDbColumn(), id);
|
||||
name.add(rdn);
|
||||
}
|
||||
|
||||
public void createLdapNameByBean(LdapName name, Object bean) throws InvalidNameException {
|
||||
Object id = idProperty.getValue(bean);
|
||||
createLdapNameById(name, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 1.
|
||||
|
||||
@@ -13,7 +13,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebean.annotation.ConcurrencyMode;
|
||||
import com.avaje.ebean.config.TableName;
|
||||
import com.avaje.ebean.config.dbplatform.IdGenerator;
|
||||
@@ -22,7 +24,6 @@ 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.meta.MetaAutoFetchStatistic;
|
||||
import com.avaje.ebeaninternal.server.core.CacheOptions;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor.EntityType;
|
||||
import com.avaje.ebeaninternal.server.deploy.ChainedBeanPersistController;
|
||||
@@ -34,8 +35,6 @@ import com.avaje.ebeaninternal.server.deploy.DeployNamedQuery;
|
||||
import com.avaje.ebeaninternal.server.deploy.DeployNamedUpdate;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.ebeaninternal.server.reflect.BeanReflect;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Describes Beans including their deployment information.
|
||||
@@ -58,8 +57,6 @@ public class DeployBeanDescriptor<T> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(DeployBeanDescriptor.class);
|
||||
|
||||
private static final String META_BEAN_PREFIX = MetaAutoFetchStatistic.class.getName().substring(0, 20);
|
||||
|
||||
/**
|
||||
* Map of BeanProperty Linked so as to preserve order.
|
||||
*/
|
||||
@@ -151,8 +148,6 @@ public class DeployBeanDescriptor<T> {
|
||||
*/
|
||||
private BeanFinder<T> beanFinder;
|
||||
|
||||
private UseIndex useIndex;
|
||||
|
||||
/**
|
||||
* The table joins for this bean. Server side only.
|
||||
*/
|
||||
@@ -181,20 +176,6 @@ public class DeployBeanDescriptor<T> {
|
||||
return Modifier.isAbstract(beanType.getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default UseIndex strategy.
|
||||
*/
|
||||
public UseIndex getUseIndex() {
|
||||
return useIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default UseIndex strategy.
|
||||
*/
|
||||
public void setUseIndex(UseIndex useIndex) {
|
||||
this.useIndex = useIndex;
|
||||
}
|
||||
|
||||
public boolean isScalaObject() {
|
||||
Class<?>[] interfaces = beanType.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
@@ -247,9 +228,6 @@ public class DeployBeanDescriptor<T> {
|
||||
*/
|
||||
public boolean checkReadAndWriteMethods() {
|
||||
|
||||
if (isMeta()) {
|
||||
return true;
|
||||
}
|
||||
boolean missingMethods = false;
|
||||
|
||||
Iterator<DeployBeanProperty> it = propMap.values().iterator();
|
||||
@@ -289,22 +267,11 @@ public class DeployBeanDescriptor<T> {
|
||||
|
||||
public EntityType getEntityType() {
|
||||
if (entityType == null) {
|
||||
entityType = isMeta() ? EntityType.META : EntityType.ORM;
|
||||
entityType = EntityType.ORM;
|
||||
}
|
||||
return entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this is a Meta entity bean.
|
||||
* <p>
|
||||
* The Meta entity beans are not based on real tables but get meta information
|
||||
* from memory such as all the entity bean meta data.
|
||||
* </p>
|
||||
*/
|
||||
private boolean isMeta() {
|
||||
return beanType.getName().startsWith(META_BEAN_PREFIX);
|
||||
}
|
||||
|
||||
public void add(DRawSqlMeta rawSqlMeta) {
|
||||
rawSqlMetas.put(rawSqlMeta.getName(), rawSqlMeta);
|
||||
if ("default".equals(rawSqlMeta.getName())) {
|
||||
@@ -788,26 +755,6 @@ public class DeployBeanDescriptor<T> {
|
||||
return selectClause.substring(0, selectClause.length() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an Array of properties to include in default fetch (for LDAP).
|
||||
*/
|
||||
public String[] getDefaultSelectDbArray(Set<String> defaultSelect) {
|
||||
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
for (DeployBeanProperty p : propMap.values()) {
|
||||
if (defaultSelect != null) {
|
||||
if (defaultSelect.contains(p.getName())) {
|
||||
// properties in defaultSelect
|
||||
list.add(p.getDbColumn());
|
||||
}
|
||||
} else if (!p.isTransient() && p.isDbRead()) {
|
||||
// non transient db properties
|
||||
list.add(p.getDbColumn());
|
||||
}
|
||||
}
|
||||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the include separating by comma or semicolon.
|
||||
*/
|
||||
|
||||
@@ -6,10 +6,7 @@ import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import com.avaje.ebean.annotation.CacheStrategy;
|
||||
import com.avaje.ebean.annotation.EntityConcurrencyMode;
|
||||
import com.avaje.ebean.annotation.NamedUpdate;
|
||||
@@ -54,18 +51,6 @@ public class AnnotationClass extends AnnotationParser {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isXmlElement(Class<?> cls) {
|
||||
XmlRootElement rootElement = cls.getAnnotation(XmlRootElement.class);
|
||||
if (rootElement != null) {
|
||||
return true;
|
||||
}
|
||||
XmlType xmlType = cls.getAnnotation(XmlType.class);
|
||||
if (xmlType != null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void read(Class<?> cls) {
|
||||
|
||||
Entity entity = cls.getAnnotation(Entity.class);
|
||||
@@ -77,9 +62,6 @@ public class AnnotationClass extends AnnotationParser {
|
||||
} else {
|
||||
descriptor.setName(entity.name());
|
||||
}
|
||||
} else if (isXmlElement(cls)) {
|
||||
descriptor.setName(cls.getSimpleName());
|
||||
descriptor.setEntityType(EntityType.XMLELEMENT);
|
||||
}
|
||||
|
||||
Embeddable embeddable = cls.getAnnotation(Embeddable.class);
|
||||
@@ -152,11 +134,6 @@ public class AnnotationClass extends AnnotationParser {
|
||||
cacheOptions.setNaturalKey(propName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UseIndex.DEFAULT.equals(cacheStrategy.useIndex())) {
|
||||
// a specific text index strategy has been defined
|
||||
descriptor.setUseIndex(cacheStrategy.useIndex());
|
||||
}
|
||||
}
|
||||
|
||||
private void readNamedQueries(NamedQueries namedQueries) {
|
||||
|
||||
@@ -14,51 +14,39 @@ import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
*/
|
||||
public abstract class AbstractExpression implements SpiExpression {
|
||||
|
||||
private static final long serialVersionUID = 4072786211853856174L;
|
||||
|
||||
protected final String propName;
|
||||
|
||||
protected final FilterExprPath pathPrefix;
|
||||
|
||||
protected AbstractExpression(FilterExprPath pathPrefix, String propName) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
this.propName = propName;
|
||||
}
|
||||
private static final long serialVersionUID = 4072786211853856174L;
|
||||
|
||||
public String getPropertyName() {
|
||||
if (pathPrefix == null){
|
||||
return propName;
|
||||
} else {
|
||||
String path = pathPrefix.getPath();
|
||||
if (path == null || path.length() == 0){
|
||||
return propName;
|
||||
} else {
|
||||
return path+"."+propName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
|
||||
protected final String propName;
|
||||
|
||||
String propertyName = getPropertyName();
|
||||
if (propertyName != null){
|
||||
ElPropertyDeploy elProp = desc.getElPropertyDeploy(propertyName);
|
||||
if (elProp != null) {
|
||||
if (elProp.containsFormulaWithJoin()) {
|
||||
// for findRowCount query select clause
|
||||
manyWhereJoin.addFormulaWithJoin(propertyName);
|
||||
}
|
||||
if (elProp.containsMany()){
|
||||
// for findRowCount we join to a many property
|
||||
protected AbstractExpression(String propName) {
|
||||
this.propName = propName;
|
||||
}
|
||||
|
||||
public String getPropertyName() {
|
||||
return propName;
|
||||
}
|
||||
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
|
||||
|
||||
String propertyName = getPropertyName();
|
||||
if (propertyName != null) {
|
||||
ElPropertyDeploy elProp = desc.getElPropertyDeploy(propertyName);
|
||||
if (elProp != null) {
|
||||
if (elProp.containsFormulaWithJoin()) {
|
||||
// for findRowCount query select clause
|
||||
manyWhereJoin.addFormulaWithJoin(propertyName);
|
||||
}
|
||||
if (elProp.containsMany()) {
|
||||
// for findRowCount we join to a many property
|
||||
manyWhereJoin.add(elProp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ElPropertyValue getElProp(SpiExpressionRequest request) {
|
||||
|
||||
String propertyName = getPropertyName();
|
||||
return request.getBeanDescriptor().getElGetValue(propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ElPropertyValue getElProp(SpiExpressionRequest request) {
|
||||
|
||||
String propertyName = getPropertyName();
|
||||
return request.getBeanDescriptor().getElGetValue(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,24 +20,12 @@ class AllEqualsExpression implements SpiExpression {
|
||||
|
||||
private final Map<String, Object> propMap;
|
||||
|
||||
private final FilterExprPath pathPrefix;
|
||||
|
||||
AllEqualsExpression(FilterExprPath pathPrefix, Map<String, Object> propMap) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
AllEqualsExpression(Map<String, Object> propMap) {
|
||||
this.propMap = propMap;
|
||||
}
|
||||
|
||||
protected String name(String propName) {
|
||||
if (pathPrefix == null) {
|
||||
return propName;
|
||||
} else {
|
||||
String path = pathPrefix.getPath();
|
||||
if (path == null || path.length() == 0) {
|
||||
return propName;
|
||||
} else {
|
||||
return path + "." + propName;
|
||||
}
|
||||
}
|
||||
return propName;
|
||||
}
|
||||
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
|
||||
|
||||
@@ -15,8 +15,8 @@ class BetweenExpression extends AbstractExpression {
|
||||
|
||||
private final Object valueLow;
|
||||
|
||||
BetweenExpression(FilterExprPath pathPrefix, String propertyName, Object valLo, Object valHigh) {
|
||||
super(pathPrefix, propertyName);
|
||||
BetweenExpression(String propertyName, Object valLo, Object valHigh) {
|
||||
super(propertyName);
|
||||
this.valueLow = valLo;
|
||||
this.valueHigh = valHigh;
|
||||
}
|
||||
|
||||
+2
-15
@@ -10,8 +10,6 @@ import com.avaje.ebeaninternal.server.el.ElPropertyDeploy;
|
||||
|
||||
/**
|
||||
* Between expression where a value is between two properties.
|
||||
*
|
||||
* @author rbygrave
|
||||
*/
|
||||
class BetweenPropertyExpression implements SpiExpression {
|
||||
|
||||
@@ -19,29 +17,18 @@ class BetweenPropertyExpression implements SpiExpression {
|
||||
|
||||
private static final String BETWEEN = " between ";
|
||||
|
||||
private final FilterExprPath pathPrefix;
|
||||
private final String lowProperty;
|
||||
private final String highProperty;
|
||||
private final Object value;
|
||||
|
||||
BetweenPropertyExpression(FilterExprPath pathPrefix, String lowProperty, String highProperty, Object value) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
BetweenPropertyExpression(String lowProperty, String highProperty, Object value) {
|
||||
this.lowProperty = lowProperty;
|
||||
this.highProperty = highProperty;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
protected String name(String propName) {
|
||||
if (pathPrefix == null) {
|
||||
return propName;
|
||||
} else {
|
||||
String path = pathPrefix.getPath();
|
||||
if (path == null || path.length() == 0) {
|
||||
return propName;
|
||||
} else {
|
||||
return path + "." + propName;
|
||||
}
|
||||
}
|
||||
return propName;
|
||||
}
|
||||
|
||||
public void containsMany(BeanDescriptor<?> desc, ManyWhereJoins manyWhereJoin) {
|
||||
|
||||
+2
-2
@@ -11,8 +11,8 @@ class CaseInsensitiveEqualExpression extends AbstractExpression {
|
||||
|
||||
private final String value;
|
||||
|
||||
CaseInsensitiveEqualExpression(FilterExprPath pathPrefix, String propertyName, String value) {
|
||||
super(pathPrefix, propertyName);
|
||||
CaseInsensitiveEqualExpression(String propertyName, String value) {
|
||||
super(propertyName);
|
||||
this.value = value.toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
+3
-6
@@ -66,8 +66,6 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
*/
|
||||
private ArrayList<SpiExpression> list;
|
||||
|
||||
private final FilterExprPath pathPrefix;
|
||||
|
||||
/**
|
||||
* Construct the query by example expression.
|
||||
*
|
||||
@@ -78,8 +76,7 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
* @param likeType
|
||||
* the type of Like wild card used
|
||||
*/
|
||||
public DefaultExampleExpression(FilterExprPath pathPrefix, Object entity, boolean caseInsensitive, LikeType likeType) {
|
||||
this.pathPrefix = pathPrefix;
|
||||
public DefaultExampleExpression(Object entity, boolean caseInsensitive, LikeType likeType) {
|
||||
this.entity = entity;
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
this.likeType = likeType;
|
||||
@@ -217,13 +214,13 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
|
||||
if (beanProperty.isScalar() && value != null) {
|
||||
if (value instanceof String) {
|
||||
list.add(new LikeExpression(pathPrefix, propName, (String) value, caseInsensitive, likeType));
|
||||
list.add(new LikeExpression(propName, (String) value, caseInsensitive, likeType));
|
||||
} else {
|
||||
if (!includeZeros && isZero(value)) {
|
||||
// exclude the zero values typically to weed out
|
||||
// primitive int and long that initialise to 0
|
||||
} else {
|
||||
list.add(new SimpleExpression(pathPrefix, propName, SimpleExpression.Op.EQ, value));
|
||||
list.add(new SimpleExpression(propName, SimpleExpression.Op.EQ, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
-35
@@ -21,19 +21,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
|
||||
private static final Object[] EMPTY_ARRAY = new Object[] {};
|
||||
|
||||
private final FilterExprPath prefix = null;
|
||||
|
||||
public DefaultExpressionFactory() {
|
||||
//this();//null);
|
||||
}
|
||||
|
||||
// public DefaultExpressionFactory(FilterExprPath prefix) {
|
||||
// this.prefix = prefix;
|
||||
// }
|
||||
|
||||
public ExpressionFactory createExpressionFactory(){//FilterExprPath prefix) {
|
||||
public ExpressionFactory createExpressionFactory(){
|
||||
return this;
|
||||
//return new DefaultExpressionFactory(prefix);
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
@@ -47,7 +39,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
if (value == null) {
|
||||
return isNull(propertyName);
|
||||
}
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.EQ, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +49,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
if (value == null) {
|
||||
return isNotNull(propertyName);
|
||||
}
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.NOT_EQ, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.NOT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +60,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
if (value == null) {
|
||||
return isNull(propertyName);
|
||||
}
|
||||
return new CaseInsensitiveEqualExpression(prefix, propertyName, value);
|
||||
return new CaseInsensitiveEqualExpression(propertyName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +68,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression between(String propertyName, Object value1, Object value2) {
|
||||
|
||||
return new BetweenExpression(prefix, propertyName, value1, value2);
|
||||
return new BetweenExpression(propertyName, value1, value2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +76,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression betweenProperties(String lowProperty, String highProperty, Object value) {
|
||||
|
||||
return new BetweenPropertyExpression(prefix, lowProperty, highProperty, value);
|
||||
return new BetweenPropertyExpression(lowProperty, highProperty, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +84,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression gt(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.GT, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.GT, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +93,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression ge(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.GT_EQ, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.GT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +101,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression lt(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.LT, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.LT, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,7 +109,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression le(String propertyName, Object value) {
|
||||
|
||||
return new SimpleExpression(prefix, propertyName, SimpleExpression.Op.LT_EQ, value);
|
||||
return new SimpleExpression(propertyName, SimpleExpression.Op.LT_EQ, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +117,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression isNull(String propertyName) {
|
||||
|
||||
return new NullExpression(prefix, propertyName, false);
|
||||
return new NullExpression(propertyName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,14 +125,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
*/
|
||||
public Expression isNotNull(String propertyName) {
|
||||
|
||||
return new NullExpression(prefix, propertyName, true);
|
||||
return new NullExpression(propertyName, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Case insensitive {@link #exampleLike(Object)}
|
||||
*/
|
||||
public ExampleExpression iexampleLike(Object example) {
|
||||
return new DefaultExampleExpression(prefix, example, true, LikeType.RAW);
|
||||
return new DefaultExampleExpression(example, true, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,14 +140,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* LikeType.RAW (you need to add you own wildcards % and _).
|
||||
*/
|
||||
public ExampleExpression exampleLike(Object example) {
|
||||
return new DefaultExampleExpression(prefix, example, false, LikeType.RAW);
|
||||
return new DefaultExampleExpression(example, false, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the query by Example expression specifying more options.
|
||||
*/
|
||||
public ExampleExpression exampleLike(Object example, boolean caseInsensitive, LikeType likeType) {
|
||||
return new DefaultExampleExpression(prefix, example, caseInsensitive, likeType);
|
||||
return new DefaultExampleExpression(example, caseInsensitive, likeType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +155,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* characters % (percentage) and _ (underscore).
|
||||
*/
|
||||
public Expression like(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, false, LikeType.RAW);
|
||||
return new LikeExpression(propertyName, value, false, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,14 +164,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* a lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public Expression ilike(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, true, LikeType.RAW);
|
||||
return new LikeExpression(propertyName, value, true, LikeType.RAW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts With - property like value%.
|
||||
*/
|
||||
public Expression startsWith(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, false, LikeType.STARTS_WITH);
|
||||
return new LikeExpression(propertyName, value, false, LikeType.STARTS_WITH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,14 +179,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public Expression istartsWith(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, true, LikeType.STARTS_WITH);
|
||||
return new LikeExpression(propertyName, value, true, LikeType.STARTS_WITH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends With - property like %value.
|
||||
*/
|
||||
public Expression endsWith(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, false, LikeType.ENDS_WITH);
|
||||
return new LikeExpression(propertyName, value, false, LikeType.ENDS_WITH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,14 +194,14 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public Expression iendsWith(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, true, LikeType.ENDS_WITH);
|
||||
return new LikeExpression(propertyName, value, true, LikeType.ENDS_WITH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains - property like %value%.
|
||||
*/
|
||||
public Expression contains(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, false, LikeType.CONTAINS);
|
||||
return new LikeExpression(propertyName, value, false, LikeType.CONTAINS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,28 +209,28 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* function to make the expression case insensitive.
|
||||
*/
|
||||
public Expression icontains(String propertyName, String value) {
|
||||
return new LikeExpression(prefix, propertyName, value, true, LikeType.CONTAINS);
|
||||
return new LikeExpression(propertyName, value, true, LikeType.CONTAINS);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the array of values.
|
||||
*/
|
||||
public Expression in(String propertyName, Object[] values) {
|
||||
return new InExpression(prefix, propertyName, values);
|
||||
return new InExpression(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - using a subQuery.
|
||||
*/
|
||||
public Expression in(String propertyName, Query<?> subQuery) {
|
||||
return new InQueryExpression(prefix, propertyName, (SpiQuery<?>) subQuery);
|
||||
return new InQueryExpression(propertyName, (SpiQuery<?>) subQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* In - property has a value in the collection of values.
|
||||
*/
|
||||
public Expression in(String propertyName, Collection<?> values) {
|
||||
return new InExpression(prefix, propertyName, values);
|
||||
return new InExpression(propertyName, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,7 +261,7 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* a map keyed by property names.
|
||||
*/
|
||||
public Expression allEq(Map<String, Object> propertyMap) {
|
||||
return new AllEqualsExpression(prefix, propertyMap);
|
||||
return new AllEqualsExpression(propertyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,13 +13,13 @@ class InExpression extends AbstractExpression {
|
||||
|
||||
private final Object[] values;
|
||||
|
||||
InExpression(FilterExprPath pathPrefix, String propertyName, Collection<?> coll) {
|
||||
super(pathPrefix, propertyName);
|
||||
InExpression(String propertyName, Collection<?> coll) {
|
||||
super(propertyName);
|
||||
values = coll.toArray(new Object[coll.size()]);
|
||||
}
|
||||
|
||||
InExpression(FilterExprPath pathPrefix, String propertyName, Object[] array) {
|
||||
super(pathPrefix, propertyName);
|
||||
InExpression(String propertyName, Object[] array) {
|
||||
super(propertyName);
|
||||
this.values = array;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class InQueryExpression extends AbstractExpression {
|
||||
|
||||
private transient CQuery<?> compiledSubQuery;
|
||||
|
||||
public InQueryExpression(FilterExprPath pathPrefix, String propertyName, SpiQuery<?> subQuery) {
|
||||
super(pathPrefix, propertyName);
|
||||
public InQueryExpression(String propertyName, SpiQuery<?> subQuery) {
|
||||
super(propertyName);
|
||||
this.subQuery = subQuery;
|
||||
}
|
||||
|
||||
|
||||
@@ -383,6 +383,7 @@ abstract class JunctionExpression<T> implements Junction<T>, SpiExpression, Expr
|
||||
return exprList.setFirstRow(firstRow);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public com.avaje.ebean.Query<T> setListener(QueryListener<T> queryListener) {
|
||||
return exprList.setListener(queryListener);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ class LikeExpression extends AbstractExpression {
|
||||
|
||||
private final LikeType type;
|
||||
|
||||
LikeExpression(FilterExprPath pathPrefix, String propertyName, String value, boolean caseInsensitive, LikeType type) {
|
||||
super(pathPrefix, propertyName);
|
||||
LikeExpression(String propertyName, String value, boolean caseInsensitive, LikeType type) {
|
||||
super(propertyName);
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
this.type = type;
|
||||
this.val = value;
|
||||
|
||||
@@ -43,7 +43,8 @@ final class NotExpression implements SpiExpression {
|
||||
}
|
||||
|
||||
public void queryPlanHash(BeanQueryRequest<?> request, HashQueryPlanBuilder builder) {
|
||||
queryAutoFetchHash(builder);
|
||||
builder.add(NotExpression.class);
|
||||
exp.queryPlanHash(request, builder);
|
||||
}
|
||||
|
||||
public int queryBindHash() {
|
||||
|
||||
@@ -15,8 +15,8 @@ class NullExpression extends AbstractExpression {
|
||||
|
||||
private final boolean notNull;
|
||||
|
||||
NullExpression(FilterExprPath pathPrefix, String propertyName, boolean notNull) {
|
||||
super(pathPrefix, propertyName);
|
||||
NullExpression(String propertyName, boolean notNull) {
|
||||
super(propertyName);
|
||||
this.notNull = notNull;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ public class SimpleExpression extends AbstractExpression {
|
||||
|
||||
private final Object value;
|
||||
|
||||
public SimpleExpression(FilterExprPath pathPrefix, String propertyName, Op type, Object value) {
|
||||
super(pathPrefix, propertyName);
|
||||
public SimpleExpression(String propertyName, Op type, Object value) {
|
||||
super(propertyName);
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -597,12 +597,35 @@ public class DataSourcePool implements DataSource {
|
||||
*/
|
||||
protected void returnConnection(PooledConnection pooledConnection) {
|
||||
|
||||
if (poolListener != null) {
|
||||
poolListener.onBeforeReturnConnection(pooledConnection);
|
||||
}
|
||||
queue.returnPooledConnection(pooledConnection);
|
||||
// return a normal 'good' connection
|
||||
returnTheConnection(pooledConnection, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a bad connection and must be removed from the pool's busy list and fully closed.
|
||||
*/
|
||||
protected void returnConnectionForceClose(PooledConnection pooledConnection) {
|
||||
|
||||
returnTheConnection(pooledConnection, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return connection. If forceClose is true then this is a bad connection that
|
||||
* must be removed and closed fully.
|
||||
*/
|
||||
private void returnTheConnection(PooledConnection pooledConnection, boolean forceClose) {
|
||||
|
||||
if (poolListener != null && !forceClose) {
|
||||
poolListener.onBeforeReturnConnection(pooledConnection);
|
||||
}
|
||||
queue.returnPooledConnection(pooledConnection, forceClose);
|
||||
|
||||
if (forceClose) {
|
||||
// Got a bad connection so check the pool
|
||||
checkDataSource();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect statistics of a connection that is fully closing
|
||||
*/
|
||||
|
||||
@@ -508,9 +508,8 @@ public class PooledConnection extends ConnectionDelegator {
|
||||
|
||||
if (hadErrors) {
|
||||
if (!pool.validateConnection(this)) {
|
||||
// the connection is BAD, close it and test the pool
|
||||
closeConnectionFully(false);
|
||||
pool.checkDataSource();
|
||||
// the connection is BAD, remove it, close it and test the pool
|
||||
pool.returnConnectionForceClose(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -535,10 +534,9 @@ public class PooledConnection extends ConnectionDelegator {
|
||||
pool.returnConnection(this);
|
||||
|
||||
} catch (Exception ex) {
|
||||
// the connection is BAD, close it and test the pool
|
||||
// the connection is BAD, remove it, close it and test the pool
|
||||
logger.warn("Error when trying to return connection to pool, closing fully.", ex);
|
||||
closeConnectionFully(false);
|
||||
pool.checkDataSource();
|
||||
pool.returnConnectionForceClose(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ public class PooledConnectionQueue {
|
||||
/**
|
||||
* Return a PooledConnection.
|
||||
*/
|
||||
protected void returnPooledConnection(PooledConnection c) {
|
||||
protected void returnPooledConnection(PooledConnection c, boolean forceClose) {
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
lock.lock();
|
||||
@@ -246,7 +246,7 @@ public class PooledConnectionQueue {
|
||||
if (!busyList.remove(c)) {
|
||||
logger.error("Connection [{}] not found in BusyList? ", c);
|
||||
}
|
||||
if (c.shouldTrimOnReturn(lastResetTime, maxAgeMillis)) {
|
||||
if (forceClose || c.shouldTrimOnReturn(lastResetTime, maxAgeMillis)) {
|
||||
c.closeConnectionFully(false);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -72,17 +72,11 @@ public final class DefaultPersister implements Persister {
|
||||
|
||||
private final BeanDescriptorManager beanDescriptorManager;
|
||||
|
||||
// private final boolean defaultUpdateNullProperties;
|
||||
// private final boolean defaultDeleteMissingChildren;
|
||||
|
||||
public DefaultPersister(SpiEbeanServer server, Binder binder, BeanDescriptorManager descMgr, PstmtBatch pstmtBatch) {
|
||||
|
||||
this.server = server;
|
||||
this.beanDescriptorManager = descMgr;
|
||||
this.persistExecute = new DefaultPersistExecute(binder, pstmtBatch);
|
||||
|
||||
// this.defaultUpdateNullProperties = server.isDefaultUpdateNullProperties();
|
||||
// this.defaultDeleteMissingChildren = server.isDefaultDeleteMissingChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -508,7 +502,7 @@ public final class DefaultPersister implements Persister {
|
||||
SqlUpdate sqlDelete = manys[i].deleteByParentId(id, idList);
|
||||
executeSqlUpdate(sqlDelete, t);
|
||||
} else {
|
||||
// we need to fetch the Id's to delete (recurse or notify L2 cache/lucene)
|
||||
// we need to fetch the Id's to delete (recurse or notify L2 cache)
|
||||
List<Object> childIds = manys[i].findIdsByParentId(id, idList, t, null);
|
||||
if (!childIds.isEmpty()) {
|
||||
delete(targetDesc, null, childIds, t);
|
||||
@@ -770,7 +764,14 @@ public final class DefaultPersister implements Persister {
|
||||
// increase depth for batching order
|
||||
t.depth(+1);
|
||||
for (Object removedBean : modifyRemovals) {
|
||||
deleteRecurse(removedBean, t);
|
||||
if (removedBean instanceof EntityBean) {
|
||||
EntityBean eb = (EntityBean)removedBean;
|
||||
if (eb._ebean_getIntercept().isLoaded()) {
|
||||
// only delete if the bean was loaded meaning that
|
||||
// it is know to exist in the DB
|
||||
deleteRecurse(removedBean, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
t.depth(-1);
|
||||
}
|
||||
|
||||
+4
@@ -47,12 +47,16 @@ public class FactoryBaseProperties {
|
||||
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
|
||||
if(DmlMode.WHERE.equals(mode) && !withLobs && !props[i].isDbUpdatable()) {
|
||||
// skip non-updatable column from where clause
|
||||
} else {
|
||||
Bindable item = factoryProperty.create(props[i], mode, withLobs);
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
} else {
|
||||
// null where readOnly (Secondary tables) or Lob exclusion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.avaje.ebean.bean.ObjectGraphNode;
|
||||
import com.avaje.ebean.bean.ObjectGraphOrigin;
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebean.event.BeanQueryRequest;
|
||||
import com.avaje.ebean.meta.MetaAutoFetchStatistic;
|
||||
import com.avaje.ebeaninternal.api.BindParams;
|
||||
import com.avaje.ebeaninternal.api.HashQuery;
|
||||
import com.avaje.ebeaninternal.api.HashQueryPlan;
|
||||
@@ -90,9 +89,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
* The name of the query.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
private UseIndex useIndex;
|
||||
|
||||
|
||||
private Type type;
|
||||
|
||||
private Mode mode = Mode.NORMAL;
|
||||
@@ -317,14 +314,6 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
public ExpressionFactory getExpressionFactory() {
|
||||
return expressionFactory;
|
||||
}
|
||||
|
||||
public MetaAutoFetchStatistic getMetaAutoFetchStatistic() {
|
||||
if (parentNode != null && server != null){
|
||||
ObjectGraphOrigin origin = parentNode.getOriginQueryPoint();
|
||||
return server.find(MetaAutoFetchStatistic.class, origin.getKey());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the where expressions contains a many property.
|
||||
@@ -493,18 +482,9 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public UseIndex getUseIndex() {
|
||||
return useIndex;
|
||||
}
|
||||
|
||||
public DefaultOrmQuery<T> setUseIndex(UseIndex useIndex) {
|
||||
this.useIndex = useIndex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLoadDescription() {
|
||||
return loadDescription;
|
||||
}
|
||||
public String getLoadDescription() {
|
||||
return loadDescription;
|
||||
}
|
||||
|
||||
public String getLoadMode() {
|
||||
return loadMode;
|
||||
@@ -661,7 +641,7 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
}
|
||||
|
||||
builder.add((type == null ? 0 : type.ordinal()+1));
|
||||
builder.add(useIndex).add(autoFetchTuned).add(distinct).add(query);
|
||||
builder.add(autoFetchTuned).add(distinct).add(query);
|
||||
builder.add(firstRow).add(maxRows).add(orderBy).add(forUpdate);
|
||||
builder.add(rawWhereClause).add(additionalWhere).add(additionalHaving);
|
||||
builder.add(mapKey);
|
||||
|
||||
+13
-1
@@ -5,6 +5,8 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
import com.avaje.ebean.bean.PersistenceContext;
|
||||
import com.avaje.ebeaninternal.api.Monitor;
|
||||
|
||||
@@ -124,7 +126,7 @@ public final class DefaultPersistenceContext implements PersistenceContext {
|
||||
|
||||
private ClassContext getClassContext(Class<?> beanType) {
|
||||
|
||||
String clsName = beanType.getName();
|
||||
String clsName = getBeanBaseType(beanType).getName();
|
||||
ClassContext classMap = typeCache.get(clsName);
|
||||
if (classMap == null) {
|
||||
classMap = new ClassContext();
|
||||
@@ -132,6 +134,16 @@ public final class DefaultPersistenceContext implements PersistenceContext {
|
||||
}
|
||||
return classMap;
|
||||
}
|
||||
|
||||
private Class<?> getBeanBaseType(Class<?> beanType) {
|
||||
Class<?> parent = beanType.getSuperclass();
|
||||
|
||||
while (parent != null && parent.isAnnotationPresent(Entity.class)) {
|
||||
beanType = parent;
|
||||
parent = parent.getSuperclass();
|
||||
}
|
||||
return beanType;
|
||||
}
|
||||
|
||||
private static class ClassContext {
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import com.avaje.ebeaninternal.server.core.PersistRequest;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
|
||||
/**
|
||||
* Beans deleted by Id used for updating L2 Cache and Lucene indexes.
|
||||
* Beans deleted by Id used for updating L2 Cache.
|
||||
*/
|
||||
public final class DeleteByIdMap {
|
||||
|
||||
|
||||
@@ -593,12 +593,14 @@ public class JdbcTransaction implements SpiTransaction {
|
||||
}
|
||||
connection.commit();
|
||||
}
|
||||
// these will not throw an exception
|
||||
deactivate();
|
||||
notifyCommit();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RollbackException(e);
|
||||
|
||||
} finally {
|
||||
// these will not throw an exception
|
||||
deactivate();
|
||||
notifyCommit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,12 +636,13 @@ public class JdbcTransaction implements SpiTransaction {
|
||||
try {
|
||||
connection.rollback();
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new PersistenceException(ex);
|
||||
|
||||
} finally {
|
||||
// these will not throw an exception
|
||||
deactivate();
|
||||
notifyRollback(cause);
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new PersistenceException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ import com.avaje.ebeaninternal.server.lib.sql.DataSourcePool;
|
||||
/**
|
||||
* Manages transactions.
|
||||
* <p>
|
||||
* Keeps the Cache, Cluster and Lucene indexes in synch when transactions are
|
||||
* committed.
|
||||
* Keeps the Cache and Cluster in synch when transactions are committed.
|
||||
* </p>
|
||||
*/
|
||||
public class TransactionManager {
|
||||
@@ -426,7 +425,7 @@ public class TransactionManager {
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
String m = "NotifyOfCommit failed. Cache/Lucene potentially not notified.";
|
||||
String m = "NotifyOfCommit failed. L2 Cache potentially not notified.";
|
||||
logger.error(m, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,15 +61,6 @@ public class ScalarTypeUtilDate {
|
||||
public java.util.Date parseDateTime(long systemTimeMillis) {
|
||||
return new java.util.Date(systemTimeMillis);
|
||||
}
|
||||
|
||||
public Object luceneFromIndexValue(Object value) {
|
||||
Long l = (Long)value;
|
||||
return new java.util.Date(l);
|
||||
}
|
||||
|
||||
public Object luceneToIndexValue(Object value) {
|
||||
return ((java.util.Date)value).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DateType extends ScalarTypeBaseDate<java.util.Date> {
|
||||
|
||||
@@ -11,9 +11,9 @@ public class ClassPathSearchFilter {
|
||||
|
||||
private static final String COM_AVAJE_EBEANINTERNAL_SERVER_BEAN = "com.avaje.ebeaninternal.server.bean";
|
||||
|
||||
private static final String COM_AVAJE_EBEAN_META = "com.avaje.ebean.meta";
|
||||
private static final String COM_AVAJE_EBEAN_META = "com.avaje.ebean.meta";
|
||||
|
||||
private boolean defaultPackageMatch = true;
|
||||
private boolean defaultPackageMatch = true;
|
||||
|
||||
private boolean defaultJarMatch = false;
|
||||
|
||||
@@ -121,7 +121,7 @@ public class ClassPathSearchFilter {
|
||||
* Add a jar to explicitly exclude in the search.
|
||||
*/
|
||||
public void excludeJar(String jarName) {
|
||||
includeJarSet.add(jarName);
|
||||
excludeJarSet.add(jarName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +129,6 @@ public class ClassPathSearchFilter {
|
||||
*/
|
||||
public void includeJar(String jarName) {
|
||||
includeJarSet.add(jarName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
|
||||
protected transient ExpressionFactory expr;
|
||||
|
||||
private final String exprLang;
|
||||
private final String listAndStart;
|
||||
private final String listAndEnd;
|
||||
private final String listAndJoin;
|
||||
@@ -59,20 +58,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
this.list = list;
|
||||
this.query = query;
|
||||
this.expr = expr;
|
||||
this.exprLang = expr.getLang();
|
||||
this.parentExprList = parentExprList;
|
||||
|
||||
if ("ldap".equals(exprLang)) {
|
||||
// Language is LDAP
|
||||
listAndStart = "(&";
|
||||
listAndEnd = ")";
|
||||
listAndJoin = "";
|
||||
|
||||
} else {
|
||||
listAndStart = "";
|
||||
listAndEnd = "";
|
||||
listAndJoin = " and ";
|
||||
}
|
||||
this.listAndStart = "";
|
||||
this.listAndEnd = "";
|
||||
this.listAndJoin = " and ";
|
||||
}
|
||||
|
||||
public SpiExpressionList<?> trimPath(int prefixTrim) {
|
||||
@@ -231,6 +221,7 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.setMapKey(mapKey);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Query<T> setListener(QueryListener<T> queryListener) {
|
||||
return query.setListener(queryListener);
|
||||
}
|
||||
|
||||
@@ -27,14 +27,6 @@ public class DefaultExpressionRequest implements SpiExpressionRequest {
|
||||
this.deployParser = deployParser;
|
||||
}
|
||||
|
||||
// public DefaultExpressionRequest(SpiOrmQueryRequest<?> queryRequest, LIndex
|
||||
// index) {
|
||||
// this.queryRequest = queryRequest;
|
||||
// this.beanDescriptor = queryRequest.getBeanDescriptor();
|
||||
// this.deployParser = null;
|
||||
// this.luceneIndex = index;
|
||||
// }
|
||||
|
||||
public DefaultExpressionRequest(BeanDescriptor<?> beanDescriptor) {
|
||||
this.beanDescriptor = beanDescriptor;
|
||||
this.queryRequest = null;
|
||||
|
||||
@@ -136,6 +136,7 @@ public class FilterExpressionList<T> extends DefaultExpressionList<T> {
|
||||
return rootQuery.setFirstRow(firstRow);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Query<T> setListener(QueryListener<T> queryListener) {
|
||||
return rootQuery.setListener(queryListener);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class BaseTestCase {
|
||||
|
||||
static {
|
||||
logger.debug("... preStart");
|
||||
if (!AgentLoader.loadAgentFromClasspath("avaje-ebeanorm-agent","debug=0")) {
|
||||
if (!AgentLoader.loadAgentFromClasspath("avaje-ebeanorm-agent","debug=0;packages=com.avaje.tests.**")) {
|
||||
logger.info("avaje-ebeanorm-agent not found in classpath - not dynamically loaded");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public class ClassPathSearchTests {
|
||||
ClassPathSearchFilter filter = new ClassPathSearchFilter();
|
||||
filter.includePackage("com.avaje.ebeaninternal.server");
|
||||
filter.includeJar("WEB-INF");
|
||||
filter.setDefaultJarMatch(false);
|
||||
|
||||
ClassPathSearch search = new ClassPathSearch(cl, filter, new ClassPathSearchMatcher() {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.avaje.tests.cascade;
|
||||
|
||||
import javax.persistence.OptimisticLockException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.tests.model.basic.TSDetail;
|
||||
import com.avaje.tests.model.basic.TSMaster;
|
||||
|
||||
public class TestPrivateOwnedIgnoreTransientOrphan extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
|
||||
/** new object **/
|
||||
TSMaster master0 = new TSMaster();
|
||||
|
||||
/** recovered after first save **/
|
||||
TSMaster master1 = null;
|
||||
|
||||
/** recovered after transient child ignored **/
|
||||
TSMaster master2 = null;
|
||||
|
||||
Ebean.save(master0);
|
||||
|
||||
master1 = Ebean.find(master0.getClass(), master0.getId());
|
||||
|
||||
// Add then remove a bean that was never saved (to the DB)
|
||||
master1.getDetails().add(new TSDetail());
|
||||
master1.getDetails().clear();
|
||||
|
||||
try{
|
||||
Ebean.save(master1);
|
||||
} catch (OptimisticLockException exception) {
|
||||
// Occured when the "unsaved" bean was wrongly being deleted
|
||||
Assert.fail("Optimistic lock exception wrongly thrown: " + exception.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
master2 = master1 = Ebean.find(master1.getClass(), master1.getId());
|
||||
|
||||
Assert.assertTrue(master2.getDetails().isEmpty());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.avaje.tests.model.basic;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
@@ -14,7 +15,7 @@ public class UUTwo {
|
||||
|
||||
String name;
|
||||
|
||||
@ManyToOne
|
||||
@ManyToOne(cascade=CascadeType.PERSIST)
|
||||
UUOne master;
|
||||
|
||||
public UUID getId() {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.avaje.tests.model.inheritexposedtype;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@DiscriminatorValue( "photo" )
|
||||
public class IXPhoto extends IXResource {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.avaje.tests.model.inheritexposedtype;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
|
||||
@Entity
|
||||
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
|
||||
public class IXResource {
|
||||
|
||||
@Id
|
||||
UUID id;
|
||||
|
||||
@Column(insertable=false, updatable=false)
|
||||
String dtype;
|
||||
|
||||
String name;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDtype() {
|
||||
return dtype;
|
||||
}
|
||||
|
||||
public void setDtype(String dtype) {
|
||||
this.dtype = dtype;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.avaje.tests.model.inheritexposedtype.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.tests.model.inheritexposedtype.IXPhoto;
|
||||
|
||||
public class TestInheritExposeDtype extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
IXPhoto p = new IXPhoto();
|
||||
p.setName("the name");
|
||||
Ebean.save(p);
|
||||
|
||||
// update
|
||||
p.setName("new name");
|
||||
Ebean.save(p);
|
||||
|
||||
// delete
|
||||
Ebean.delete(p);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.avaje.tests.model.inheritmany;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
@Entity
|
||||
public class IMRelated {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
String name;
|
||||
|
||||
@ManyToOne(optional=false)
|
||||
IMRoot owner;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public IMRoot getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(IMRoot owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.avaje.tests.model.inheritmany;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
|
||||
public class IMRoot {
|
||||
|
||||
@Id
|
||||
Long id;
|
||||
|
||||
@OneToMany(mappedBy="owner")
|
||||
List<IMRelated> related;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<IMRelated> getRelated() {
|
||||
return related;
|
||||
}
|
||||
|
||||
public void setRelated(List<IMRelated> related) {
|
||||
this.related = related;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.avaje.tests.model.inheritmany;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@DiscriminatorValue("ONE")
|
||||
public class IMRootOne extends IMRoot {
|
||||
|
||||
String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.avaje.tests.model.inheritmany;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
@DiscriminatorValue("TWO")
|
||||
public class IMRootTwo extends IMRoot {
|
||||
|
||||
String title;
|
||||
|
||||
Date whenTitle;
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Date getWhenTitle() {
|
||||
return whenTitle;
|
||||
}
|
||||
|
||||
public void setWhenTitle(Date whenTitle) {
|
||||
this.whenTitle = whenTitle;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import org.junit.Test;
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.Query.UseIndex;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
import com.avaje.tests.model.basic.ResetBasicData;
|
||||
|
||||
@@ -21,7 +20,7 @@ public class TestExprNestedDisjunction extends BaseTestCase {
|
||||
|
||||
java.sql.Date onAfter = java.sql.Date.valueOf("2009-08-31");
|
||||
|
||||
Query<Customer> q = Ebean.find(Customer.class).setUseIndex(UseIndex.NO).where().disjunction()
|
||||
Query<Customer> q = Ebean.find(Customer.class).where().disjunction()
|
||||
.conjunction().startsWith("name", "r").eq("anniversary", onAfter).endJunction()
|
||||
.conjunction().eq("status", Customer.Status.ACTIVE).gt("id", 0).endJunction().orderBy()
|
||||
.asc("name");
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avaje.tests.query.other;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebean.Expression;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.tests.model.basic.Customer;
|
||||
|
||||
public class TestSubQueryBinding extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
EbeanServer server = Ebean.getServer(null);
|
||||
|
||||
Query<Customer> someCustomerIds = server.find(Customer.class).select("id").where().lt("id", 5).query();
|
||||
|
||||
Expression someCustIdsExpression = server.getExpressionFactory().in("id", someCustomerIds);
|
||||
|
||||
Query<Customer> query = server.find(Customer.class).where().like("name", "Rob%").not(someCustIdsExpression).query();
|
||||
|
||||
query.findList();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.avaje.tests.update;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.text.json.JsonContext;
|
||||
import com.avaje.ebean.text.json.JsonWriteOptions;
|
||||
import com.avaje.tests.model.basic.UUOne;
|
||||
import com.avaje.tests.model.basic.UUTwo;
|
||||
|
||||
public class TestJsonStatelessUpdate extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
UUOne one = new UUOne();
|
||||
one.setName("oneName");
|
||||
|
||||
Ebean.save(one);
|
||||
|
||||
UUTwo two = new UUTwo();
|
||||
two.setMaster(one);
|
||||
two.setName("twoName");
|
||||
|
||||
Ebean.save(two);
|
||||
|
||||
UUTwo twoX = Ebean.find(UUTwo.class, two.getId());
|
||||
|
||||
JsonContext jsonContext = Ebean.createJsonContext();
|
||||
|
||||
JsonWriteOptions writeOptions = JsonWriteOptions.parsePath("(id,name,master(*))");
|
||||
String jsonString = jsonContext.toJsonString(twoX, true, writeOptions);
|
||||
|
||||
System.out.println(jsonString);
|
||||
jsonString = jsonString.replace("twoName", "twoNameModified");
|
||||
jsonString = jsonString.replace("oneName", "oneNameModified");
|
||||
|
||||
|
||||
UUTwo two2 = jsonContext.toBean(UUTwo.class, jsonString);
|
||||
|
||||
Assert.assertEquals(twoX.getId(), two2.getId());
|
||||
Assert.assertEquals("twoNameModified", two2.getName());
|
||||
Assert.assertEquals("oneNameModified", two2.getMaster().getName());
|
||||
|
||||
// The update below cascades to also save "master" and that fails
|
||||
// as it thinks it should INSERT master rather than UPDATE master
|
||||
|
||||
// Ebean.update(two2);
|
||||
|
||||
|
||||
// The following is a workaround, to explicitly update master first
|
||||
// so then Ebean doesn't try to save it when two2 is updated
|
||||
Ebean.beginTransaction();
|
||||
try {
|
||||
UUOne master = two2.getMaster();
|
||||
Ebean.update(master);
|
||||
Ebean.update(two2);
|
||||
|
||||
} finally {
|
||||
Ebean.endTransaction();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.avaje.test.model.inheritmany.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.EbeanServer;
|
||||
import com.avaje.ebeaninternal.api.SpiEbeanServer;
|
||||
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
|
||||
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
|
||||
import com.avaje.tests.model.inheritmany.IMRelated;
|
||||
import com.avaje.tests.model.inheritmany.IMRoot;
|
||||
import com.avaje.tests.model.inheritmany.IMRootOne;
|
||||
import com.avaje.tests.model.inheritmany.IMRootTwo;
|
||||
|
||||
|
||||
public class TestInheritWithMany extends BaseTestCase {
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
EbeanServer server = Ebean.getServer(null);
|
||||
Assert.assertNotNull(server);
|
||||
|
||||
SpiEbeanServer spiServer = (SpiEbeanServer)server;
|
||||
BeanDescriptor<IMRoot> beanDescriptor = spiServer.getBeanDescriptor(IMRoot.class);
|
||||
InheritInfo inheritInfo = beanDescriptor.getInheritInfo();
|
||||
Assert.assertNotNull(inheritInfo);
|
||||
|
||||
|
||||
IMRootOne one = new IMRootOne();
|
||||
one.setName("One Name");
|
||||
server.save(one);
|
||||
add(one, "aaa");
|
||||
add(one, "bbb");
|
||||
|
||||
|
||||
|
||||
IMRootTwo two = new IMRootTwo();
|
||||
two.setTitle("Two Title");
|
||||
server.save(two);
|
||||
add(two, "ccc");
|
||||
add(two, "ddd");
|
||||
|
||||
|
||||
List<IMRoot> list = server.find(IMRoot.class).select("id").findList();
|
||||
|
||||
for (IMRoot imRoot : list) {
|
||||
// lazy load the related OneToMany which is related to a non-leaf
|
||||
List<IMRelated> related = imRoot.getRelated();
|
||||
for (IMRelated imRelated : related) {
|
||||
imRelated.getName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void add(IMRoot owner, String string) {
|
||||
|
||||
IMRelated relate = new IMRelated();
|
||||
relate.setName(string);
|
||||
relate.setOwner(owner);
|
||||
|
||||
EbeanServer server = Ebean.getServer(null);
|
||||
server.save(relate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user