Spring Data JPA - "No Property Found for Type" 异常

177

我在谷歌上搜索了很多内容,但没有一个能够解答我的问题。所以,接下来就是我的问题。

我正在尝试通过实现 Pinterest 克隆的最小功能来学习 Spring MVC 和 Spring Data JPA。因此,以下是我认为与我的问题相关的代码部分。

模型 / 实体

@Entity
@Table(name = "pin_item")
public class PinItem implements Serializable {
    // properties ...
    @JoinColumn(name = "board_id", referencedColumnName = "user_board_id")
    @ManyToOne(optional = false)
    private UserBoard board;

    // getters and setters...
}

@Entity
@Table(name = "user_board")
public class UserBoard implements Serializable {
    // properties ...
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "board")
    private List<PinItem> pinItemList;

    // getters and setters...
}

服务

@Service
@Transactional(readOnly = true)
public class BoardServiceImpl implements BoardService {
    @Autowired
    private UserBoardRepository boardRepository;

    @Override
    public List<UserBoard> findLatestBoards() {
        PageRequest request = new PageRequest(
                     0, PresentationUtil.PAGE_SIZE, 
                     Sort.Direction.DESC, "boardId"
        );
        return boardRepository.findAll(request).getContent();
    }

    // Other Methods
}

仓库

public interface UserBoardRepository extends JpaRepository<UserBoard, Integer> {

}

现在,当我调用BoardService中的 findLatestBoards 方法时,出现"No Property Found"异常,该异常发生在return boardRepository.findAll(request).getContent();代码行。以下是来自Tomcat日志的摘录。

DEBUG日志

12:28:44,254 DEBUG AnnotationTransactionAttributeSource:106 - Adding transactional method 'findLatestBoards' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
12:28:44,254 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'transactionManager'
12:28:44,254 DEBUG JpaTransactionManager:366 - Creating new transaction with name [com.tecnooc.picpin.service.impl.BoardServiceImpl.findLatestBoards]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
12:28:44,254 DEBUG JpaTransactionManager:369 - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl@75284194] for JPA transaction
12:28:44,255 DEBUG AbstractTransactionImpl:158 - begin
12:28:44,255 DEBUG LogicalConnectionImpl:212 - Obtaining JDBC connection
12:28:44,255 DEBUG DriverManagerDataSource:162 - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/pic_pin]
12:28:44,266 DEBUG LogicalConnectionImpl:218 - Obtained JDBC connection
12:28:44,267 DEBUG JdbcTransaction:69 - initial autocommit status: true
12:28:44,267 DEBUG JdbcTransaction:71 - disabling autocommit
12:28:44,267 DEBUG JpaTransactionManager:401 - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@370da60e]
12:28:44,274 DEBUG TransactionalRepositoryProxyPostProcessor$CustomAnnotationTransactionAttributeSource:286 - Adding transactional method 'findAll' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
12:28:44,274 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'transactionManager'
12:28:44,274 DEBUG JpaTransactionManager:332 - Found thread-bound EntityManager [org.hibernate.ejb.EntityManagerImpl@75284194] for JPA transaction
12:28:44,274 DEBUG JpaTransactionManager:471 - Participating in existing transaction
12:28:44,279 DEBUG CachedIntrospectionResults:159 - Not strongly caching class [java.io.Serializable] because it is not cache-safe
12:28:44,281 DEBUG JpaTransactionManager:851 - Participating transaction failed - marking existing transaction as rollback-only
12:28:44,281 DEBUG JpaTransactionManager:559 - Setting JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@75284194] rollback-only
12:28:44,283 DEBUG JpaTransactionManager:844 - Initiating transaction rollback
12:28:44,284 DEBUG JpaTransactionManager:534 - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@75284194]
12:28:44,284 DEBUG AbstractTransactionImpl:203 - rolling back
12:28:44,284 DEBUG JdbcTransaction:164 - rolled JDBC Connection
12:28:44,285 DEBUG JdbcTransaction:126 - re-enabling autocommit
12:28:44,285 DEBUG JpaTransactionManager:594 - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@75284194] after transaction
12:28:44,285 DEBUG EntityManagerFactoryUtils:338 - Closing JPA EntityManager
12:28:44,286 DEBUG LogicalConnectionImpl:232 - Releasing JDBC connection
12:28:44,286 DEBUG LogicalConnectionImpl:250 - Released JDBC connection
12:28:44,287 DEBUG ExceptionHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.tecnooc.picpin.controller.BoardController.latest(javax.servlet.http.HttpSession,org.springframework.ui.Model)]: org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard
12:28:44,289 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.tecnooc.picpin.controller.BoardController.latest(javax.servlet.http.HttpSession,org.springframework.ui.Model)]: org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard
12:28:44,290 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.tecnooc.picpin.controller.BoardController.latest(javax.servlet.http.HttpSession,org.springframework.ui.Model)]: org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard
12:28:44,291 DEBUG DispatcherServlet:959 - Could not complete request

异常

异常为"org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard"。但是,如果我理解正确,在PinItem中存在属性board,并且在UserBoard中使用 mappedBy = "board" 正确映射。

org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:271)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
    at org.springframework.data.jpa.repository.query.QueryUtils.toJpaOrder(QueryUtils.java:408)
    at org.springframework.data.jpa.repository.query.QueryUtils.toOrders(QueryUtils.java:372)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:456)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:437)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:319)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:289)
    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.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy147.findAll(Unknown Source)
    at com.tecnooc.picpin.service.impl.BoardServiceImpl.findLatestBoards(BoardServiceImpl.java:45)
    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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy148.findLatestBoards(Unknown Source)
    at com.tecnooc.picpin.controller.BoardController.latest(BoardController.java:31)
    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.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

我不明白为什么会抛出这个异常。你知道发生这种情况的原因吗?

注意: 我正在使用Hibernate作为持久化提供程序。另外,我在这里放置的代码部分是我认为与问题相关的。如果不是,请告诉我,我将使用所需的部分更新问题。


3
我遇到了同样的问题,当我将嵌入式ID命名为MyCompositePK并尝试编写findByMyCompositePKUserId(Long userId)时。关键是CRUD存储库也需要使用驼峰命名法,以便在从方法创建查询时区分表属性。因此,它必须是MyCompositePk和*findByMyCompositePkUserId(Long userId)*。 - EmeraldTablet
在我的情况下,错误在于我写了两次“by”。 findByApropAndByBprop - 错误。只需写一次“by” -findByApropAndBprop - 正确 - lingar
30个回答

3

看起来你的自定义JpaRepository方法名称与实体类中的任何变量不匹配。确保你的方法名称与实体类中的变量匹配。

例如:你有一个名为“active”的变量,而你的自定义JpaRepository方法说“findByActiveStatus”,因为没有叫做“activeStatus”的变量,它将抛出“PropertyReferenceException”异常。


2

我最近在将spring-boot版本从1.5.4升级到1.5.20时遇到了这个异常。问题出在存储库包结构上。

问题: 同一个包下有三个包: repository、repositoryCustom和repositoryImpl。

解决方案: 重新安排存储库包,使repository包包含repositoryCustom包,而repositoryCustom包包含repositoryImpl包:

repository 
   |
   ----- repositoryCustom
             |
             ----- repositoryImpl

2
最初的回答:
我曾经遇到过类似的问题,让我头疼了几个小时。
我的存储库方法是:
public List<ResultClass> findAllByTypeAndObjects(String type, List<Object> objects);

我遇到了这个错误:在ResultClass类型中未找到属性类型。

解决方案是,JPA/Hibernate不支持复数形式?尽管如此,移除“s”就解决了问题:

最初的回答

public List<ResultClass> findAllByTypeAndObject(String type, List<Object>

抱歉,您删除了哪个“s”?这两行看起来一样。 - Raymond Chen
@user7344209,我已经纠正了这个错误。请查看第二个代码示例的方法名称。 - mirisbowring
即使对于实体名称 Objects? - Satish Patro

2
通常,这个问题是由于输错导致的,在我的情况下,并不是仓库或服务层的问题,而是控制器层的问题!!!
以下是我的控制器代码片段,可以看到我在sortColumn变量中添加了“nconst”而不是相关实体中正确的字段名“tconst”,因此Spring无法确定这个字段,我应该输入“tconst”。
@GetMapping("/getAll")
    public ResponseEntity<Page> getAll(@RequestParam(defaultValue = "0") int page,
                                       @RequestParam(defaultValue = "10") int size,
                                       @RequestParam(defaultValue = "nconst") String sortColumn,
                                       @RequestParam(defaultValue = "asc") String sortOrder)
    { 
....
}

1
我遇到了类似的问题并且得到了相同的错误。以下是我的代码。
List<Users> list = userRepo.findAll(Sort.by(Direction.ASC, "userId", "memberLevel");

我收到了以下错误信息:
org.springframework.data.mapping.PropertyReferenceException: No property userId found for type User!

既然userId在主键对象中,如下所示:

private UserPk pk;

用户ID在UserPk中:

@EmbeddedId
@AttributeOverrides({
        @AttributeOverride(name = "userId", column = @Column(name = "USER_ID", nullable = false, length = 10)),
        @AttributeOverride(name = "currency", column = @Column(name = "CAT_CODE", nullable = false, length = 4)),
        @AttributeOverride(name = "memberLevel", column = @Column(name = "MEMBER_LEVEL", nullable = false, length = 4))})
public UserPk getPk() {
    return pk;
}

解决方案是更改它,使其引用主键属性名称。
List<Users> list = userRepo.findAll(Sort.by(Direction.ASC, "pk.userId", "pk.memberLevel");

1
请在repo的默认调用中检查属性名称,例如repository.findByUsername(username)。

1

我希望这能帮助到和我有类似问题的人,我遵循了所有命名和接口标准,但仍然遇到了问题。

My param name was -->  update_datetime 

我希望能根据更新时间以降序获取我的实体,但是我一直收到错误提示。
org.springframework.data.mapping.PropertyReferenceException: No property update found for type Release!

一些情况下它无法读取下划线字符 --> ( _ )。
so for workaround i changed the property name as  --> updateDatetime 

然后使用了相同的方法来使用JpaRepository方法。

成功了!


0
如果您的项目使用了Spring-Boot,您可以尝试在Application.java中添加这些注释。
@EnableJpaRepositories(repositoryFactoryBeanClass=CustomRepositoryFactoryBean.class)
@SpringBootApplication

public class Application {.....

0
除了建议之外,我还建议在您的存储库接口上使用@Repository进行注释。
Spring IOC 可能无法将其识别为存储库,因此无法检测实体及其对应的属性。

不是真的。 当一个接口扩展JpaRepository时,@Repository可以被省略,因为Spring Data JPA会自动创建CategoryRepositoryImpl实现类。还有一点需要注意。JpaRepository本身带有@NoRepositoryBean注解。这意味着Spring Data JPA不会为您创建JpaRepositoryImpl bean。 - codeskin

0

你应该在你的模型或实体类中定义那个属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接