mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
commit
e84c71fb82
@ -13,13 +13,17 @@
|
||||
*/
|
||||
package com.mysema.query.jpa;
|
||||
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Column;
|
||||
import java.util.*;
|
||||
import javax.persistence.Table;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mysema.query.JoinExpression;
|
||||
import com.mysema.query.QueryMetadata;
|
||||
import com.mysema.query.sql.*;
|
||||
@ -34,7 +38,7 @@ import com.mysema.query.types.*;
|
||||
*/
|
||||
public final class NativeSQLSerializer extends SQLSerializer {
|
||||
|
||||
private final Map<Expression<?>, String> aliases = Maps.newHashMap();
|
||||
private final ListMultimap<Expression<?>, String> aliases = ArrayListMultimap.create();
|
||||
|
||||
private final boolean wrapEntityProjections;
|
||||
|
||||
@ -78,7 +82,7 @@ public final class NativeSQLSerializer extends SQLSerializer {
|
||||
return expr instanceof Operation && ((Operation<?>)expr).getOperator() == Ops.ALIAS;
|
||||
}
|
||||
|
||||
public Map<Expression<?>, String> getAliases() {
|
||||
public ListMultimap<Expression<?>, String> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,10 @@ package com.mysema.query.jpa.hibernate.sql;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mysema.commons.lang.CloseableIterator;
|
||||
import com.mysema.query.*;
|
||||
import com.mysema.query.NonUniqueResultException;
|
||||
@ -86,7 +88,8 @@ public abstract class AbstractHibernateSQLQuery<Q extends AbstractHibernateSQLQu
|
||||
HibernateUtil.setConstants(query, serializer.getConstantToLabel(), queryMixin.getMetadata().getParams());
|
||||
|
||||
if (!forCount) {
|
||||
Map<Expression<?>, String> aliases = serializer.getAliases();
|
||||
ListMultimap<Expression<?>, String> aliases = serializer.getAliases();
|
||||
Set<String> used = Sets.newHashSet();
|
||||
// set entity paths
|
||||
List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection();
|
||||
Expression<?> proj = projection.get(0);
|
||||
@ -95,13 +98,25 @@ public abstract class AbstractHibernateSQLQuery<Q extends AbstractHibernateSQLQu
|
||||
if (isEntityExpression(expr)) {
|
||||
query.addEntity(extractEntityExpression(expr).toString(), expr.getType());
|
||||
} else if (aliases.containsKey(expr)) {
|
||||
query.addScalar(aliases.get(expr));
|
||||
for (String scalar : aliases.get(expr)) {
|
||||
if (!used.contains(scalar)) {
|
||||
query.addScalar(scalar);
|
||||
used.add(scalar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isEntityExpression(proj)) {
|
||||
query.addEntity(extractEntityExpression(proj).toString(), proj.getType());
|
||||
} else if (aliases.containsKey(proj)) {
|
||||
query.addScalar(aliases.get(proj));
|
||||
for (String scalar : aliases.get(proj)) {
|
||||
if (!used.contains(scalar)) {
|
||||
query.addScalar(scalar);
|
||||
used.add(scalar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set result transformer, if projection is a FactoryExpression instance
|
||||
|
||||
@ -13,8 +13,20 @@
|
||||
*/
|
||||
package com.mysema.query.jpa.sql;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.Query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mysema.commons.lang.CloseableIterator;
|
||||
import com.mysema.query.*;
|
||||
import com.mysema.query.jpa.AbstractSQLQuery;
|
||||
@ -30,15 +42,6 @@ import com.mysema.query.types.FactoryExpressionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.FlushModeType;
|
||||
import javax.persistence.LockModeType;
|
||||
import javax.persistence.Query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AbstractJPASQLQuery is the base class for JPA Native SQL queries
|
||||
*
|
||||
@ -113,19 +116,33 @@ public abstract class AbstractJPASQLQuery<Q extends AbstractJPASQLQuery<Q>> exte
|
||||
query = entityManager.createNativeQuery(queryString);
|
||||
}
|
||||
if (!forCount) {
|
||||
Map<Expression<?>, String> aliases = serializer.getAliases();
|
||||
ListMultimap<Expression<?>, String> aliases = serializer.getAliases();
|
||||
Set<String> used = Sets.newHashSet();
|
||||
if (proj instanceof FactoryExpression) {
|
||||
for (Expression<?> expr : ((FactoryExpression<?>)proj).getArgs()) {
|
||||
if (isEntityExpression(expr)) {
|
||||
queryHandler.addEntity(query, extractEntityExpression(expr).toString(), expr.getType());
|
||||
} else if (aliases.containsKey(expr)) {
|
||||
queryHandler.addScalar(query, aliases.get(expr), expr.getType());
|
||||
for (String scalar : aliases.get(expr)) {
|
||||
if (!used.contains(scalar)) {
|
||||
queryHandler.addScalar(query, scalar, expr.getType());
|
||||
used.add(scalar);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isEntityExpression(proj)) {
|
||||
queryHandler.addEntity(query, extractEntityExpression(proj).toString(), proj.getType());
|
||||
} else if (aliases.containsKey(proj)) {
|
||||
queryHandler.addScalar(query, aliases.get(proj), proj.getType());
|
||||
for (String scalar : aliases.get(proj)) {
|
||||
if (!used.contains(scalar)) {
|
||||
queryHandler.addScalar(query, scalar, proj.getType());
|
||||
used.add(scalar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,10 +12,7 @@ import com.mysema.query.jpa.domain.QCat;
|
||||
import com.mysema.query.jpa.domain.QCompany;
|
||||
import com.mysema.query.jpa.domain.sql.SAnimal;
|
||||
import com.mysema.query.sql.SQLSubQuery;
|
||||
import com.mysema.query.types.ConstructorExpression;
|
||||
import com.mysema.query.types.Expression;
|
||||
import com.mysema.query.types.Projections;
|
||||
import com.mysema.query.types.SubQueryExpression;
|
||||
import com.mysema.query.types.*;
|
||||
import com.mysema.query.types.expr.DateExpression;
|
||||
import com.mysema.query.types.expr.Wildcard;
|
||||
import com.mysema.testutil.ExcludeIn;
|
||||
@ -249,6 +246,12 @@ public abstract class AbstractSQLTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Projections_DuplicateColumns() {
|
||||
SAnimal cat = new SAnimal("cat");
|
||||
assertEquals(1, query().from(cat).list(new QList(cat.count(), cat.count())).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Single_Result() {
|
||||
query().from(cat).singleResult(cat.id);
|
||||
@ -357,4 +360,5 @@ public abstract class AbstractSQLTest {
|
||||
// print(rows);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -213,6 +213,9 @@
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireBackwardCompatibility implementation="org.semver.enforcer.RequireBackwardCompatibility">
|
||||
<excludes>
|
||||
<exclude>com/mysema/query/jpa/NativeSQLSerializer</exclude>
|
||||
</excludes>
|
||||
<compatibilityType>BACKWARD_COMPATIBLE_USER</compatibilityType>
|
||||
<dumpDetails>true</dumpDetails>
|
||||
<publicOnly>true</publicOnly>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user