Compare commits

..
Author SHA1 Message Date
Rob Bygrave e4306ce1ab [maven-release-plugin] prepare release avaje-ebeanorm-3.3.1 2014-04-02 21:59:46 +13:00
Rob Bygrave 444b656780 Update pom to 3.3.1 2014-04-02 21:58:13 +13:00
Rob Bygrave fcbba23441 Test case for #83 - Bug: Stateless update cascading to OneToOne or
ManyToOne incorrectly tries to INSERT rather than UPDATE
2014-04-02 21:44:41 +13:00
Rob Bygrave 18961047a1 Fix for #80 - Exposing discriminator value in entity bean throws
exception when updating or deleting
2014-03-31 22:49:44 +13:00
Rob Bygrave 34347fc3e1 Fix for #77 - NPE when lazy loading on a OneToMany that is not a leaf 2014-03-31 22:06:10 +13:00
Rob Bygrave 189e0a2ea9 Part of fix for #79 - moving deactivate() and notifyCommit() into finally block 2014-03-21 21:54:47 +13:00
Rob Bygrave 182e027521 Further changes for #79 - returning/cleanup of bad connection 2014-03-21 02:42:41 +13:00
Rob Bygrave f85fa2c21d Fix for #79 - Rollback in case of connection closed - deactivate() not called when connection.rollback() fails 2014-03-20 20:14:14 +13:00
Rob Bygrave 5a5f479568 Merge pull request #81 from rvowles/master
assume that if includes are specified then turn default includes off
2014-03-16 15:02:28 +13:00
Rob Bygrave 9ca2486c9c Change defaultJarMatch back to default to false (as per previous release) 2014-03-16 14:31:21 +13:00
Richard Vowles 656b239925 assume that if includes are specified then turn default includes off 2014-03-16 13:11:51 +13:00
Rob Bygrave 5d46904341 Fix for introduced issue with sub-query expression 2014-03-16 00:05:43 +13:00
Rob Bygrave f0dd069ed2 Fix for #70 - @PrivateOwned makes Ebean try to remove non persistent objects from DB and throws OptimisticLockException 2014-03-15 13:48:56 +13:00
Rob Bygrave 5bd454bdc0 Merge pull request #76 from icaromuniz/master
Adding test case TestPrivateOwnedIgnoreTransientOrphan related to issue #70
2014-03-15 13:14:17 +13:00
Rob Bygrave eeebaf9a08 Fix for #78 - Wrong collection used in excludeJar 2014-03-15 12:53:58 +13:00
Rob Bygrave 636a148509 Fix for #79 - Rollback in case of connection closed 2014-03-15 12:45:44 +13:00
Icaro Muniz 170cd6051e Adding test case TestPrivateOwnedIgnoreTransientOrphan 2014-02-26 09:23:35 -03:00
Rob Bygrave 522fc2384c [maven-release-plugin] prepare for next development iteration 2014-01-31 02:12:20 +13:00
Rob Bygrave 6f214590aa [maven-release-plugin] prepare release avaje-ebeanorm-3.3.1-RC2 2014-01-31 02:12:07 +13:00
Rob Bygrave 0014ea3501 Remove unused Lucene references including Query.UserIndex and associated methods 2014-01-31 01:26:12 +13:00
Rob Bygrave db3140512f set specific packages on dynamically loaded agent for tests 2014-01-31 00:59:48 +13:00
Rob Bygrave 8bfa331c61 Cleanup of expressions after FilterExprPath now only needed on FilterExpressionList 2014-01-31 00:48:59 +13:00
Rob Bygrave 456a1d8608 Remove AutoFetch query statistics meta entity beans, Remove Xml bean parsing (for json etc) 2014-01-31 00:22:38 +13:00
Rob Bygrave 695d3374a8 Default classPath scan include all jars (hopefully better default
behaviour)
2014-01-31 00:17:11 +13:00
Rob Bygrave 5488d054bf [maven-release-plugin] prepare for next development iteration 2014-01-30 23:25:57 +13:00
71 changed files with 900 additions and 1308 deletions
+1 -1
View File
@@ -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.
*/
+3 -25
View File
@@ -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;
}
@@ -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) {
@@ -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();
}
@@ -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));
}
}
}
@@ -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);
}
@@ -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);
@@ -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;
}
}
@@ -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);
}
}