anakin59490
anakin59490

Reputation: 672

Query : property name in parameter

With this query, I succeed to retrieve a phone number in database:

import java.util.List;
import org.springframework.data.jpa.repository.JpaReposit ory;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.mc.appcontacts.domain.hibernate.Contact;

public interface ContactRepository extends JpaRepository<Contact, Integer> {


@Query("SELECT c.phoneNumber from Contact c WHERE LOWER(c.name) = LOWER(:name)")
String find(@Param("name") String name);

But is it possible to specify dynamically name of the property i want to retrieve in parameter?

In all tuto i've read on the net, i learn we can pass the value of the property in parameter (In my exemple : @Param("name") String name ) but what i want to pass in parameter is the name of the property not the value !

I know the exemple below is not correct but it's to give the general idea :

@Query("SELECT c.(property) from Contact c WHERE LOWER(c.name) = LOWER(:name)") String find(@Param("name") String name, @Param("property") String property);

With property = phoneNumber (or an other property of my table).

Thank you for your help !!


I don't understand how to do that (everything is new for me):

I have read (and try) that jpql is defined like this :

import com.mysema.query.jpa.impl.JPAQuery;
import com.mc.appcontacts.repository.ContactRepository;  // managed by spring data 
                                                         //jpa repository

public class ServicesC { 

      @Autowired
      private ContactRepository repository;

      @PersistenceContext                        // try
      private EntityManager em;                  // try
      JPAQuery query = new JPAQuery(em);     // try

      public Contact getOne(Integer id) {
             return repository.findOne(id);
      }

      public String findAtt(String att, String key){
            String jpql = "SELECT c." + att + " from Contact c WHERE LOWER(c.name) = LOWER(:key)";   // try
            List<Contact> l = (List<Contact>) em.createQuery(jpql);   // try
            return "test";
    }
}

But it doesn't work (i'm not surprised...) :

2014-02-24 18:18:34.567:WARN::Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appMapping': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mc.appcontacts.service.ServiceC com.mc.appcontacts.mvc.MappingService.service; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Service' defined in file [C:\Professional\Workspaces\Eclipse\ContactMain\ContactCore\target\classes\com\mc\appcontacts\service\ServiceC.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mc.appcontacts.service.ServiceC]: Constructor threw exception; nested exception is java.lang.NullPointerException:
    java.lang.NullPointerException
at com.mysema.query.jpa.impl.JPAProvider.get(JPAProvider.java:72)
at com.mysema.query.jpa.impl.JPAProvider.getTemplates(JPAProvider.java:80)
at com.mysema.query.jpa.impl.JPAQuery.<init>(JPAQuery.java:46)

Must i define a second EntityManager only for jpql ? (Is it possible ? is it the right way ? I don't think so...) I have already a EntityManager defin for Spring-data in xml file :

<tx:annotation-driven transaction-manager="transactionManager" />   

<!-- Activate Spring Data JPA repository support -->
<jpa:repositories base-package="com.mc.appcontacts.repository" />

<!-- Declare a JPA entityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:META-INF/contacts/hibernate/persistence.xml" />
    <property name="persistenceUnitName" value="hibernatePersistenceUnit" />
    <!-- <property name="dataSource" ref="dataSource" /> -->
    <property name="jpaVendorAdapter" ref="hibernateVendor" />
</bean>

<!-- Specify our ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="showSql" value="${hibernate.showSql}" />
</bean>

<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

Please help me ... how does it work ?

Upvotes: 1

Views: 3442

Answers (2)

JanM
JanM

Reputation: 1487

I think for this use case of building queries dynamically your best bet would be to explore Criteria API, which is very suitable for such things. http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691735

No, it's not possible to do that. You'll have to implement it by yourself by dynamically generating the JPQL query.

Using query parameyters is not an option, because query parameters can only be values to replace in a given prepared statement, and can't alter the nature of the query itself. So you'll have to do something like

String jpql = "select c." + property + " from ...";

Upvotes: 1

Related Questions