比较器抛出奇怪的 ClassCastException:pkg.MyClass 无法转换为 pkg.MyClass
我正在使用 Comparator
按 viewscoped 托管 bean 中的属性(Date
类型)对 List
进行排序。
问题是我不断收到 ClassCastException
如下 -
java.lang.ClassCastException:pkg.db.BaseArStatus 无法转换为 pkg.db.BaseArStatus。
为什么无法将 BaseArStatus
转换为 BaseArStatus
?是因为BaseArStatus
是一个Entity
吗?
这个问题对我来说真的很奇怪,因为我并不是每次都得到异常。在构建和部署应用程序时,大多数工作正常(运行没有任何问题),但有时(即使我做同样的事情 - 构建和部署)它在运行时失败,并出现 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() { }
//...
I am using a Comparator
to sort a List<Entity>
by it's property (of type Date
) in viewscoped managed bean.
The problem is that I keep getting the ClassCastException
as follows -
java.lang.ClassCastException: pkg.db.BaseArStatus cannot be cast to pkg.db.BaseArStatus.
Why is it not able to cast BaseArStatus
to BaseArStatus
? Is it because BaseArStatus
is an Entity
?
The problem is really strange to me because I am not getting the exception every time. Most of the it works fine (runs without any problem) when build and deploy the application but sometimes (even though I am doing the same thing - build and deploy) it fails at runtime with the ClassCastException
.
Why is this happening only sometimes and not all the time? Is it because I am using it in managed bean?
This is how the managed bean looks like -
@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());
}
});
//...
And the entity 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() { }
//...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
两个不同的类加载器正在加载该类的两个不同副本。当“熟悉”该类的一个副本的客户端代码获取一个作为该类的另一个副本的实例的对象时,这就是您所得到的。
仅当两个类加载器都加载了该类时才会出现此问题。这会让它看起来断断续续;根据您通常无法控制的事件,类加载器之一可能已加载该类,也可能未加载该类。根据我的经验,这是 Java EE 编程中最常见的问题,当然,这正是您正在做的事情。
Two different classloaders are loading two different copies of the class. When client code "familiar" with one copy of the class gets an object that's an instance of the other copy of the class, this is what you get.
The problem will only occur if the class has been loaded by both classloaders. This can make it seem intermittent; depending on events you often have no control over, one of the classloaders may or may not have loaded the class. In my experience, this is a problem most commonly seen in Java EE programming, which, of course, is what you're doing.
听起来绝对像是不同类加载器加载的类之间的比较。您可以使用 Class.getClassLoader() 方法来为我们确认是否拒绝此操作。捕获异常并打印是否 classA.getClassLoader() == classB.getClassLoader()。
Definitely sounds like a comparison between classes loaded by different ClassLoaders. You can use the Class.getClassLoader() method to confirm on deny this for us. Catch the Exception and print whether or not classA.getClassLoader() == classB.getClassLoader().