2014-02-25 47 views
10

我想定製我的查詢與CrudRepository自定義查詢:與CrudRepository

這是我的代碼:

@Repository 
public interface CustomerRepository extends CrudRepository<Customer, Long> { 

@Query("UPDATE customer c SET c.firstName = :firstName WHERE c.id = :id") 
Integer setNewFirstNameForId(@Param("firstName") String firstName, @Param("id") long id); 
} 



@Entity 
public class Customer { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private long id; 
    private String firstName; 
    private String lastName; 

    protected Customer() {} 

    public Customer(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    @Override 
    public String toString() { 
     return String.format(
       "Customer[id=%d, firstName='%s', lastName='%s']", 
       id, firstName, lastName); 
    } 

但是,當我compilate這一切,我有這種錯誤的摘錄: 「錯誤名爲 'customerRepository' 創建豆:init方法的調用失敗; ...」

謝謝提前,

編輯:

這是我的錯誤:

Exception in thread "main" 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.lang.Integer hello.CustomerRepository.setNewFirstNameForId(java.lang.String,long)! 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) 
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:681) 
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84) 
at hello.Application.main(Application.java:75) 
Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.lang.Integer hello.CustomerRepository.setNewFirstNameForId(java.lang.String,long)! 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:80) 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:54) 
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:65) 
at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:48) 
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:115) 
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:160) 
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:304) 
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:161) 
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:220) 
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:206) 
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:84) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) 
... 11 more 
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: customer is not mapped [UPDATE customer c SET c.firstName = :firstName WHERE c.id = :id] 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:331) 
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:606) 
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:334) 
at com.sun.proxy.$Proxy38.createQuery(Unknown Source) 
at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:74) 
... 24 more 
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: customer is not mapped [UPDATE customer c SET c.firstName = :firstName WHERE c.id = :id] 
at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:96) 
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:120) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:234) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:126) 
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88) 
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:190) 
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301) 
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236) 
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1796) 
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328) 
... 31 more 
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: customer is not mapped 
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189) 
at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109) 
at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:95) 
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:331) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3554) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3443) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:706) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.updateStatement(HqlSqlBaseWalker.java:363) 
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:255) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278) 
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) 
... 39 more 
+0

如果有人解決了您的問題,您可以接受答案嗎? –

回答

13

主要問題是在你的JPQL:

@Query("UPDATE customer c SET c.firstName = :firstName WHERE c.id = :id") 

類型

@Query("UPDATE Customer c SET c.firstName = :firstName WHERE c.id = :id") 

那是因爲JPQL希望你的階級和階級應該是在開始時總是帶着大個性。所以JPQL沒有找到你的班級,錯誤發生了。

另一個問題可能是在@Modifying

@Modifying 
@Query("UPDATE customer c SET c.firstName = :firstName WHERE c.id = :id") 
    Integer setNewFirstNameForId(@Param("firstName") String firstName, @Param("id") long id); 
} 
要通過查詢修改每次

,你sholud添加@Modifying anotation因爲春天想了解它。

+0

我更新我的帖子,謝謝。 – user2931656

+0

對不起,下次我的問題將發表評論。我也編輯了我的信息 – Daris

+0

謝謝!!,更新和刪除我添加「@Transactional」如果不是我是執行錯誤。 – user2931656

1

還要考慮到,當您創建自定義查詢時,您必須使用實體結構而不是最終的數據庫結構。 例如,你可以有一個組成的私人密鑰。那麼你的實體將有一個屬性,它將是具有符合私鑰的屬性的實體。例如:

@Entity(name = "itemPrice") 
public class ItemPriceEntity { 

    @EmbeddedId 
    private ItemPriceComposedPK composedPK; 

    // Rest of the fields 
    ... 

    // Getters and setters 
    ... 
} 

@Embeddable 
public class ItemPriceComposedPK implements Serializable { 

    @Column 
    private String id; 

    @Column 
    private int iteration; 

    // Getters and setters 
    ... 
} 

如果你想使用外地迭代,那麼你必須編寫這樣的:i.composedPK.iteration。例如:

@Modifying 
@Query("select i from itemPrice i where i.composedPK.iteration = :it") 
public List<ItemPriceEntity> searchByIteration(@Param("it") String it); 

當然CrudRepository提供了一個更好的辦法,使這個查詢,而無需使用自定義查詢,但是,作爲一個例子,是確定的。

問候!

-3

在查詢使用模型/實體名稱它應該工作。