Translate

Mostrando entradas con la etiqueta QueryDsl. Mostrar todas las entradas
Mostrando entradas con la etiqueta QueryDsl. Mostrar todas las entradas

viernes, 10 de agosto de 2012

MongoDB: java.lang.NoClassDefFoundError: com/google/common/base/Function

Este error se produce por no tener las versiones correctas de las librerías de Spring-data y query-dsl


--
java.lang.NoClassDefFoundError: com/google/common/base/Function
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.createQueryFor(QueryDslMongoRepository.java:167)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.count(QueryDslMongoRepository.java:154)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
 at $Proxy26.count(Unknown Source)
 at com.antuansoft.contentapi.application.CourseContentTemplateImpl.countByAllowedUsers(CourseContentTemplateImpl.java:61)
 at com.antuansoft.contentapi.integration.CourseContentTemplateIntegrationTest.countByAllowedUsers(CourseContentTemplateIntegrationTest.java:157)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Function
 at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
 at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
 ... 43 more

--

Si investigamos un poco en google la clase que nos fata la podemos encontrar en un jar llamado guava-12.0.jar este error se soluciona pero nos da otro


--
java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery.<init>(Lcom/mongodb/DBCollection;Lcom/google/common/base/Function;Lcom/mysema/query/mongodb/MongodbSerializer;)V
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:58)
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:44)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.createQueryFor(QueryDslMongoRepository.java:167)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.count(QueryDslMongoRepository.java:154)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)

--
Para este error ya tengo un post publicado que este:

Spring JPA MongoDB: java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery

miércoles, 11 de julio de 2012

Spring Data y QueryDSL operador like

QueryDSL like operator

Prerrequisitos: Conocimientos medios de QueryDsl.

El problema que resolvemos a continuación es el operador like usando QueryDSL. Si no quieres leerte todo el rollo te adelanto que el operador que buscas es containsIgnoreCase en vez de like pero tiene alguna pega que expongo a continuación.

Si has llegado hasta aquí buscando por google supongo que ya tendrás configurado tu entorno y QueryDsl para realizar tus consultas. Como ya sabemos la ventaja que te da QueryDsl es nos permite construir una query directamente sobre el código java de nuestro service.

Imaginemos que tenemos  el siguiente pojo

----
@Entity
@Document
public class Course implements Serializable {
 
 
 private static final long serialVersionUID = -7251789829032925885L;
 
 
 @Id
 private String id = UUID.randomUUID().toString();
 private String name; 
 private String description;
 private String companyOwner;
 private String metodology;

---

Una vez configurado QueryDsl automáticamente nos lo transforma nuestro pojo en el siguiente código.

----
/**
 * QCourse is a Querydsl query type for Course
 */
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QCourse extends EntityPathBase<Course> {

    private static final long serialVersionUID = 430564814;

    public static final QCourse course = new QCourse("course");

    public final StringPath companyOwner = createString("companyOwner");

    public final StringPath description = createString("description");

    public final StringPath id = createString("id");

    public final StringPath metodology = createString("metodology");


    public QCourse(String variable) {
        super(Course.class, forVariable(variable));
    }

    public QCourse(Path<? extends Course> entity) {
        super(entity.getType(), entity.getMetadata());
    }

    public QCourse(PathMetadata<?> metadata) {
        super(Course.class, metadata);
    }


---

Esto nos permite hacer queries directamente con código java

----
BooleanBuilder builder = new BooleanBuilder();
   
   builder.and(QCourse.course.id.eq("id1"));
   builder.and(QCourse.course.name.like("Matematica"));

List<Course> data = (List<Course>) courseDao.findAll(builder.getValue()); 
      
   return data;

---


El problema es cuando queremos hacer una búsqueda sobre un campo String con lo que en SQL sería el operador LIKE, como por ejemplo Name like %Matematica% 

QueryDsl tiene el operador like pero su lo utilizamos nos da el siguiente error:
 
 
----
java.lang.UnsupportedOperationException: Illegal operation course.name like Matemáticas
 at com.mysema.query.mongodb.MongodbSerializer.visit(MongodbSerializer.java:225)
 at com.mysema.query.mongodb.MongodbSerializer.visit(MongodbSerializer.java:34)
 at com.mysema.query.types.expr.BooleanOperation.accept(BooleanOperation.java:52)
 at com.mysema.query.mongodb.MongodbSerializer.handle(MongodbSerializer.java:39)
 at com.mysema.query.mongodb.MongodbSerializer.visit(MongodbSerializer.java:98)
 at com.mysema.query.mongodb.MongodbSerializer.visit(MongodbSerializer.java:34)
 at com.mysema.query.types.OperationImpl.accept(OperationImpl.java:81)
 at com.mysema.query.mongodb.MongodbSerializer.handle(MongodbSerializer.java:39)
 at com.mysema.query.mongodb.MongodbQuery.createQuery(MongodbQuery.java:330)
 at com.mysema.query.mongodb.MongodbQuery.createCursor(MongodbQuery.java:240)
 at com.mysema.query.mongodb.MongodbQuery.createCursor(MongodbQuery.java:235)
 at com.mysema.query.mongodb.MongodbQuery.list(MongodbQuery.java:221)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.findAll(QueryDslMongoRepository.java:113)


---
 
   
  La alternativa para que la operación sea la que deseamos es containsIgnoreCase


----

builder.and(QCourse.course.name.containsIgnoreCase("Matemati"));

---
 
  
  Esta búsqueda recuperará cualquier palabra en el nombre que contenga Matemati como por ejemplo, Matematica, Matematico, Matematicas ya esté en mayúsculas o minúsculas.


Lo que no encontrará este tipo de búsqueda son acentos, por ejemplo Matemáticas, así que no es una búsqueda full text pero se aproxima bastante.




lunes, 18 de junio de 2012

Spring JPA MongoDB: java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery

En nuestros proyecto estamos estamos trabajando con Spring Data Jpa para MySql y para MongoDb.

Al hora de hacer una query en MongoDb utilizando QueryDSL para utilizar los predicado que facilitan la creación de queries, nos ha dado el siguiente error.


------
java.lang.NoSuchMethodError: com.mysema.query.mongodb.MongodbQuery.<init>(Lcom/mongodb/DBCollection;Lcom/google/common/base/Function;Lcom/mysema/query/mongodb/MongodbSerializer;)V
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:58)
 at org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery.<init>(SpringDataMongodbQuery.java:44)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.createQueryFor(QueryDslMongoRepository.java:167)
 at org.springframework.data.mongodb.repository.support.QueryDslMongoRepository.count(QueryDslMongoRepository.java:154)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
----- 
El código utilizado el el siguiente:

 
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;

import charris.example.domain.Product;

public interface ProductRepository extends MongoRepository<Product, String>, QueryDslPredicateExecutor<Product> {

}



El error proviene al hacer una query como esta:

 
ProductRepository repo = context.getBean(ProductRepository.class);
Product p = repo.findOne(QProduct.product.name.eq("ProductName"));



El problema consistía en un problema de versiones entre los jar de
  1. querydl-mongodb
  2. spring-data
El error se solucionó poniendo las versiones  adecuadas de los JAR. Nosotros tuvimos que recurrir a los Nightly builds de spring data para que funcionara perfectamente.

Las versiones de los Jars fueron las siguientes a fecha (18/06/2012)

  •  querydsl-mongodb-2.5.0.jar
  • querydsl-mongodb-2.5.0-apt.jar
  • querydsl-mongodb-2.5.0-apt-one-jar.jar
  • spring-data-commons-core-1.3.2.BUILD-20120618.140513-1.jar
  • spring-data-jpa-1.1.1.BUILD-20120606.192912-1.jar
  • spring-data-mongodb-1.1.0.BUILD-20120614.104654-40.jar