2014-02-25 27 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

在查询使用模型/实体名称它应该工作。