#777 - ENH: Add support for @NamedQuery and @NamedQueries

This commit is contained in:
Robin Bygrave
2016-07-15 23:15:18 +12:00
parent cf13119b49
commit 05eb0bfc55
7 changed files with 96 additions and 12 deletions
@@ -894,6 +894,10 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
if (desc == null) {
throw new PersistenceException(beanType.getName() + " is NOT an Entity Bean registered with this server?");
}
String named = desc.getNamedQuery(namedQuery);
if (named != null) {
return createQuery(beanType, named);
}
RawSql rawSql = desc.getNamedRawSql(namedQuery);
if (rawSql != null) {
DefaultOrmQuery<T> query = createQuery(beanType);
@@ -905,7 +909,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
@Override
public <T> Query<T> createQuery(Class<T> beanType, String eql) {
DefaultOrmQuery<T> query = createQuery(beanType);
EqlParser.parse(eql, query);
return query;
@@ -7,7 +7,6 @@ import com.avaje.ebean.RawSql;
import com.avaje.ebean.SqlUpdate;
import com.avaje.ebean.Transaction;
import com.avaje.ebean.ValuePair;
import com.avaje.ebeaninternal.api.ConcurrencyMode;
import com.avaje.ebean.annotation.DocStoreMode;
import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.bean.EntityBean;
@@ -16,8 +15,8 @@ import com.avaje.ebean.bean.PersistenceContext;
import com.avaje.ebean.bean.PersistenceContextUtil;
import com.avaje.ebean.config.EncryptKey;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
import com.avaje.ebean.config.dbplatform.IdType;
import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
import com.avaje.ebean.event.BeanFindController;
import com.avaje.ebean.event.BeanPersistController;
import com.avaje.ebean.event.BeanPersistListener;
@@ -36,6 +35,7 @@ import com.avaje.ebean.plugin.BeanType;
import com.avaje.ebean.plugin.ExpressionPath;
import com.avaje.ebean.plugin.Property;
import com.avaje.ebeaninternal.api.CQueryPlanKey;
import com.avaje.ebeaninternal.api.ConcurrencyMode;
import com.avaje.ebeaninternal.api.LoadContext;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.api.SpiQuery;
@@ -111,6 +111,8 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
private final Map<String, RawSql> namedRawSql;
private final Map<String, String> namedQuery;
public void merge(EntityBean bean, EntityBean existing) {
EntityBeanIntercept fromEbi = bean._ebean_getIntercept();
@@ -414,6 +416,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
this.rootBeanType = PersistenceContextUtil.root(beanType);
this.prototypeEntityBean = createPrototypeEntityBean(beanType);
this.namedQuery = deploy.getNamedQuery();
this.namedRawSql = deploy.getNamedRawSql();
this.inheritInfo = deploy.getInheritInfo();
@@ -988,6 +991,13 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
return this;
}
/**
* Return the named ORM query.
*/
public String getNamedQuery(String name) {
return namedQuery.get(name);
}
/**
* Return the named RawSql query.
*/
@@ -46,6 +46,8 @@ import java.util.Map;
*/
public class DeployBeanDescriptor<T> {
private static final Map<String, String> EMPTY_NAMED_QUERY = new HashMap<String, String>();
private static final Map<String, RawSql> EMPTY_RAW_MAP = new HashMap<String, RawSql>();
private static class PropOrder implements Comparator<DeployBeanProperty> {
@@ -73,6 +75,8 @@ public class DeployBeanDescriptor<T> {
private Map<String, RawSql> namedRawSql;
private Map<String, String> namedQuery;
private EntityType entityType;
private DeployBeanPropertyAssocOne<?> unidirectional;
@@ -1055,6 +1059,23 @@ public class DeployBeanDescriptor<T> {
return serverConfig.getDocStoreConfig().getPersist();
}
/**
* Return the named ORM queries.
*/
public Map<String, String> getNamedQuery() {
return (namedQuery != null) ? namedQuery : EMPTY_NAMED_QUERY;
}
/**
* Add a named query.
*/
public void addNamedQuery(String name, String query) {
if (namedQuery == null) {
namedQuery = new LinkedHashMap<String, String>();
}
namedQuery.put(name, query);
}
/**
* Return the named RawSql queries.
*/
@@ -21,6 +21,8 @@ import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@@ -177,6 +179,18 @@ public class AnnotationClass extends AnnotationParser {
if (cache != null && !disableL2Cache) {
descriptor.setCache(cache);
}
NamedQueries namedQueries = cls.getAnnotation(NamedQueries.class);
if (namedQueries != null) {
for (NamedQuery namedQuery : namedQueries.value()) {
descriptor.addNamedQuery(namedQuery.name(), namedQuery.query());
}
}
NamedQuery namedQuery = cls.getAnnotation(NamedQuery.class);
if (namedQuery != null) {
descriptor.addNamedQuery(namedQuery.name(), namedQuery.query());
}
}
}
@@ -68,4 +68,40 @@ public class EbeanServer_eqlTest extends BaseTestCase {
query.findUnique();
}
@Test
public void namedQuery() {
ResetBasicData.reset();
Query<Customer> name = server().createNamedQuery(Customer.class, "name");
name.findList();
assertThat(name.getGeneratedSql()).contains("select t0.id c0, t0.name c1 from o_customer t0 order by t0.name");
}
@Test
public void namedQuery_withStatus() {
ResetBasicData.reset();
Query<Customer> name = server().createNamedQuery(Customer.class, "withStatus");
name.order().clear().asc("status");
name.findList();
assertThat(name.getGeneratedSql()).contains("select t0.id c0, t0.name c1, t0.status c2 from o_customer t0 order by t0.status");
}
@Test
public void namedQuery_withContacts() {
ResetBasicData.reset();
Query<Customer> query = server()
.createNamedQuery(Customer.class, "withContacts")
.setParameter("id", 1);
query.findUnique();
assertThat(query.getGeneratedSql()).contains("from o_customer t0 left outer join contact t1 on t1.customer_id = t0.id ");
}
}
@@ -5,17 +5,8 @@ import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
@Entity
@NamedQueries({
@NamedQuery(name="loadResult",
query="find CalculationResult " +
"fetch productConfiguration "+
"fetch groupConfiguration "+
"where charge = :charge")
})
public class CalculationResult {
@Id
@@ -14,6 +14,8 @@ import com.avaje.tests.model.basic.finder.CustomerFinder;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -27,6 +29,13 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* Customer entity bean.
*/
@NamedQueries(
value = {
@NamedQuery(name = "name", query = "select(name) order by name"),
@NamedQuery(name = "withStatus", query = "select(name,status) order by name")
}
)
@NamedQuery(name="withContacts", query = "fetch contacts (firstName, lastName) where id = :id")
@Cache(enableQueryCache = true)
@DocStore
@ChangeLog(inserts = ChangeLogInsertMode.EXCLUDE, updatesThatInclude = {"name", "status"})