2016-09-26 157 views
0

我是新的spring-data-jpa和本機查詢。在這個例子中我想以下SQL(與結果示出),以被轉換成JPA庫查詢引起︰java.lang.IllegalArgumentException︰org.hibernate.hql.internal.ast.QuerySyntaxException︰無法解析屬性︰

select c.* from customers c INNER JOIN orders o ON c.customerNumber=o.customerNumber where c.city='Nantes'; 

enter image description here

圖像的查詢的結果:

所以,我不喜歡下面 -

CustomerRepository.java

public interface CustomerRepository extends JpaRepository<Customer, Long>{ 
    List<Customer> findByContactFirstName(String firstName); 

    @Query("select c from Customer c INNER JOIN Order o ON c.customerNumber=o.customerNumber where c.city=:city") 
    List<Customer> findByCustomerNumberByCity(@Param("city") String city); 
} 

當我與測試類

@Test 
    public void testByCustomerNumber(){ 
     List<Customer> customers = customerRepository.findByCustomerNumberByCity("Nantes"); 
     System.out.println("Size of Customers : "+customers.size()); 
    } 

執行這個我看到下面的錯誤出現。

java.lang.IllegalStateException: Failed to load ApplicationContext 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) 
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.scheduler.repository.CustomerRepository.findByCustomerNumberByCity(java.lang.String)! 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1572) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:736) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128) 
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) 
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108) 
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251) 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) 
    ... 25 common frames omitted 
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.util.List com.scheduler.repository.CustomerRepository.findByCustomerNumberByCity(java.lang.String)! 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:92) 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:62) 
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:72) 
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:53) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:136) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:204) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:416) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:206) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237) 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1631) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568) 
    ... 40 common frames omitted 
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: could not resolve property: customerNumber of: com.scheduler.model.Order [select c from com.scheduler.model.Customer c INNER JOIN com.scheduler.model.Order o ON c.customerNumber=o.customerNumber where c.city=:city] 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1679) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:294) 
    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:497) 
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:344) 
    at com.sun.proxy.$Proxy60.createQuery(Unknown Source) 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:86) 
    ... 53 common frames omitted 
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: could not resolve property: customerNumber of: com.scheduler.model.Order [select c from com.scheduler.model.Customer c INNER JOIN com.scheduler.model.Order o ON c.customerNumber=o.customerNumber where c.city=:city] 
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) 
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:268) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) 
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) 
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) 
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) 
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1907) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) 
    ... 60 common frames omitted 
01:39:43.367 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test class: context [[email protected] testClass = CustomerTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [[email protected] testClass = CustomerTest, locations = '{classpath:application-context.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null]. 

Customer.java

@Entity 
@Table(name="customers") 
@NamedQuery(name="Customer.findAll", query="SELECT c FROM Customer c") 
public class Customer implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    //@GeneratedValue(strategy=GenerationType.AUTO) 
    private int customerNumber; 

    private String addressLine1; 

    private String addressLine2; 

    private String city; 

    private String contactFirstName; 

    private String contactLastName; 

    private String country; 

    private double creditLimit; 

    private String customerName; 

    private String phone; 

    private String postalCode; 

    private String state; 

    //bi-directional many-to-one association to Employee 
    @ManyToOne 
    @JoinColumn(name="salesRepEmployeeNumber") 
    private Employee employee; 

    //bi-directional many-to-one association to Order 
    @OneToMany(mappedBy="customer",fetch = FetchType.EAGER) 
    private List<Order> orders; 

    //bi-directional many-to-one association to Payment 
    @OneToMany(mappedBy="customer") 
    private List<Payment> payments; 

    // Assume setters and getters 
} 

Order.java

@Entity 
@Table(name="orders") 
@NamedQuery(name="Order.findAll", query="SELECT o FROM Order o") 
public class Order implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
// @GeneratedValue(strategy=GenerationType.AUTO) 
    private int orderNumber; 

    @Lob 
    private String comments; 

    @Temporal(TemporalType.DATE) 
    private Date orderDate; 

    @Temporal(TemporalType.DATE) 
    private Date requiredDate; 

    @Temporal(TemporalType.DATE) 
    private Date shippedDate; 

    private String status; 

    //bi-directional many-to-one association to Orderdetail 
    @OneToMany(mappedBy="order") 
    private List<Orderdetail> orderdetails; 

    //bi-directional many-to-one association to Customer 
    @ManyToOne 
    @JoinColumn(name="customerNumber") 
    private Customer customer; 
} 

這可能使用@查詢庫查詢來執行這樣的疑問?或者它應該使用本機sql查詢開發?請指導。 Order.java

@Entity 
@Table(name="orders") 
@NamedQuery(name="Order.findAll", query="SELECT o FROM Order o") 
public class Order implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
// @GeneratedValue(strategy=GenerationType.AUTO) 
    private int orderNumber; 

    @Lob 
    private String comments; 

    @Temporal(TemporalType.DATE) 
    private Date orderDate; 

    @Temporal(TemporalType.DATE) 
    private Date requiredDate; 

    @Temporal(TemporalType.DATE) 
    private Date shippedDate; 

    private String status; 

    //bi-directional many-to-one association to Orderdetail 
    @OneToMany(mappedBy="order") 
    private List<Orderdetail> orderdetails; 

    //bi-directional many-to-one association to Customer 
    @ManyToOne 
    @JoinColumn(name="customerNumber") 
    private Customer customer; 
     // Assume setters and getters present 
} 

回答

0

哦,我看到了問題。您需要以正確的方式重構JPA @Query。以下將正常工作。

@Query("SELECT c FROM Customer c JOIN c.orders o WHERE c.customerNumber = 
o.customer.customerNumber AND c.city=:city") 
List<Customer> findByCustomerNumberByCity(@Param("city") String city); 

是否使用來自鏈接的MySQL架構:http://www.mysqltutorial.org/mysql-sample-database.aspx。如果是,那麼下面的測試情況下產生的結果是:

@Test 
public void testfindByCustomerNumberByCityJPA(){ 
    List<Customer> customers = custmerRepository.findByCustomerNumberByCity("Nantes"); 
    System.out.println("Size of Customers : "+customers.size()); 
} 

要回答突出部分:

1)JPA repository查詢不會如果你正在做複雜的連接工作,那麼這是個不錯的選擇如果你正在做幾個加入,那麼JPA repository查詢是不錯的選擇。2)如果你正在處理與許多表格的複雜連接,那麼建議使用EntityManager並創建一個類似Query query = em.createNativeQuery(sql.toString());的Native Query,其中sql將是你的本地查詢。

希望這會引導你。

0
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: could not resolve property: customerNumber of: com.scheduler.model.Order [select c from com.scheduler.model.Customer c INNER JOIN com.scheduler.model.Order o ON c.customerNumber=o.customerNumber where c.city=:city] 
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74) 
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: could not resolve property: customerNumber of: com.scheduler.model.Order [select c from com.scheduler.model.Customer c INNER JOIN com.scheduler.model.Order o ON c.customerNumber=o.customerNumber where c.city=:city] 

屬性customerNumber之未結構域順序暴露。 因此冬眠無法從com.scheduler.model.Customer執行下面查詢

選擇C C INNER JOIN com.scheduler.model.Order O於c.customerNumber = o.customerNumber其中c.city =:城市

相關問題