mise en veille prolongée jpa java.lang.ClassCastException: modèle.Chien ne peut pas être jeté à modèle.Chien
J'ai une exception bizarre et je ne peux pas dire pourquoi. J'ai la liste en mémoire de la base de données mais lorsque j'essaie d'accéder aux getters ou d'enregistrer l'entité dans une variable, elle lève une exception.
Voici l'entité:
package model;
import java.io.Serializable;
import javax.persistence.*;
@Entity
@NamedQuery(name="Dog.findAll", query="SELECT d FROM Dog d")
public class Dog implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
public Dog() {
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
Ceci est mon implémentation de bean de session:
@Stateless(name = "mytable")
public class TableBean implements TableLocal {
@PersistenceContext(unitName = "sample")
private EntityManager manager;
@Override
public Dog getAll() {
Dog h = manager.find(Dog.class, 1);
Hibernate.initialize(h);
return h;
}
@Override
@SuppressWarnings("unchecked")
public List<Dog> findAll() {
Query query = manager.createQuery("SELECT h FROM Dog h",Dog.class);
List<Dog> col = query.getResultList();
Hibernate.initialize(col);
return col;
}
@Override
public void addDog() {
Dog d = new Dog();
//d.setId(2);
d.setName("chappy");
manager.persist(d);
}
}
J'ai aussi un bean de service, mais c'est inutile
@Stateless(name = "service")
public class ServiceBean implements ServiceLocal {
@EJB(beanName = "mytable")
TableLocal table;
@Override
public Dog getAll() {
return table.getAll();
}
@Override
public List<Dog> findAll() {
return table.findAll();
}
@Override
public void addDog() {
table.addDog();
}
}
Et mon servlet:
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB(beanName = "service")
ServiceLocal table;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Dog> tables = table.findAll();
Iterator<Dog> it = tables.iterator();
while (it.hasNext()) {
Dog t = it.next();
resp.getWriter().println(t.getName());
}
/*Dog h = table.getAll();
resp.getWriter().println(h.getId() + " " + h.getName());*/
/*table.addDog();
resp.getWriter().println("Added!");*/
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Et l'erreur est:
2015-07-28T13:38:17.385+0300|Warning: StandardWrapperValve[HelloServlet]: Servlet.service() for servlet HelloServlet threw exception
java.lang.ClassCastException: model.Dog cannot be cast to model.Dog
at HelloServlet.doGet(HelloServlet.java:26)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Et ma persistance.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="sample">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>MySQL</jta-data-source>
<class>model.Dog</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl" value="update" />
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
2 answers
Dans votre méthode findAll()
, utilisez TypedQuery au lieu de Query.
La raison en est que, TypedQuery getResultList()
renvoie la liste de la liste typée. c'est-à-dire dans votre cas, List<Dog>
mais getResultList de la requête renvoie Raw List
Vous pouvez essayer d'utiliser le code ci-dessous: -
@Override
@SuppressWarnings("unchecked")
public List<Dog> findAll() {
TypedQuery<Dog> query = manager.createQuery("SELECT h FROM Dog h",Dog.class);
List<Dog> col = query.getResultList();
Hibernate.initialize(col);
return col;
}
Très probablement, vous avez deux pots:
- un pour le web
- un pour les services de base (par exemple EJBS)
Les deux fichiers jar incluent la classe model.Dog
et le serveur d'applications charge deux versions de la même classe à partir de deux sources différentes. Lorsque la couche principale envoie la réponse model.Dog
à la couche web, la réponse a une version de classe chargée dans la couche principale alors que la couche Web a déjà une version d'exécution différente de cette classe, d'où l'exception que vous obtenez.
À corrigez-le, vous devez inclure les entités uniquement dans la couche principale et la couche Web doit avoir une dépendance sur l'artefact de la couche principale, au lieu d'inclure les entités elles-mêmes.
Mise à jour
Supprimez également ceci:
Hibernate.initialize(h);
Car cela n'apporte aucune valeur dans votre cas d'utilisation particulier.