Add support for JPA 2.1 treat

This commit is contained in:
Timo Westkämper 2014-04-09 16:31:55 +03:00
parent 3812288e86
commit 25d99dcd6f
8 changed files with 135 additions and 183 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
@ -16,8 +16,8 @@
<packaging>jar</packaging>
<properties>
<hibernate.version>4.2.0.Final</hibernate.version>
<hibernate.validator.version>4.3.0.Final</hibernate.validator.version>
<hibernate.version>4.3.5.Final</hibernate.version>
<hibernate.validator.version>4.3.1.Final</hibernate.validator.version>
<eclipselink.version>2.5.1</eclipselink.version>
</properties>
@ -59,7 +59,7 @@
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
@ -342,4 +342,4 @@
</plugins>
</build>
</project>
</project>

View File

@ -24,6 +24,8 @@ public final class JPQLOps {
private static final String NS = JPQLOps.class.getName();
public static final Operator<Object> TREAT = new OperatorImpl<Object>(NS, "TREAT");
public static final Operator<Integer> INDEX = new OperatorImpl<Integer>(NS, "INDEX");
public static final Operator<String> TYPE = new OperatorImpl<String>(NS, "TYPE");

View File

@ -13,50 +13,22 @@
*/
package com.mysema.query.jpa;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.mysema.query.JoinExpression;
import com.mysema.query.JoinType;
import com.mysema.query.QueryMetadata;
import com.mysema.query.support.SerializerBase;
import com.mysema.query.types.Constant;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Expression;
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.FactoryExpression;
import com.mysema.query.types.Operation;
import com.mysema.query.types.Operator;
import com.mysema.query.types.Ops;
import com.mysema.query.types.Order;
import com.mysema.query.types.OrderSpecifier;
import com.mysema.query.types.ParamExpression;
import com.mysema.query.types.Path;
import com.mysema.query.types.PathImpl;
import com.mysema.query.types.PathType;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.SubQueryExpression;
import com.mysema.query.types.*;
import com.mysema.util.MathUtils;
import javax.annotation.Nullable;
import javax.persistence.*;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;
import java.util.*;
/**
* JPQLSerializer serializes Querydsl expressions into JPQL syntax.
*
@ -127,25 +99,54 @@ public class JPQLSerializer extends SerializerBase<JPQLSerializer> {
this.entityManager = em;
}
private String getEntityName(Class<?> clazz) {
final Entity entityAnnotation = clazz.getAnnotation(Entity.class);
if (entityAnnotation != null && entityAnnotation.name().length() > 0) {
return entityAnnotation.name();
} else if (clazz.getPackage() != null) {
String pn = clazz.getPackage().getName();
return clazz.getName().substring(pn.length() + 1);
} else {
return clazz.getName();
}
}
private void handleJoinTarget(JoinExpression je) {
// type specifier
if (je.getTarget() instanceof EntityPath<?>) {
final EntityPath<?> pe = (EntityPath<?>) je.getTarget();
if (pe.getMetadata().isRoot()) {
final Entity entityAnnotation = pe.getAnnotatedElement().getAnnotation(Entity.class);
if (entityAnnotation != null && entityAnnotation.name().length() > 0) {
append(entityAnnotation.name());
} else if (pe.getType().getPackage() != null) {
final String pn = pe.getType().getPackage().getName();
final String typeName = pe.getType().getName().substring(pn.length() + 1);
append(typeName);
} else {
append(pe.getType().getName());
}
append(getEntityName(pe.getType()));
append(" ");
}
handle(je.getTarget());
} else if (je.getTarget() instanceof Operation) {
Operation<?> op = (Operation)je.getTarget();
if (op.getOperator() == Ops.ALIAS) {
boolean treat = false;
if (Collection.class.isAssignableFrom(op.getArg(0).getType())) {
if (op.getArg(0) instanceof CollectionExpression) {
Class<?> par = ((CollectionExpression)op.getArg(0)).getParameter(0);
treat = !par.equals(op.getArg(1).getType());
}
} else if (Map.class.isAssignableFrom(op.getArg(0).getType())) {
if (op.getArg(0) instanceof MapExpression) {
Class<?> par = ((MapExpression)op.getArg(0)).getParameter(1);
treat = !par.equals(op.getArg(1).getType());
}
} else {
treat = !op.getArg(0).getType().equals(op.getArg(1).getType());
}
if (treat) {
Expression<?> entityName = ConstantImpl.create(getEntityName(op.getArg(1).getType()));
Expression<?> t = OperationImpl.create(op.getType(), JPQLOps.TREAT, op.getArg(0), entityName);
op = OperationImpl.create(op.getType(), Ops.ALIAS, t, op.getArg(1));
}
}
handle(op);
} else {
handle(je.getTarget());
}
handle(je.getTarget());
}
public void serialize(QueryMetadata metadata, boolean forCountRow, @Nullable String projection) {

View File

@ -13,13 +13,13 @@
*/
package com.mysema.query.jpa;
import javax.annotation.Nullable;
import com.mysema.query.types.Operator;
import com.mysema.query.types.Ops;
import com.mysema.query.types.PathType;
import com.mysema.query.types.Templates;
import javax.annotation.Nullable;
/**
* JPQLTemplates extends {@link Templates} to provide operator patterns for JPQL
* serialization
@ -130,8 +130,8 @@ public class JPQLTemplates extends Templates {
add(Ops.INSTANCE_OF, "type({0}) = {1}");
add(JPQLOps.TYPE, "type({0})");
add(JPQLOps.INDEX, "index({0})");
add(JPQLOps.TREAT, "treat({0} as {1s})");
//CHECKSTYLE:ON
}

View File

@ -13,38 +13,8 @@
*/
package com.mysema.query;
import static com.mysema.query.Target.DERBY;
import static com.mysema.query.Target.HSQLDB;
import static com.mysema.query.Target.MYSQL;
import static com.mysema.query.Target.ORACLE;
import static com.mysema.query.Target.TERADATA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import com.google.common.collect.Lists;
import com.mysema.commons.lang.Pair;
import com.mysema.query.group.Group;
@ -53,67 +23,29 @@ import com.mysema.query.group.QPair;
import com.mysema.query.jpa.JPAExpressions;
import com.mysema.query.jpa.JPASubQuery;
import com.mysema.query.jpa.JPQLQuery;
import com.mysema.query.jpa.domain.Animal;
import com.mysema.query.jpa.domain.Author;
import com.mysema.query.jpa.domain.Book;
import com.mysema.query.jpa.domain.Cat;
import com.mysema.query.jpa.domain.Color;
import com.mysema.query.jpa.domain.Company;
import com.mysema.query.jpa.domain.*;
import com.mysema.query.jpa.domain.Company.Rating;
import com.mysema.query.jpa.domain.DomesticCat;
import com.mysema.query.jpa.domain.DoubleProjection;
import com.mysema.query.jpa.domain.Employee;
import com.mysema.query.jpa.domain.Entity1;
import com.mysema.query.jpa.domain.Entity2;
import com.mysema.query.jpa.domain.FloatProjection;
import com.mysema.query.jpa.domain.Foo;
import com.mysema.query.jpa.domain.JobFunction;
import com.mysema.query.jpa.domain.Numeric;
import com.mysema.query.jpa.domain.QAnimal;
import com.mysema.query.jpa.domain.QAuthor;
import com.mysema.query.jpa.domain.QBook;
import com.mysema.query.jpa.domain.QCat;
import com.mysema.query.jpa.domain.QCompany;
import com.mysema.query.jpa.domain.QDoubleProjection;
import com.mysema.query.jpa.domain.QEmployee;
import com.mysema.query.jpa.domain.QEntity1;
import com.mysema.query.jpa.domain.QFloatProjection;
import com.mysema.query.jpa.domain.QFoo;
import com.mysema.query.jpa.domain.QHuman;
import com.mysema.query.jpa.domain.QMammal;
import com.mysema.query.jpa.domain.QNumeric;
import com.mysema.query.jpa.domain.QShow;
import com.mysema.query.jpa.domain.QSimpleTypes;
import com.mysema.query.jpa.domain.QUser;
import com.mysema.query.jpa.domain.QWorld;
import com.mysema.query.jpa.domain.Show;
import com.mysema.query.jpa.domain4.QBookMark;
import com.mysema.query.jpa.domain4.QBookVersion;
import com.mysema.query.jpa.hibernate.HibernateSubQuery;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.ArrayConstructorExpression;
import com.mysema.query.types.Concatenation;
import com.mysema.query.types.ConstructorExpression;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Expression;
import com.mysema.query.types.ExpressionUtils;
import com.mysema.query.types.ParamNotSetException;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.Projections;
import com.mysema.query.types.QTuple;
import com.mysema.query.types.expr.BooleanExpression;
import com.mysema.query.types.expr.ListExpression;
import com.mysema.query.types.expr.Param;
import com.mysema.query.types.expr.SimpleExpression;
import com.mysema.query.types.expr.StringExpression;
import com.mysema.query.types.path.EnumPath;
import com.mysema.query.types.path.ListPath;
import com.mysema.query.types.path.NumberPath;
import com.mysema.query.types.path.SimplePath;
import com.mysema.query.types.path.StringPath;
import com.mysema.query.types.*;
import com.mysema.query.types.expr.*;
import com.mysema.query.types.path.*;
import com.mysema.testutil.ExcludeIn;
import com.mysema.testutil.IncludeIn;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.Calendar;
import java.util.Map.Entry;
import static com.mysema.query.Target.*;
import static org.junit.Assert.*;
/**
* @author tiwe
@ -441,7 +373,7 @@ public abstract class AbstractJPATest {
}
}
@Test(expected=NullPointerException.class)
@Test(expected=ClassCastException.class)
@NoEclipseLink
@NoBatooJPA
public void Constant_Hibernate() {
@ -1483,6 +1415,17 @@ public abstract class AbstractJPATest {
}
}
@Test
@NoBatooJPA
@NoEclipseLink
public void Treat() {
QDomesticCat domesticCat = QDomesticCat.domesticCat;
query().from(cat)
.innerJoin(cat.mate, domesticCat._super)
.where(domesticCat.name.eq("Bobby"))
.count();
}
@Test
@Ignore
public void Type() {
@ -1490,7 +1433,6 @@ public abstract class AbstractJPATest {
query().from(animal).orderBy(animal.id.asc()).list(JPAExpressions.type(animal)));
}
@Test
@NoOpenJPA
public void Type_Order() {

View File

@ -13,39 +13,30 @@
*/
package com.mysema.query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runner.RunWith;
import com.mysema.commons.lang.CloseableIterator;
import com.mysema.query.jpa.JPASubQuery;
import com.mysema.query.jpa.domain.Cat;
import com.mysema.query.jpa.domain.QCat;
import com.mysema.query.jpa.domain.QCatSummary;
import com.mysema.query.jpa.domain.QChild;
import com.mysema.query.jpa.domain.QParent;
import com.mysema.query.jpa.domain.*;
import com.mysema.query.jpa.impl.JPADeleteClause;
import com.mysema.query.jpa.impl.JPAQuery;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.expr.BooleanExpression;
import com.mysema.testutil.ExcludeIn;
import com.mysema.testutil.JPATestRunner;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runner.RunWith;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
/**
* @author tiwe
@ -88,7 +79,9 @@ public class JPABase extends AbstractJPATest {
}
@Test
@NoEclipseLink @NoOpenJPA
@NoEclipseLink
@NoOpenJPA
@NoHibernate
public void Connection_Access() {
assertNotNull(query().from(cat).createQuery(cat).unwrap(Connection.class));
}

View File

@ -13,25 +13,26 @@
*/
package com.mysema.query.jpa;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.junit.Test;
import com.mysema.query.DefaultQueryMetadata;
import com.mysema.query.JoinType;
import com.mysema.query.QueryMetadata;
import com.mysema.query.domain.QCat;
import com.mysema.query.jpa.domain.Location;
import com.mysema.query.jpa.domain.QDomesticCat;
import com.mysema.query.jpa.domain.QEmployee;
import com.mysema.query.support.Expressions;
import com.mysema.query.types.EntityPath;
import com.mysema.query.types.Expression;
import com.mysema.query.types.Path;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.path.EntityPathBase;
import com.mysema.query.types.path.NumberPath;
import com.mysema.query.types.path.StringPath;
import org.junit.Test;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
public class JPQLSerializerTest {
@ -196,4 +197,18 @@ public class JPQLSerializerTest {
"from Cat cat\n" +
"order by cat.name asc nulls last", serializer.toString());
}
@Test
public void Treat() {
QCat cat = QCat.cat;
JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT);
QueryMetadata md = new DefaultQueryMetadata();
md.addJoin(JoinType.DEFAULT, cat);
md.addJoin(JoinType.JOIN, cat.mate.as((Path)QDomesticCat.domesticCat));
md.addProjection(QDomesticCat.domesticCat);
serializer.serialize(md, false, null);
assertEquals("select domesticCat\n" +
"from Cat cat\n" +
" inner join treat(cat.mate as DomesticCat) as domesticCat", serializer.toString());
}
}

View File

@ -13,13 +13,8 @@
*/
package com.mysema.testutil;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
import com.mysema.query.Mode;
import com.mysema.query.jpa.domain.Domain;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
@ -34,8 +29,12 @@ import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import com.mysema.query.Mode;
import com.mysema.query.jpa.domain.Domain;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
/**
* @author tiwe
@ -109,7 +108,7 @@ public class HibernateTestRunner extends BlockJUnit4ClassRunner {
props.load(is);
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(props)
.buildServiceRegistry();
.build();
cfg.setProperties(props);
sessionFactory = cfg.buildSessionFactory(serviceRegistry);
session = sessionFactory.openSession();