2016-08-08 88 views
0

我有兩個表。一個代表問題,另一個代表可能的答案。因此,在真實世界的應用程序中,將顯示帶有答案的問題,這些答案將顯示爲無線電值,選擇框或複選框。JPA導致數據類型轉換錯誤的實體映射

我已經在問題實體上使用@OneToMany映射爲兩個表創建了JPA實體,並且在由複合外鍵連接的答案端上創建了@ManyToOne映射。

當我有我的應用程序搜索特定問題時,在初始化問題對象中的可能答案集時出現錯誤。

當我向下滾動錯誤堆棧時,它會引發一個轉換錯誤(將nvarchar轉換爲int),因爲'subtask'屬性是實體類中的字符串,數據庫中的varchar(SQL Server 2008)表。

我查看了Hibernate文檔,並嘗試了可能與此關係的註釋的所有不同組合,但我一直得到相同的錯誤。

你可以看看代碼看看哪裏有缺陷?我瘋了嗎?

DAO代碼:

public List<SubtaskQuestion> getSubtaskQuestions(String company, 
     String subtask) { 
    return entityManager 
      .createQuery("SELECT s FROM SubtaskQuestion s WHERE company = :company AND subtask = :subtask", SubtaskQuestion.class) 
      .setParameter("company", company) 
      .setParameter("subtask", subtask) 
      .getResultList();" 
} 

實體類:

@Entity 
@IdClass(SubtaskQuestionKey.class) 
@Table(name="M_SUBTASK_QS") 
public class SubtaskQuestion implements Comparable<SubtaskQuestion> { 
    @Id 
    @Column(name="COMPANY") 
    private String company; 
    @Id 
    @Column(name="SUBTASKID") 
    private String subtask; 
    @Id 
    @Column(name="Q_SEQ") 
    private Integer qSeq; 
    @Column(name="QUESTION") 
    private String question; 
    @Column(name="ANSWER_TYPE") 
    private String answerType; 
    @Column(name="REQUIRED") 
    private Boolean required; 

    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumns({ 
     @JoinColumn(name="COMPANY", insertable=false, updatable=false), 
     @JoinColumn(name="SUBTASKID", insertable=false, updatable=false), 
     @JoinColumn(name="Q_SEQ", insertable=false, updatable=false) 
    }) 
    @OrderBy("V_SEQ") 
    private SortedSet<SubtaskQuestionAnswer> possibleAnswers; 

    ... 


@Entity 
@IdClass(SubtaskQuestionAnswerKey.class) 
@Table(name="M_SUBTASK_QS_VALUES") 
public class SubtaskQuestionAnswer implements Comparable<SubtaskQuestionAnswer> { 

    @Id 
    @Column(name="COMPANY") 
    private String company; 
    @Id 
    @Column(name="SUBTASKID") 
    private String subtask; 
    @Id 
    @Column(name="Q_SEQ") 
    private Integer qSeq; 
    @Id 
    @Column(name="V_SEQ") 
    private Integer vSeq; 
    @Column(name="ANSWER_TYPE") 
    private String answerType; 
    @Column(name="VALUE") 
    private String value; 
    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name="COMPANY", insertable=false, updatable=false), 
     @JoinColumn(name="SUBTASKID", insertable=false, updatable=false), 
     @JoinColumn(name="Q_SEQ", insertable=false, updatable=false) 
    }) 
    private SubtaskQuestion subtaskQuestion; 

    ... 

實際的錯誤消息:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.questionanswer.pojo.subtask.SubtaskQuestion.possibleAnswers#component[company,qSeq,subtask]{company=C310, qSeq=4, subtask=CS0100}] 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602) 
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:492) 
    at com.questionanswer.repository.SubtaskDaoImpl.getSubtaskQuestions(SubtaskDaoImpl.java:76) 
    at com.questionanswer.service.SubtaskServiceImpl.getPendingHeaderData(SubtaskServiceImpl.java:54) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    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.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55) 
    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.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.$Proxy784.getPendingHeaderData(Unknown Source) 
    at com.questionanswer.controller.SubtaskController.subtaskCaseId(SubtaskController.java:82) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
    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:743) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:672) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:82) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829) 
    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.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:118) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106) 
    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:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    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:1041) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.questionanswer.pojo.subtask.SubtaskQuestion.possibleAnswers#component[company,qSeq,subtask]{company=C310, qSeq=4, subtask=CS0100}] 
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) 
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) 
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:98) 
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:682) 
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) 
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2004) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:730) 
    at org.hibernate.engine.internal.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:918) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) 
    at org.hibernate.loader.Loader.doList(Loader.java:2610) 
    at org.hibernate.loader.Loader.doList(Loader.java:2593) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2422) 
    at org.hibernate.loader.Loader.list(Loader.java:2417) 
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) 
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1339) 
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) 
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606) 
    at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483) 
    ... 92 more 
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting the nvarchar value 'CS0100' to data type int. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4853) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1781) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1034) 
    at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207) 
    at org.apache.commons.dbcp.DelegatingResultSet.next(DelegatingResultSet.java:207) 
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:109) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86) 
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:88) 
    ... 109 more 

回答

0

所以基本上嘗試了幾件事情後,我意識到,休眠是匹配在使用組合鍵進行連接時出現錯誤的列。在這樣做時,它試圖將問題表中的Q_SEQ列與答案表中的SUBTASKID列進行匹配。所以基本上我必須使用註釋中的referencedColumnName屬性將每個連接列與問題表中的相應列顯式匹配。我幾乎重命名了答案表中的數據庫表列(爲fk列名添加了「_FK」),所以我並沒有把自己弄糊塗到什麼引用什麼。

@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL) 
    @JoinColumns({ 
     @JoinColumn(name="COMPANY_FK", referencedColumnName="COMPANY", insertable=false, updatable=false), 
     @JoinColumn(name="SUBTASKID_FK", referencedColumnName="SUBTASKID", insertable=false, updatable=false), 
     @JoinColumn(name="Q_SEQ_FK", referencedColumnName="Q_SEQ", insertable=false, updatable=false) 
    }) 
    @OrderBy("V_SEQ") 
    private SortedSet<SubtaskQuestionAnswer> possibleAnswers;