mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Fix for #174 - Incorrect SQL generated with syntax error at the "order by" clause
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.deploy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -8,33 +9,33 @@ import java.util.Set;
|
||||
*/
|
||||
public final class DeployPropertyParserMap extends DeployParser {
|
||||
|
||||
private final Map<String,String> map;
|
||||
private final Map<String, String> map;
|
||||
|
||||
public DeployPropertyParserMap(Map<String,String> map) {
|
||||
this.map = map;
|
||||
}
|
||||
public DeployPropertyParserMap(Map<String, String> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null for raw sql queries.
|
||||
*/
|
||||
public Set<String> getIncludes() {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Returns null for raw sql queries.
|
||||
*/
|
||||
public Set<String> getIncludes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
public String convertWord() {
|
||||
String r = getDeployWord(word);
|
||||
return r == null ? word : r;
|
||||
}
|
||||
public String convertWord() {
|
||||
String r = getDeployWord(word);
|
||||
return r == null ? word : r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeployWord(String expression) {
|
||||
|
||||
String deployExpr = map.get(expression);
|
||||
if (deployExpr == null) {
|
||||
return null;
|
||||
} else {
|
||||
return deployExpr;
|
||||
}
|
||||
@Override
|
||||
public String getDeployWord(String expression) {
|
||||
|
||||
String deployExpr = map.get(expression);
|
||||
if (deployExpr == null) {
|
||||
return null;
|
||||
} else {
|
||||
return deployExpr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@ package com.avaje.ebeaninternal.server.query;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.avaje.ebeaninternal.api.BindParams;
|
||||
import com.avaje.ebeaninternal.api.BindParams.OrderedList;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionList;
|
||||
@@ -17,8 +21,6 @@ import com.avaje.ebeaninternal.server.querydefn.OrmQueryProperties;
|
||||
import com.avaje.ebeaninternal.server.type.DataBind;
|
||||
import com.avaje.ebeaninternal.server.util.BindParamsParser;
|
||||
import com.avaje.ebeaninternal.util.DefaultExpressionRequest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Compile Query Predicates.
|
||||
@@ -121,6 +123,8 @@ public class CQueryPredicates {
|
||||
* Includes from where and order by clauses.
|
||||
*/
|
||||
private Set<String> predicateIncludes;
|
||||
|
||||
private Set<String> orderByIncludes;
|
||||
|
||||
public CQueryPredicates(Binder binder, OrmQueryRequest<?> request) {
|
||||
this.binder = binder;
|
||||
@@ -316,16 +320,20 @@ public class CQueryPredicates {
|
||||
*/
|
||||
private void parsePropertiesToDbColumns(DeployParser deployParser) {
|
||||
|
||||
dbWhere = deriveWhere(deployParser);
|
||||
dbFilterMany = deriveFilterMany(deployParser);
|
||||
dbHaving = deriveHaving(deployParser);
|
||||
|
||||
// order by is dependent on the manyProperty (if there is one)
|
||||
logicalOrderBy = deriveOrderByWithMany(request.getManyProperty());
|
||||
if (logicalOrderBy != null) {
|
||||
dbOrderBy = deployParser.parse(logicalOrderBy);
|
||||
}
|
||||
|
||||
// create a copy of the includes required to support the orderBy
|
||||
orderByIncludes = new HashSet<String>(deployParser.getIncludes());
|
||||
|
||||
dbWhere = deriveWhere(deployParser);
|
||||
dbFilterMany = deriveFilterMany(deployParser);
|
||||
dbHaving = deriveHaving(deployParser);
|
||||
|
||||
// all includes including ones for manyWhere clause
|
||||
predicateIncludes = deployParser.getIncludes();
|
||||
}
|
||||
|
||||
@@ -504,6 +512,13 @@ public class CQueryPredicates {
|
||||
return predicateIncludes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the orderBy includes.
|
||||
*/
|
||||
public Set<String> getOrderByIncludes() {
|
||||
return orderByIncludes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The where sql with named bind parameters converted to ?.
|
||||
*/
|
||||
|
||||
@@ -291,6 +291,7 @@ public class SqlTreeBuilder {
|
||||
|
||||
// remove ManyWhereJoins from the predicateIncludes
|
||||
predicateIncludes.removeAll(manyWhereJoins.getPropertyNames());
|
||||
predicateIncludes.addAll(predicates.getOrderByIncludes());
|
||||
|
||||
// look for predicateIncludes that are not in selectIncludes and add
|
||||
// them as extra joins to the query
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.avaje.tests.model.pview;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "paggview")
|
||||
public class Paggview {
|
||||
|
||||
@OneToOne
|
||||
private Pview pview;
|
||||
|
||||
@Basic(optional = false)
|
||||
private Integer amount;
|
||||
|
||||
public Pview getPview() {
|
||||
return pview;
|
||||
}
|
||||
|
||||
public void setPview(Pview pview) {
|
||||
this.pview = pview;
|
||||
}
|
||||
|
||||
public Integer getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Integer amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.avaje.tests.model.pview;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "pp")
|
||||
public class Pview {
|
||||
|
||||
@Id
|
||||
private UUID id;
|
||||
|
||||
private String name;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(length = 100, nullable = false)
|
||||
private String value;
|
||||
|
||||
@JoinTable(name = "pp_to_ww", joinColumns = { @JoinColumn(name = "pp_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "ww_id", referencedColumnName = "id") })
|
||||
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
private List<Wview> wviews;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public List<Wview> getWviews() {
|
||||
return wviews;
|
||||
}
|
||||
|
||||
public void setWviews(List<Wview> wviews) {
|
||||
this.wviews = wviews;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.avaje.tests.model.pview;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.avaje.ebean.BaseTestCase;
|
||||
import com.avaje.ebean.Ebean;
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebean.config.GlobalProperties;
|
||||
|
||||
public class TestPview extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
GlobalProperties.put("ebean.search.packages", "com.avaje.tests.model.odd");
|
||||
|
||||
Wview wview = Ebean.getReference(Wview.class, UUID.randomUUID());
|
||||
|
||||
Query<Paggview> query = Ebean.find(Paggview.class);
|
||||
query.select("amount");
|
||||
query.where().eq("pview.wviews", wview);
|
||||
query.orderBy("pview.value");
|
||||
query.findList();
|
||||
String generatedSql = query.getGeneratedSql();
|
||||
|
||||
Assert.assertTrue(generatedSql.contains("select distinct t0.amount c0, t1.value from paggview t0 join pp u1 on u1.id = t0.pview_id join pp_to_ww u2z_ on u2z_.pp_id = u1.id join wview u2 on u2.id = u2z_.ww_id left outer join pp t1 on t1.id = t0.pview_id where u2.id = ? order by t1.value"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.avaje.tests.model.pview;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "wview")
|
||||
public class Wview {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private UUID id;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(unique = true)
|
||||
private String name;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user