mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-03 08:24:23 +00:00
#1181 - ENH: Add @FetchPreference support - Secondary query generation is based on order of fetch statements
This commit is contained in:
1 parent
9b2b2f7787
commit
156f505394
11 files changed
+123
-11
No files matched your search
@@ -318,6 +318,10 @@ public class OrmQueryDetail implements Serializable {
|
||||
*/
|
||||
void markQueryJoins(BeanDescriptor<?> beanDescriptor, String lazyLoadManyPath, boolean allowOne, boolean addIds) {
|
||||
|
||||
if (fetchPaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// the name of the many fetch property if there is one
|
||||
String manyFetchProperty = null;
|
||||
|
||||
@@ -325,22 +329,19 @@ public class OrmQueryDetail implements Serializable {
|
||||
boolean fetchJoinFirstMany = allowOne;
|
||||
|
||||
sortFetchPaths(beanDescriptor, addIds);
|
||||
List<FetchEntry> pairs = sortByFetchPreference(beanDescriptor);
|
||||
|
||||
for (String fetchPath : fetchPaths.keySet()) {
|
||||
ElPropertyDeploy elProp = beanDescriptor.getElPropertyDeploy(fetchPath);
|
||||
if (elProp == null) {
|
||||
throw new PersistenceException("Invalid fetch path " + fetchPath + " from " + beanDescriptor.getFullName());
|
||||
}
|
||||
for (FetchEntry pair : pairs) {
|
||||
ElPropertyDeploy elProp = pair.getElProp();
|
||||
if (elProp.containsManySince(manyFetchProperty)) {
|
||||
|
||||
// this is a join to a *ToMany
|
||||
OrmQueryProperties chunk = fetchPaths.get(fetchPath);
|
||||
OrmQueryProperties chunk = pair.getProperties();
|
||||
if (isQueryJoinCandidate(lazyLoadManyPath, chunk)) {
|
||||
// this is a 'fetch join' (included in main query)
|
||||
if (fetchJoinFirstMany) {
|
||||
// letting the first one remain a 'fetch join'
|
||||
fetchJoinFirstMany = false;
|
||||
manyFetchProperty = fetchPath;
|
||||
manyFetchProperty = pair.getPath();
|
||||
} else {
|
||||
// convert this one over to a 'query join'
|
||||
chunk.markForQueryJoin();
|
||||
@@ -350,6 +351,25 @@ public class OrmQueryDetail implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the fetch entries taking into account fetchPreference on the path.
|
||||
*/
|
||||
private List<FetchEntry> sortByFetchPreference(BeanDescriptor<?> desc) {
|
||||
|
||||
List<FetchEntry> entries = new ArrayList<>(fetchPaths.size());
|
||||
int idx = 0;
|
||||
for (Map.Entry<String, OrmQueryProperties> entry : fetchPaths.entrySet()) {
|
||||
String fetchPath = entry.getKey();
|
||||
ElPropertyDeploy elProp = desc.getElPropertyDeploy(fetchPath);
|
||||
if (elProp == null) {
|
||||
throw new PersistenceException("Invalid fetch path " + fetchPath + " from " + desc.getFullName());
|
||||
}
|
||||
entries.add(new FetchEntry(idx++, fetchPath, elProp, entry.getValue()));
|
||||
}
|
||||
Collections.sort(entries);
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this path is a candidate for converting to a query join.
|
||||
*/
|
||||
@@ -483,4 +503,45 @@ public class OrmQueryDetail implements Serializable {
|
||||
public Set<Map.Entry<String, OrmQueryProperties>> entries() {
|
||||
return fetchPaths.entrySet();
|
||||
}
|
||||
|
||||
private static class FetchEntry implements Comparable<FetchEntry> {
|
||||
|
||||
private final int index;
|
||||
private final String path;
|
||||
private final OrmQueryProperties properties;
|
||||
private final ElPropertyDeploy elProp;
|
||||
|
||||
FetchEntry(int index, String path, ElPropertyDeploy elProp, OrmQueryProperties value) {
|
||||
this.index = index;
|
||||
this.path = path;
|
||||
this.elProp = elProp;
|
||||
this.properties = value;
|
||||
}
|
||||
|
||||
String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
OrmQueryProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
ElPropertyDeploy getElProp() {
|
||||
return elProp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort by fetchPreference and then by index order.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(FetchEntry other) {
|
||||
int fp = elProp.getFetchPreference();
|
||||
int op = other.elProp.getFetchPreference();
|
||||
if (fp == op) {
|
||||
return Integer.compare(index, other.index);
|
||||
} else {
|
||||
return (fp < op) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user