比较器抛出奇怪的ClassCastException:pkg.MyClass无法强制转换为pkg.MyClass

时间:2011-09-23 19:02:59

标签: java jsf-2 entity comparator classcastexception

我正在使用Comparator在视图结构的托管bean中按其属性(类型List<Entity>)对Date进行排序。

问题在于我不断获得ClassCastException如下 -

  

java.lang.ClassCastException:pkg.db.BaseArStatus无法强制转换为pkg.db.BaseArStatus。

为什么无法将BaseArStatus投射到BaseArStatus?是因为BaseArStatusEntity吗?

这个问题对我来说真的很奇怪,因为我每次都没有得到例外。在构建和部署应用程序时,大多数工作正常(运行没有任何问题)但有时(即使我做同样的事情 - 构建和部署)它在运行时因ClassCastException而失败。

为什么有时只发生而不是所有时间?是因为我在托管bean中使用它吗?

这就是托管bean的样子 -

@ManagedBean
@ViewScoped
public class MyBean {

@PersistenceContext(unitName = "myPU")
private EntityManager em;

public void myMethod() {
    List<BaseArStatus> basList = this.fetchAllBaseArStatus();
    Collections.sort(basList, new Comparator<BaseArStatus>() {
        @Override
        public int compare(BaseArStatus o1, BaseArStatus o2) {
            return o1.getMonthDate().compareTo(o2.getMonthDate());
        }
    });
//...

实体BaseArStatus -

@Entity
@Table(name = "base_ar_status")
@NamedQueries({
    @NamedQuery(name = "BaseArStatus.findAll", query = "SELECT b FROM BaseArStatus b")})
public class BaseArStatus implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Column(name = "month_date")
    @Temporal(TemporalType.DATE)
    private Date monthDate;
    @Basic(optional = false)
    @NotNull
    @Column(name = "ar_count")
    private double arCount;
    @Size(max = 50)
    @Column(name = "user_id")
    private String userId;
    @Column(name = "last_update_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastUpdateDate;

    public BaseArStatus() { }
//...

2 个答案:

答案 0 :(得分:5)

两个不同的类加载器正在加载该类的两个不同副本。当客户端代码“熟悉”该类的一个副本时,会获得一个对象,该对象是该类的另一个副本的实例,这就是您所获得的。

只有在两个类加载器加载了类时才会出现此问题。这可能会让它看起来断断续续;根据您通常无法控制的事件,其中一个类加载器可能已加载或未加载该类。根据我的经验,这是Java EE编程中最常见的问题,当然,这正是您正在做的事情。

答案 1 :(得分:0)

绝对听起来像是由不同的ClassLoader加载的类之间的比较。您可以使用Class.getClassLoader()方法来确认拒绝这一点。捕获异常并打印classA.getClassLoader()== classB.getClassLoader()。