我正在進行一點練習,並且在調用select查詢時遇到一些問題。在Hibernate中使用繼承時的問題
基本上我在下面的方法創建一個抽象類:
//AbstractStage
entity --class ~.AbstractStage --mappedSuperclass --abstract
field date --fieldName datetime --type java.util.Date --notNull
field boolean --fieldName iscomplete --type java.util.boolean
和兩個子類如下:
//
// HappyStage
//
entity --table happy_stage --class ~.HappyStage --extends ~.AbstractStage --testAutomatically --identifierField id --identifierColumn id_happy_stage
field boolean --fieldName isSad --type java.util.boolean
field date --fieldName dateOfDeath --type java.util.Date --notNull
finder add findHappyStagesByIscomplete
和
//
// HStage
//
entity --table h_stage --class ~.HStage --extends ~.AbstractStage --testAutomatically --identifierField id --identifierColumn id_h_stage
field boolean --fieldName isHappy --type java.util.boolean
field date --fieldName dateOfBirth --type java.util.Date --notNull
我的環境是:
Java
SpringTool
Roo
Hibernate
我也運行一個持久袋鼠命令:
persistence setup --provider HIBERNATE --database MYSQL
然後我寫了控制器類如下:
package test;
import java.util.Date;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.springframework.roo.addon.web.mvc.controller.RooWebScaffold;
import test.HappyStage;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.stereotype.Controller;
@RooWebScaffold(path = "happystages", formBackingObject = HappyStage.class)
@RequestMapping("/happystages")
@Controller
public class HappyStageController {
@RequestMapping(value="/happy", method=RequestMethod.GET)
public String get() throws Exception
{
// TypedQuery<AbstractStage> queryResults = HappyStage.findAbstractStagesByIscomplete(true);
Date dd = new Date();
TypedQuery<AbstractStage> queryResults = HappyStage.findAbstractStagesByDateGreaterThan(dd);
System.err.println("N.of abstractstages found: " + queryResults.getResultList().size());
return "redirect:/InheritanceTest";
}
}
HappyStage有方法findAbstractStagesByDateGreaterThan。這個想法是從子類中調用這個方法,並獲取日期大於的所有抽象階段。
q = em.createQuery("FROM test.AbstractStage AS abstractstage WHERE abstractstage.datetime > :datetime", AbstractStage.class);
這裏是HappyStage類代碼:
package test;
import test.AbstractStage;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.roo.addon.entity.RooEntity;
import java.util.Date;
import javax.validation.constraints.NotNull;
import javax.persistence.EntityManager;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import org.springframework.format.annotation.DateTimeFormat;
@RooJavaBean
@RooToString
@RooEntity(identifierField = "id", identifierColumn = "id_happy_stage", table = "happy_stage", finders = { "findHappyStagesByIscomplete", "findHappyStagesByDatetimeGreaterThan" })
public class HappyStage extends AbstractStage {
private Boolean isSad;
@NotNull
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(style = "S-")
private Date dateOfDeath;
public static TypedQuery<AbstractStage> findAbstractStagesByIscomplete(Boolean iscomplete) throws Exception {
if (iscomplete == null) throw new IllegalArgumentException("The iscomplete argument is required");
EntityManager em = HappyStage.entityManager();
TypedQuery<AbstractStage> q = null;
try {
q = em.createQuery("FROM test.AbstractStage AS abstractstage WHERE abstractstage.iscomplete = :iscomplete", AbstractStage.class);
q.setParameter("iscomplete", iscomplete);
} catch (Exception exp) {
System.err.println("Ex message:\n" + exp + "\nStack trace \n");
int stLenght = exp.getStackTrace().length;
StackTraceElement [] ste = exp.getStackTrace();
for(int i=0; i<stLenght; i++){
System.err.println("message [" + i + "]" + ste[i].toString());
}
throw(exp);
}
return q;
}
public static TypedQuery<AbstractStage> findAbstractStagesByDateGreaterThan(Date datetime) throws Exception {
EntityManager em = HappyStage.entityManager();
TypedQuery<AbstractStage> q = null;
try {
q = em.createQuery("FROM test.AbstractStage AS abstractstage WHERE abstractstage.datetime > :datetime", AbstractStage.class);
q.setParameter("datetime", datetime);
} catch (Exception exp) {
System.err.println("Ex message:\n" + exp);
throw(exp);
}
return q;
}
}
的問題是,當我運行的代碼在服務器上,然後轉到* /happystages /快樂我得到一個空指針異常與以下堆棧跟蹤: *
org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:281)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
$Proxy48.createQuery(Unknown Source)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
$Proxy49.createQuery(Unknown Source)
test.HappyStage.findAbstractStagesByDateGreaterThan_aroundBody2(HappyStage.java:55)
test.HappyStage.findAbstractStagesByDateGreaterThan(HappyStage.java:1)
test.HappyStageController.get(HappyStageController.java:25)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:90)
com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:76)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:409)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:680)
運行,我們已經確定了JUnit測試,可能的錯誤是在異常鏈接到休眠如何處理SQL查詢。添加一些斷點,我們發現,這可能是所涉及的代碼:
/**
* Abstract implementation of the Query interface.
*
* @author Gavin King
* @author Max Andersen
*/
public abstract class AbstractQueryImpl implements Query {
....
public Type[] getReturnTypes() throws HibernateException {
return session.getFactory().getReturnTypes(queryString);
}
...
}
我們現在正在打破碼多一點,但* 我在想,如果你們已經經歷了類似的問題。有什麼我失蹤?將抽象類作爲父類還是有必要將其作爲「具體」類來使用? *對於我來說,看起來很奇怪,你不能擁有一個抽象類並對其進行擴展,然後使用它根據繼承的值查詢所有子類。
請問我澄清,因爲我的問題可能沒有得到妥善解釋。
問候
PS:我已經試過也沒有在抽象類的--Abstract關鍵字。它仍然無法正常工作,並且在開始使用/開心和觸發get方法時會給我這個期待(調用:TypedQuery queryResults = HappyStage。findAbstractStagesByDateGreaterThan(dd); )」
org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:281)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
$Proxy48.createQuery(Unknown Source)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
$Proxy49.createQuery(Unknown Source)
test.HappyStage.findAbstractStagesByDateGreaterThan_aroundBody2(HappyStage.java:55)
test.HappyStage.findAbstractStagesByDateGreaterThan(HappyStage.java:1)
test.HappyStageController.get(HappyStageController.java:25)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:113)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:90)
com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:76)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:409)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:680)
看來,它沒有與MySQL和摘要做,因爲我還翻譯使用的休眠變成一個真正的SQL查詢的話SQL查詢,我已經在運行MySQL的外殼直接