简体   繁体   English

在Hibernate中使用继承时出现问题

[英]Problems when using inheritance with Hibernate

I am working on a little exercise and I am facing some problems when calling a select query. 我正在做一些练习,在调用选择查询时遇到一些问题。

Basically I've created an Abstract class in the following way: 基本上,我已通过以下方式创建了Abstract类:

//AbstractStage
entity --class ~.AbstractStage --mappedSuperclass  --abstract 
field date --fieldName datetime --type java.util.Date --notNull
field boolean --fieldName iscomplete --type java.util.boolean

and two subclasses as following: 和两个子类,如下所示:

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

and

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

My environment is: 我的环境是:

Java
SpringTool
Roo
Hibernate

I've also run a persistence roo command: 我还运行了一个持久性roo命令:

persistence setup --provider HIBERNATE --database MYSQL

Then I've wrote the controller class as following: 然后,我将控制器类编写如下:

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 has the method findAbstractStagesByDateGreaterThan. HappyStage具有方法findAbstractStagesByDateGreaterThan。 The idea was to call this method from the subclass and gett all the abstract stages with date greater than. 想法是从子类中调用此方法,并获得日期大于的所有抽象阶段。

q = em.createQuery("FROM test.AbstractStage AS abstractstage WHERE abstractstage.datetime > :datetime", AbstractStage.class);

Here is the HappyStage class code: 这是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;
    }    

}

The problem is that when I run the code as on server and go to the * /happystages/happy I get a nullPointer exception with the following stack trace:. 问题是,当我在服务器上运行代码并转到* / 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)

Running a JUnit test we have identified that probably the error is in the exception is linked to how Hibernate handles the SQL query. 运行JUnit测试,我们已经确定错误可能出在异常中,这与Hibernate处理SQL查询的方式有关。 Adding some breakpoints we found that this might be the code involved: 添加一些断点,我们发现这可能是所涉及的代码:

/**
 * 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 );
 }

...
}

We are now breaking down the code a bit more but * I was wondering if any of you has already experienced a similar problem. 我们现在将代码分解得更多一些,但是* 我想知道你们中是否有人已经遇到过类似的问题。 Is there anything I am missing? 我有什么想念的吗? Is alright to have an abstract class as parent class or would be necessary to have it as a "concrete" class? 将抽象类作为父类还是将其作为“具体”类是否必要? * It just seems odd to me that you cannot have an abstract class and extend it and then use it to query all the subclasses with a query based onthe inherited value. *对于我来说,您无法拥有一个抽象类并对其进行扩展,然后再使用它来基于继承的值进行查询来查询所有子类,这似乎使我感到奇怪。

Please ask me for clarifications as my question might not have been explained properly. 请澄清一下我的问题,因为我的问题可能没有正确解释。

Best Regards 最好的祝福

PS: I've tried as well without the --Abstract keyword in the AbstractClass. PS:我也尝试过在AbstractClass中不使用--Abstract关键字。 It still doesn't work and gives me this expetion when going to happystages/happy and triggering the get method (which calls: TypedQuery queryResults = HappyStage.findAbstractStagesByDateGreaterThan(dd) ; )" 它仍然不起作用,在进入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)

It seems that it doesn't have to do with MySQl and Abstract as I've also translated the dialect SQL query used by hibernate into a real SQL query and I've run it on the MySQL shell directly 看来这与MySQl和Abstract无关,因为我还将休眠状态下使用的方言SQL查询转换为真实的SQL查询,并且直接在MySQL Shell上运行

I've actually tried now by removing the mapped superclass tag and it seems to be working. 我实际上已经尝试过通过删除映射的超类标记来尝试,它似乎正在工作。 I found this answer and seems to solve the problem: 我找到了这个答案,似乎可以解决问题:

Hibernate ManyToMany and superclass mapping problem Hibernate ManyToMany和超类映射问题

alghough there is a little bug with roo 1.0.1 and someone has been posting about that on the spring community forum: alghough的roo 1.0.1中有一个小错误,有人在spring社区论坛上发布了有关此错误的信息:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM