{"action":"created","issue":{"url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/126","labels_url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/126/labels{/name}","comments_url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/126/comments","events_url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/126/events","html_url":"https://github.com/spring-projects/spring-data-commons/pull/126","id":84121904,"number":126,"title":"1.9.x - PropertyPath is not dealing with properties containing underscore","user":{"login":"sabinewinkler","id":8375843,"avatar_url":"https://avatars.githubusercontent.com/u/8375843?v=3","gravatar_id":"","url":"https://api.github.com/users/sabinewinkler","html_url":"https://github.com/sabinewinkler","followers_url":"https://api.github.com/users/sabinewinkler/followers","following_url":"https://api.github.com/users/sabinewinkler/following{/other_user}","gists_url":"https://api.github.com/users/sabinewinkler/gists{/gist_id}","starred_url":"https://api.github.com/users/sabinewinkler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sabinewinkler/subscriptions","organizations_url":"https://api.github.com/users/sabinewinkler/orgs","repos_url":"https://api.github.com/users/sabinewinkler/repos","events_url":"https://api.github.com/users/sabinewinkler/events{/privacy}","received_events_url":"https://api.github.com/users/sabinewinkler/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-06-02T17:39:13Z","updated_at":"2015-06-03T05:21:09Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/spring-projects/spring-data-commons/pulls/126","html_url":"https://github.com/spring-projects/spring-data-commons/pull/126","diff_url":"https://github.com/spring-projects/spring-data-commons/pull/126.diff","patch_url":"https://github.com/spring-projects/spring-data-commons/pull/126.patch"},"body":"Having an entity with an underscore property e.g. \"first_name\" and a related repository method \"findByFirst__name\" (as documented with double underscore - http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions) results in the following exception:\r\n\r\n    java.lang.IllegalStateException: Failed to load ApplicationContext\r\n\tat ....\r\n    Caused by: org.springframework.data.mapping.PropertyReferenceException: No property first found for type Todo!\r\n\tat org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)\r\n\tat org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)\r\n\tat org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)\r\n\tat org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270)\r\n\tat org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241)\r\n\tat org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)\r\n\tat org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)\r\n\tat org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)\r\n\tat org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)\r\n\tat org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:87)\r\n\tat org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:61)\r\n\tat org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:94)\r\n\tat org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:205)\r\n\tat org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:72)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:349)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:187)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)\r\n\tat org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)\r\n\tat org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)\r\n\tat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)\r\n\t... 40 more\r\n\r\n\r\n\r\nDebugging this behaviour shows that the PropertyPath#from method seems not to deal with this case:\r\n\r\n   \t/**\r\n\t * Extracts the {@link PropertyPath} chain from the given source {@link String} and {@link TypeInformation}.\r\n\t * \r\n\t * @param source must not be {@literal null}.\r\n\t * @param type\r\n\t * @return\r\n\t */\r\n\tpublic static PropertyPath from(String source, TypeInformation<?> type) {\r\n\r\n\t\tAssert.hasText(source, \"Source must not be null or empty!\");\r\n\t\tAssert.notNull(type, \"TypeInformation must not be null or empty!\");\r\n\r\n\t\tList<String> iteratorSource = new ArrayList<String>();\r\n\t\tMatcher matcher = SPLITTER.matcher(\"_\" + source);\r\n\r\n\t\twhile (matcher.find()) {\r\n\t\t\titeratorSource.add(matcher.group(1));\r\n\t\t}\r\n\r\n\t\tIterator<String> parts = iteratorSource.iterator();\r\n\r\n\t\tPropertyPath result = null;\r\n\t\tStack<PropertyPath> current = new Stack<PropertyPath>();\r\n\r\n\t\twhile (parts.hasNext()) {\r\n\t\t\tif (result == null) {\r\n\t\t\t\tresult = create(parts.next(), type, current);\r\n\t\t\t\tcurrent.push(result);\r\n\t\t\t} else {\r\n\t\t\t\tcurrent.push(create(parts.next(), current));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\nCan you please check this. Thanks in advance!"},"comment":{"url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/comments/108196737","html_url":"https://github.com/spring-projects/spring-data-commons/pull/126#issuecomment-108196737","issue_url":"https://api.github.com/repos/spring-projects/spring-data-commons/issues/126","id":108196737,"user":{"login":"sabinewinkler","id":8375843,"avatar_url":"https://avatars.githubusercontent.com/u/8375843?v=3","gravatar_id":"","url":"https://api.github.com/users/sabinewinkler","html_url":"https://github.com/sabinewinkler","followers_url":"https://api.github.com/users/sabinewinkler/followers","following_url":"https://api.github.com/users/sabinewinkler/following{/other_user}","gists_url":"https://api.github.com/users/sabinewinkler/gists{/gist_id}","starred_url":"https://api.github.com/users/sabinewinkler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sabinewinkler/subscriptions","organizations_url":"https://api.github.com/users/sabinewinkler/orgs","repos_url":"https://api.github.com/users/sabinewinkler/repos","events_url":"https://api.github.com/users/sabinewinkler/events{/privacy}","received_events_url":"https://api.github.com/users/sabinewinkler/received_events","type":"User","site_admin":false},"created_at":"2015-06-03T05:21:09Z","updated_at":"2015-06-03T05:21:09Z","body":"Right, it was an accident. Sorry for that. Thanks for the ticket hint. In this case can you please remove the corresponding part from the documentation and make it clear to the user why it is not supported."}}