2013-10-25 15 views
57

Vâng, tôi đã tìm kiếm trên Google và tìm thấy nhiều kết quả, nhưng không ai trong số họ có thể trả lời được vấn đề của tôi. Vì vậy, ở đây nó đi.Dữ liệu mùa xuân JPA - "Không tìm thấy bất động sản nào cho Loại" Ngoại lệ

Tôi đang cố gắng nghiên cứu Spring MVC và dữ liệu Spring JPA bằng cách thực hiện tối thiểu bản sao pinterest. Vì vậy, sau đây là các phần của mã mà tôi nghĩ là có liên quan đến vấn đề của tôi.

Models/Đối tượng

@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... 
} 

Dịch vụ

@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 
} 

Repository

public interface UserBoardRepository extends JpaRepository<UserBoard, Integer> { 

} 

Bây giờ, khi tôi gọi 012 Phương pháptrong BoardService, ngoại lệ "Không tìm thấy bất động sản" được ném trên dòng return boardRepository.findAll(request).getContent();. Đây là trích đoạn từ nhật ký tomcat.

DEBUG LOG

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 [[email protected]] 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.springframewo[email protected]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 [[email protected]] 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 [[email protected]] 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 [[email protected]] 
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 [[email protected]] 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 

Exception

Trường hợp ngoại lệ là "org.springframework.data.mapping.PropertyReferenceException: No property board found for type com.tecnooc.picpin.model.UserBoard". Nhưng, nếu tôi hiểu chính xác, thuộc tính board có mặt trong PinItem và được ánh xạ chính xác với mappedBy = "board" trong UserBoard.

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) 

Tôi không hiểu tại sao ngoại lệ này bị ném. Bất kỳ ý tưởng tại sao nó đang xảy ra?

Lưu ý: Tôi đang sử dụng Hibernate làm nhà cung cấp Persistence. Ngoài ra, phần mã tôi đặt ở đây là những gì tôi nghĩ là có liên quan đến vấn đề. Nếu không, hãy cho tôi biết và tôi sẽ cập nhật câu hỏi với phần bắt buộc.

+0

Tôi chạy vào cùng một vấn đề khi tôi đã đặt tên một ID nhúng là * MyCompositePK * và cố gắng viết * findByMyCompositePKUserId (Long userId) *. Vấn đề là, nó cần phải là trường hợp lạc đà cũng như cho kho CRUD, để phân biệt giữa các thuộc tính bảng khi tạo truy vấn ra khỏi phương thức của bạn. Vì vậy, nó phải được * MyCompositePk * và * findByMyCompositePkUserId (Long userId) * – EmeraldTablet

Trả lời

0

Trong JPA một mối quan hệ có một chủ sở hữu duy nhất, và bằng cách sử dụng mappedBy trong lớp UserBoard của bạn, bạn nói rằng PinItem là chủ sở hữu của mối quan hệ hai chiều, và rằng các tài sản trong PinItem của mối quan hệ được đặt tên board.

Trong lớp UserBoard bạn không có bất kỳ trường/thuộc tính nào có tên board, nhưng có thuộc tính pinItemList, do đó bạn có thể thử sử dụng thuộc tính đó thay thế.

9

lỗi này sẽ xảy ra nếu bạn cố gắng truy cập un-tồn tại tài sản

tôi đoán là sắp xếp đó được thực hiện vào mùa xuân bởi property name và không phải bởi real column name. và lỗi cho biết rằng, trong "UserBoard" không có bất động sản nào được đặt tên "boardId".

bests,

Oak

69

Tôi chạy vào vấn đề này giống nhau và tìm thấy giải pháp ở đây: http://java.dzone.com/articles/persistence-layer-spring-data

tôi đã đổi tên thành một tài sản thực thể. Nhưng với các truy vấn tùy chỉnh Springs tự động có một giao diện được định nghĩa cho tên thuộc tính cũ.

public interface IFooDAO extends JpaRepository< Foo, Long >{ 
    Foo findByOldPropName(final String name); 
} 

Lỗi chỉ ra rằng nó không thể tìm thấy "OldPropName" và đã ném ngoại lệ.

Để trích dẫn bài báo trên DZone:

Khi mùa xuân dữ liệu tạo ra một thực hiện Repository mới, nó phân tích tất cả các phương pháp xác định bởi các giao diện và cố gắng để tự động tạo ra các truy vấn từ tên phương pháp. Trong khi điều này có những hạn chế, nó là một cách rất mạnh mẽ và thanh lịch để xác định các phương thức truy cập tùy chỉnh mới với rất ít nỗ lực. Ví dụ, nếu các đơn vị quản lý có một trường tên (và getter tiêu chuẩn Java Bean và setter cho lĩnh vực đó), xác định phương pháp findByName trong giao diện DAO sẽ tự động tạo ra các truy vấn chính xác:

public interface IFooDAO extends JpaRepository< Foo, Long >{ 
    Foo findByName(final String name); 
} 

Đây là một ví dụ tương đối đơn giản; một tập hợp từ khóa lớn hơn được hỗ trợ bởi cơ chế tạo truy vấn.

Trong trường hợp đó, phân tích cú pháp không thể phù hợp với bất động sản với lĩnh vực đối tượng miền, các ngoại lệ sau đây được ném:

java.lang.IllegalArgumentException: No property nam found for type class org.rest.model.Foo 
+0

Tôi nghĩ rằng đây là câu trả lời chi tiết và rõ ràng nhất, vì vậy nên được chấp nhận. – kmarabet

49

đặt tên của bạn không đúng.

Theo documentation, nếu kho của bạn là UserBoardRepository, việc thực hiện kho lưu trữ tùy chỉnh của bạn nên được đặt tên như UserBoardRepositoryImpl, ở đây bạn đặt tên nó như BoardServiceImpl, đó là lý do tại sao nó ném ngoại lệ.

+0

Ngoài ra, tất cả các lớp/giao diện kho lưu trữ nên được đặt trong một thư mục - theo như tôi biết –

1

Trong trường hợp của tôi, tôi đã có lỗi đánh máy (trường hợp lạc đà) trong tên phương thức của mình. Tôi đặt tên nó là "findbyLastName" và đối mặt với ngoại lệ này. Sau khi tôi thay đổi nó thành "findByLastName" ngoại lệ đã biến mất.

12

Kể từ tên kho JPA của bạn là UserBoardRepository, tên giao diện tùy chỉnh của bạn nên được UserBoardRepositoryCustom (nó nên kết thúc với 'Custom') và tên lớp thực hiện của bạn nên được UserBoardRepositoryImpl (nên kết thúc với Impl; bạn có thể thiết lập nó với một postfix khác nhau bằng cách sử dụng kho-impl-postfix tài sản)

21

cố định, khi sử dụng CrudRepository của mùa xuân, chúng ta phải gắn PROPERTYNAME một cách chính xác sau khi findBy nếu không nó sẽ cung cấp cho y ou exception "Không tìm thấy bất động sản nào cho loại"

Tôi đã nhận được ngoại lệ này là. vì tên thuộc tính và tên phương thức không đồng bộ.

Tôi đã sử dụng mã bên dưới để truy cập DB.

public interface UserDao extends CrudRepository<User, Long> { 
    User findByUsername(String username); 

và Người dùng miền của tôi có thuộc tính.

@Entity 
public class User implements UserDetails { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "userId", nullable = false, updatable = false) 
    private Long userId; 
    private String username; 
+0

Cách tiếp cận này đã giúp tôi - tôi đã sử dụng tên không đúng của thuộc tính của lớp trong phương thức 'mặc định' của kho lưu trữ (được cung cấp bởi giao diện CrudRepository) instea của findByDateOfStatisticsBetween() Tôi đã sử dụng phương thức đặt tên findByDateBetween()) – ryzhman

0

Nếu dự án của bạn sử dụng Spring-Boot, bạn có thể thử thêm chú thích này tại Application.java.

@EnableJpaRepositories(repositoryFactoryBeanClass=CustomRepositoryFactoryBean.class) 
@SpringBootApplication 

public class Application {..... 
0

Lưu ý ở đây: câu trả lời từ Zane XY và Alan B. Dee khá tốt. Tuy nhiên, đối với những người bạn của những người sẽ sử dụng Spring Boot ngay bây giờ, và Spring Data, đây là một câu trả lời hiện đại hơn.

Giả sử bạn có một lớp học như:

@Entity 
class MyClass { 
    @Id 
    @GeneratedValue 
    private Long id; 

    private String myClassName; 
} 

Bây giờ một JpaRepository cho điều này sẽ trông như thế

interface MyClassRepository extends JpaRepository { 
    Collection<MyClass> findByMyClassName(String myClassName); 
} 

Bây giờ bạn "tùy chỉnh" tìm thấy bằng phương pháp phải đánh vần Collection<MyClass> findByMyClassName(String myClassName) chính vì mùa xuân cần có một số cơ chế để ánh xạ phương thức này trên MyClass thuộc tính myClassName!

tôi figured này ra bởi vì, đối với tôi, nó có vẻ tự nhiên để tìm một lớp học theo tên của nóngữ nghĩa, trong khi trên thực tế, synatxically bạn tìm thấy bằng myClassName

Cheers

Các vấn đề liên quan