问题描述
我想选择一个具有特定属性的实体。
检索整个实体不是一种选择,因为file
属性返回一个byte[]
,这会降低应用程序的速度。
但是,它抛出ClassCastException
。
这是实体:
@NamedQuery(name = "findAllGarbage", query = "SELECT g.filename, g.description, g.uploadDate FROM Garbage g;")
@Entity
public class Garbage {
@Id
@GeneratedValue
@Column(nullable = false)
private Long id;
@Column(nullable = false)
private String filename;
@Column(nullable = false)
private String fileType;
@Column(nullable = false)
private String uploadDate;
@Column(nullable = false)
private String destroyDate;
@Lob
@Column(nullable = false)
private byte[] file;
@Column(nullable = false)
private String description;
//Getters and Setters...
这是用于数据访问的EJB。
方法findAllGarbage()
是触发ClassCastException
。
@Stateless(name = "ejbs/SearchEJB")
public class SearchEJB implements ISearchEJB {
@PersistenceContext
private EntityManager em;
public List<Garbage> findAllGarbage() {
Query query = em.createNamedQuery("findAllGarbage");
List<Garbage> gList = new ArrayList();
for (Object o : query.getResultList()) {
Garbage tmpG = new Garbage();
tmpG.setFilename(((Garbage) o).getFilename());
tmpG.setUploadDate(((Garbage) o).getUploadDate());
tmpG.setDescription(((Garbage) o).getDescription());
gList.add(tmpG);
}
return gList;
}
}
1楼
您收到ClassCastException的原因是,您的getAllGarbage查询不会返回垃圾实例的集合。 编写查询以专门返回与垃圾实例而不是完整垃圾对象关联的值的子集。 如果调试该方法,则可能会注意到query.getResultsList()返回Object []的集合。 Object []应对应于命名查询中指定的值:文件名,描述和上传日期。
这是应该使用结果用法的示例。
for (Object o : query.getResultList()) {
Object[] cols = (Object[]) o;
Garbage tmpG = new Garbage();
tmpG.setFilename(cols[0]);
tmpG.setDescription(cols[1]);
tmpG.setUploadDate(cols[2]);
gList.add(tmpG);
}
一种替代方法是将您的本机查询更改为
select g from Garbage g
这将导致返回完整的Garbage实例,从而使您的原始代码能够按预期执行。
附带说明一下,我建议您不要像在示例代码中那样对每次访问Garbage实例都执行类强制转换。 这种技术为应用程序增加了不必要的开销,并且从长远来看使代码难以维护。 如果要多次使用转换对象,请创建一个变量来存储转换实例并重新使用它。
2楼
如果使文件信息变得懒惰,则不会降低应用程序的速度。 当您的一个或多个字段包含大数据时,这是一种常见的策略。