ClassCastException从列表到单个对象的错误

时间:2015-05-22 11:15:57

标签: hibernate java-ee ejb

从列表中获取单个位置对象时遇到问题。 在primefaces中调用getLocations()dataTable可以正常工作。我可以显示所有地点。 但是当我想从位置列表中获取单个位置时,我总是得到一个ClassCastException。 我使用JPA(Hibernate)。

实体Bean:

@Entity
@Table(name = "location")
@NamedQueries({
    @NamedQuery(name = "Location.findAll", query = "SELECT l FROM Location l")})
public class Location implements Serializable {
    private static final long serialVersionUID = 1L;

@Column(name = "name")
private String name;
...

CDI Bean:

private List<Location> locations = null;

@PostConstruct
public void init() {
    locations = getService().findAll();
    Iterator iter = getLocations().iterator();
    Location first = (Location)iter.next(); //ClassCastException

同样的问题:

for (Location location : getLocations()) //Classcastexception
 {...}

错误消息:

java.lang.ClassCastException: package.ejb.entity.Location cannot be cast to package.ejb.entity.Location

更新: 整个应用程序是一个EAR项目。 Location Entity Bean包含在EJB-Jar中。 还有LocationService Session Bean,它被注入到CDI Bean中。 (对于findAll()调用)

CDI Bean包含在WAR中。

@ shruti1810提到,可能存在类加载问题。 我从Oracle阅读了文档The Class Loader Hierarchy 我理解的是,EJB类加载器是WAR类加载器的父类。由于这个原因,我不明白为什么会有ClassCastException。 CDI Bean中的位置是否从另一个类加载器加载而不是由findAll()方法给出的位置?

2 个答案:

答案 0 :(得分:1)

似乎作为类加载器问题 - 当同一个类由两个不同的类加载器加载时,同一个类上的ClassCastException是可能的,即你已经用一个类加载器加载了类,然后尝试将它转换为由另一个类加载器加载的同一个类。

在这里,你可以做以下两件事之一:

有一个通用的类加载器,可以加载自定义类加载器要使用的类。因此,在您的情况下,您将有一个新的类加载器,它将加载给定的类,您的自定义类加载器将扩展此类加载器。

另一个解决方案是在两个类加载器之间传递“序列化”状态。将一个实例序列化为一个字节数组,并通过反序列化对象流来重构另一个类加载器中的对象。

答案 1 :(得分:0)

修正了我的hibernate版本从4.3.9-Final降级到4.3.5-Final的问题。我还不知道是什么导致了这个问题。但似乎hibernate 4.3.5 +存在一些问题。

另一个主题,有类似的修复: here