Je travaille sur un petit exercice et je suis confronté à des problèmes lors de l'appel d'une requête select.Problèmes lors de l'utilisation de l'héritage avec Hibernate
Fondamentalement, j'ai créé une classe abstraite de la manière suivante:
//AbstractStage
entity --class ~.AbstractStage --mappedSuperclass --abstract
field date --fieldName datetime --type java.util.Date --notNull
field boolean --fieldName iscomplete --type java.util.boolean
et deux sous-classes comme suit:
//
// 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
et
//
// 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
Mon environnement est:
Java
SpringTool
Roo
Hibernate
Je suis également exécuter une commande roo de persistance:
persistence setup --provider HIBERNATE --database MYSQL
J'ai écrit la classe de contrôleur comme suit:
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 a la méthode findAbstractStagesByDateGreaterThan. L'idée était d'appeler cette méthode de la sous-classe et d'obtenir tous les stades abstraits avec une date supérieure à.
q = em.createQuery("FROM test.AbstractStage AS abstractstage WHERE abstractstage.datetime > :datetime", AbstractStage.class);
Voici le code de classe 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;
}
}
Le problème est que lorsque je lance le code que sur le serveur et aller au * /happystages/heureux Je reçois une exception NullPointer avec la trace de pile suivante: *
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)
Exécution d'un test JUnit, nous avons identifié que probablement l'erreur est à l'exception est liée à la façon dont Hibernate gère la requête SQL. L'ajout de quelques points d'arrêt, nous avons trouvé que cela pourrait être le code impliqué:
/**
* 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);
}
...
}
Nous brisons maintenant le code des un peu plus, mais * Je me demandais si quelqu'un d'entre vous a déjà connu un problème similaire. Y a-t-il quelque chose qui me manque? Est-ce bien d'avoir une classe abstraite en tant que classe parente ou serait-il nécessaire de l'avoir comme classe "concrète"? * Il me semble étrange que vous ne puissiez pas avoir de classe abstraite et que vous l'étendiez pour ensuite l'utiliser pour interroger toutes les sous-classes avec une requête basée sur la valeur héritée.
Veuillez me demander des clarifications car ma question n'a peut-être pas été correctement expliquée.
Cordialement
PS: Je l'ai essayé aussi bien sans le mot-clé --Abstract dans le AbstractClass. Cela ne fonctionne toujours pas et me donne cette expetion quand je vais dans happystages/happy et que je lance la méthode get (qui appelle: 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)
Il semble que cela ne doit pas faire Mysql et abstraits comme je l'ai aussi traduit le dialecte requête SQL utilisée par mise en veille prolongée en une véritable requête SQL et je l'ai exécuté sur le shell MySQL directement