Impetus / kundera

A JPA 2.1 compliant Polyglot Object-Datastore Mapping Library for NoSQL Datastores.Please subscribe to:
http://groups.google.com/group/kundera-discuss/subscribe
Apache License 2.0
902 stars 234 forks source link

Query building from repositories does not work. #674

Open rabejens opened 9 years ago

rabejens commented 9 years ago

Lets say I have a simple entity:

@Entity
public class MyEntity {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }
}

and a simple repository:

public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Long> {

    Page<MyEntity> findByNameContainingIgnoringCase(String name, Pageable pageable);
}

creating the schema at start causes the application to bail out:

...
Caused by: com.impetus.kundera.query.JPQLParseException: Bad query format FROM clause is mandatory for SELECT queries. For details, see: http://openjpa.apache.org/builds/1.0.4/apache-openjpa-1.0.4/docs/manual/jpa_langref.html#jpa_langref_bnf
    at com.impetus.kundera.query.KunderaQuery.initEntityClass(KunderaQuery.java:381)
    at com.impetus.kundera.query.KunderaQuery.postParsingInit(KunderaQuery.java:357)
    at com.impetus.kundera.query.QueryResolver.getQueryImplementation(QueryResolver.java:80)
    at com.impetus.kundera.persistence.PersistenceDelegator.getQueryInstance(PersistenceDelegator.java:551)
    at com.impetus.kundera.persistence.PersistenceDelegator.createQuery(PersistenceDelegator.java:521)
    at com.impetus.kundera.persistence.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:416)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
    at com.sun.proxy.$Proxy97.createNamedQuery(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
    at com.sun.proxy.$Proxy94.createNamedQuery(Unknown Source)
    at org.springframework.data.jpa.repository.query.NamedQuery.<init>(NamedQuery.java:62)
    at org.springframework.data.jpa.repository.query.NamedQuery.lookupFrom(NamedQuery.java:113)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:132)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:166)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:320)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:169)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
    ... 134 common frames omitted

This is because the query parser is instructed to build a query from the String MyEntity.findByNameContainingIgnoringCase. In this case, the aforementioned exception is thrown. However, this is done in the CreateIfNotFoundQueryLookupStrategy (nested class of org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy). There you can see that the Spring guys were prepared and create the query if it cannot be resolved. For this to work, the resolver, however, must throw a subclass of IllegalArgumentException but the JPQLParseException is not a subclass thereof.

When copy-pasting the QueryHandlerException which JPQLParseException subclasses and making it subclass IllegalStateException the creation is carried-out.

Now, it comes to the JpaQueryCreator where it tries to create a distinct query if the part tree is distinct. It then does

this.query = builder.createQuery().distinct(tree.isDistinct());

This is carried-out by KunderaCriteriaQuery which is incomplete, there are lots of empty stub methods.

So for this to work, these methods have to be implemented.

chhavigangwal commented 9 years ago

@rabejens

Criteria query support is not completely enabled in Kundera as of now and is there on our roadmap.So for now you can write basic JPQLs to get your queries working . An example of same can be found at :

https://github.com/impetus-opensource/Kundera/blob/trunk/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBaseTest.java

Hope this Helps ! Chhavi

chhavigangwal commented 9 years ago

Can you also share the current manner in which you are issuing the query ?

Chhavi

chhavigangwal commented 9 years ago

Further to add on this currently most of the queries supported by JPQL in Kundera are supported via Criteria as well, so can you please share your specific query to look into the issue further.

Chhavi