以实体作为参数的Spring Data JPA自定义查询不起作用

时间:2016-01-28 11:29:08

标签: spring jpa spring-data-jpa

当我在Spring Data JPA中使用带有实体的自定义查询作为参数时,我得到了异常:

  

java.sql.SQLException:没有为参数1指定值

以下是相关实体。我有两个@OneToOne关系的实体,如下所示:

汽车:

@Entity
@Table(name = "car")
public class Car {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "car_id")
private long id;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "order_id", unique = true, nullable = true, insertable = true, updatable = true)
private Order order;
...
}

订单:

@Entity
@Table(name = "order")
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "order_id")
private long id;

@OneToOne(mappedBy="order")
private Car car;
...
}

我还有Spring Data JPA存储库,创建了自定义查询来查找Order by Car:

public interface OrderRepository extends CrudRepository<Order, Long> {

Optional<Order> findByCar(Car car);

}

但是,当我使用方法findByCar(carWithNonNullOrder)时,我收到错误:

  

2016-01-28 12:13:39,494 [main] WARN SqlExceptionHelper - SQL错误:0,SQLState:07001       2016-01-28 12:13:39,494 [main] ERROR SqlExceptionHelper - 没有为参数1指定值       2016-01-28 12:13:39,503 [main] INFO TransactionContext - 回滚测试上下文的事务[DefaultTestContext @ 61dde151 testClass = OrderServiceIT,testInstance = com.carsystem.server.OrderServiceIT@b25b095,testMethod = shouldMakeOrder @ OrderServiceIT,testException = org.springframework.dao.InvalidDataAccessResourceUsageException:无法提取ResultSet; SQL [不适用];嵌套异常是org.hibernate.exception.SQLGrammarException:无法提取ResultSet,mergedContextConfiguration = [MergedContextConfiguration @ 507b79f7 testClass = OrderServiceIT,locations =&#39; {classpath:context / app-context.xml}&#39;,classes = &#39; {}&#39;,contextInitializerClasses =&#39; []&#39;,activeProfiles =&#39; {}&#39;,propertySourceLocations =&#39; {}&#39;, propertySourceProperties =&#39; {}&#39;,contextLoader =&#39; org.springframework.test.context.support.DelegatingSmartContextLoader&#39;,parent = [null]]]。       2016-01-28 12:13:39,504 [main] INFO GenericApplicationContext - 关闭org.springframework.context.support.GenericApplicationContext@ff5b51f:启动日期[Thu Jan 28 12:13:31 CET 2016];上下文层次结构的根       2016-01-28 12:13:39,506 [main] INFO tainerEntityManagerFactoryBean - 为持久性单元关闭JPA EntityManagerFactory&#39;默认&#39;
      org.springframework.dao.InvalidDataAccessResourceUsageException:无法提取ResultSet; SQL [不适用];嵌套异常是org.hibernate.exception.SQLGrammarException:无法提取ResultSet           在org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:242)           在org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)           在org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)           at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)           在org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)           at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)           在com.sun.proxy。$ Proxy41.findByCar(未知来源)           在com.carsystem.server.OrderMapper.map(OrderMapper.java:25)           在com.carsystem.server.OrderServiceImpl.listOrders(OrderServiceImpl.java:90)           在com.carsystem.server.OrderServiceIT.shouldMakeOrder(OrderServiceIT.java:96)           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)           在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:47)           在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)           在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)           在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)           在org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)           在org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)           在org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)           在org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)           在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)           在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)           在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)           在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:238)           在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:63)           在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)           在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:53)           在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:229)           在org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)           在org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)           在org.junit.runners.ParentRunner.run(ParentRunner.java:309)           在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)           在org.junit.runner.JUnitCore.run(JUnitCore.java:160)           at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)           在com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)           在com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)           在com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)       引起:org.hibernate.exception.SQLGrammarException:无法提取ResultSet           在org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)           在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)           在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)           在org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)           at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79)           在org.hibernate.loader.Loader.getResultSet(Loader.java:2116)           在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1899)           在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1875)           在org.hibernate.loader.Loader.doQuery(Loader.java:919)           在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)           在org.hibernate.loader.Loader.doList(Loader.java:2611)           在org.hibernate.loader.Loader.doList(Loader.java:2594)           在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423)           在org.hibernate.loader.Loader.list(Loader.java:2418)           在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)           在org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)           在org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)           在org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326)           在org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)           在org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606)           在org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483)           在org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:50)           在org.springframework.data.jpa.repository.query.JpaQueryExecution $ CollectionExecution.doExecute(JpaQueryExecution.java:114)           在org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)           在org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:100)           在org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:91)           at org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:462)           at org.springframework.data.repository.core.support.RepositoryFactorySupport $ QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           在org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           at org.springframework.transaction.interceptor.TransactionInterceptor $ 1.proceedWithInvocation(TransactionInterceptor.java:99)           at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)           at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)           在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)           at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)           ......还有43个       引起:java.sql.SQLException:没有为参数1指定值           在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)           在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)           在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885)           在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)           在com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2205)           在com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2185)           在com.mysql.jdbc.PreparedStatement.fillSendPacket(PreparedStatement.java:2115)           在com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1936)           at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)           ... 74更多

Spring Data JPA代理似乎无法找到Car实体。我在这里找到了类似的问题:Spring Data query not working when query parameter is an entity,但在我的情况下,我急切地获取实体。映射或Spring Data JPA是否有问题?

修改

Hibernate查询:选择order0_.order_id作为order_i1_3_,order0_.client_id作为client_i4_3_,order0_.createdDate作为createdD2_3_,order0_.returnDate作为returnDa3_3_从订单order0_左外联接汽车car1_ on order0_.order_id = car1_.order_id其中car1_.car_id =?

我注意到我在自定义查询中使用的参数Car也是Order实体的类成员。但是,当我调用查询时,Car和Order之间存在循环依赖关系:Order有一个null Car。

2 个答案:

答案 0 :(得分:0)

试试这个:

Order findOneByCar(Car car);

答案 1 :(得分:0)

public interface OrderRepository extends JpaRepository<Order, Long> {

Order findByCar(Car car);

}

这应该有用。