与Hibernate一起使用继承时的问题

时间:2010-12-08 10:37:32

标签: java mysql hibernate openjpa

我正在进行一些练习,在调用选择查询时遇到一些问题。

基本上我用以下方式创建了一个Abstract类:

//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

我还运行了一个持久性roo命令:

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 / happy 时,我得到一个带有以下堆栈的nullPointer异常跟踪: *

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测试我们已经确定异常中的错误可能与Hibernate处理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:我也尝试过没有AbstractClass中的--Abstract关键字。它仍然不起作用,并在进入happystages / happy并触发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和Abstract没有关系,因为我还将hibernate使用的方言SQL查询翻译成真正的SQL查询,我直接在MySQL shell上运行它

1 个答案:

答案 0 :(得分:0)

我实际上已经尝试删除映射的超类标记,它似乎正在工作。 我找到了这个答案,似乎解决了这个问题:

Hibernate ManyToMany and superclass mapping problem

alghough有一个关于roo 1.0.1的小错误,有人在春季社区论坛上发布了这个错误:

http://forum.springsource.org/showthread.php?p=333182#post333182