我想选择具有特定属性的实体.检索整个实体不是一个选项,因为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...
Run Code Online (Sandbox Code Playgroud)
这是用于数据访问的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;
}
}
Run Code Online (Sandbox Code Playgroud)
获得ClassCastException的原因是getAllGarbage查询不返回Garbage实例的集合.编写查询以专门返回与Garbage实例关联的值的子集,而不是完整的Garbage对象.如果调试方法,您可能会注意到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);
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是将原生查询更改为
select g from Garbage g
Run Code Online (Sandbox Code Playgroud)
这将导致返回一个完整的Garbage实例,允许您的原始代码按预期执行.
在旁注中,我建议不要像在示例代码中那样对每次访问Garbage实例执行类转换.这种技术为应用程序增加了不必要的开销,并使代码更难以长期维护.如果要多次使用已转换对象,请创建一个变量来存储已转换的实例并重复使用它.
| 归档时间: |
|
| 查看次数: |
2352 次 |
| 最近记录: |