简体   繁体   中英

Problems injecting EntityManager in GlassFish 4.1. ClassCastException (can't cast to same class)

I'm using:

  • GlassFish 4.1
  • Hibernate (see pom.xml)
  • Java EE 7
  • Eclipse Luna

I don't know why GlassFish can't inject an EntityManager. If i get the EntityManager from EntityManagerFactory, i don't have problems:

protected EntityManager em = Persistence.createEntityManagerFactory("CustomersPU").createEntityManager();

In other hand, if i try to say that GlassFish inject it, get an Exception.:

@PersistenceContext(unitName="CustomersPU")
protected EntityManager em;

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>me.localtest</groupId>
    <artifactId>customersapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven_compiler_source>1.8</maven_compiler_source>
        <maven_compiler_target>1.8</maven_compiler_target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.1.3.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.common</groupId>
            <artifactId>hibernate-commons-annotations</artifactId>
            <version>4.0.5.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.8.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

GenericService

package me.localtest.customersapp.services;

import java.io.Serializable;
import java.util.List;

public interface GenericService<T, PK extends Serializable> {
    public T save(T t) throws Throwable;
    public T update(T t) throws Throwable;
    public T remove(T t) throws Throwable;
    public T find(PK pk) throws Throwable;
    public List<T> findAll(String namedQuery) throws Throwable;
}

GenericServiceImpl

package me.localtest.customersapp.services;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

public abstract class GenericServiceImpl<T, PK extends Serializable> implements GenericService<T, PK> {
    //@PersistenceContext(unitName="CustomersPU")
    protected EntityManager em = Persistence.createEntityManagerFactory("CustomersPU").createEntityManager();
    protected Class<T> clazz;

    public GenericServiceImpl(Class<T> clazz) {
        this.clazz = clazz;
    }
    @Override
    public T save(T t) throws Throwable {
        em.persist(t);
        em.flush();
        return t;
    }
    @Override
    public T remove(T t) throws Throwable {
        em.remove(t);
        em.flush();
        return t;
    }
    @Override
    public T update(T t) throws Throwable {
        em.merge(t);
        em.flush();
        return t;
    }
    @Override
    public T find(PK pk) throws Throwable {
        return (T) em.find(clazz, pk);
    }
    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll(String aQuery) throws Throwable {
        Query query = em.createQuery(aQuery);
        return (List<T>) query.getResultList();
    }
}

CustomerServiceBean

package me.localtest.customersapp.services;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.Query;

import me.localtest.customersapp.domain.entities.Customer;

@LocalBean
@Stateless
public class CustomerServiceBean extends GenericServiceImpl<Customer, Integer> {

    public CustomerServiceBean() {
        super(Customer.class);
    }
    public Customer findByDni(String dni) {
        Query query = em.createNamedQuery("Customer.findByDni");
        query.setParameter("dni", dni);
        return (Customer) query.getSingleResult();
    }
}

Customer

package me.localtest.customersapp.domain.entities;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name="customers")
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
@NamedQueries({
    @NamedQuery(name="Customer.findByDni", query="SELECT c FROM Customer c WHERE c.dni = :dni")
})
@SuppressWarnings("serial")
public class Customer implements Serializable {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    @XmlElement(name="id")
    private Integer id;
    @Column(name="names")
    @XmlElement(name="names")
    private String names;
    @Column(name="surnames")
    @XmlElement(name="surnames")
    private String surnames;
    @Column(name="dni")
    @XmlElement(name="dni")
    private String dni;
    @Column(name="birth_date")
    @XmlElement(name="birth-date")
    @Temporal(TemporalType.DATE)
    private Date birthDate;
    @Column(name="address")
    @XmlElement(name="address")
    private String address;
    @Column(name="email")
    @XmlElement(name="email")
    private String email;
    @Column(name="creation_date")
    @Temporal(TemporalType.DATE)
    @XmlElement(name="creation-date")
    private Date creationDate;
    @Column(name="state")
    @XmlElement(name="state")
    private Boolean state;

    public Customer() {

    }
    public Customer(Integer id, String names, String surnames, String dni,
            Date birthDate, String address, String email, Date creationDate,
            Boolean state) {
        this.id = id;
        this.names = names;
        this.surnames = surnames;
        this.dni = dni;
        this.birthDate = birthDate;
        this.address = address;
        this.email = email;
        this.creationDate = creationDate;
        this.state = state;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getNames() {
        return names;
    }
    public void setNames(String names) {
        this.names = names;
    }
    public String getSurnames() {
        return surnames;
    }
    public void setSurnames(String surnames) {
        this.surnames = surnames;
    }
    public String getDni() {
        return dni;
    }
    public void setDni(String dni) {
        this.dni = dni;
    }
    public Date getBirthDate() {
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getCreationDate() {
        return creationDate;
    }
    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }
    public Boolean getState() {
        return state;
    }
    public void setState(Boolean state) {
        this.state = state;
    }
}

persistence.xml

<persistence-unit name="CustomersPU" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>jdbc/__customers</jta-data-source>
    <properties>
        <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" />
    </properties>
</persistence-unit>

Stage 1

Try to find Customer with DNI 'A' (RESTful):

http://localhost:8080/customersapp/api/customers/find/A

This is a piece stack trace:

2015-04-06T09:19:31.088-0500|Advertencia: A system exception occurred during an invocation on EJB CustomerServiceBean, method: public me.localtest.customersapp.domain.entities.Customer me.localtest.customersapp.services.CustomerServiceBean.findByDni(java.lang.String)
2015-04-06T09:19:31.089-0500|Advertencia: javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean
    at com.sun.ejb.containers.EJBContainerTransactionManager.checkExceptionClientTx(EJBContainerTransactionManager.java:662)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy267.findByDni(Unknown Source)
    at me.localtest.customersapp.services.__EJB31_Generated__CustomerServiceBean__Intf____Bean__.findByDni(Unknown Source)

And this is the cause:

Caused by: java.lang.ClassCastException: me.localtest.customersapp.domain.entities.Customer cannot be cast to me.localtest.customersapp.domain.entities.Customer

I found this stupid, how is possible can't cast to the same class?

Thanks.

Well, i could not find solution for this problem. I switched to WildFly 8.2.0, and no problems. Anyway, i hope someday to know why this happens xD.

Thanks.

Appeared to be the result of classloder problems GF 4.x is having with the hibernate version 4.3.8.Final

Most probably it relates to HHH-9446 Also it looks like it was fixed 2 days ago. Have not yet had a chance to try it though

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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