Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 选择具有特定属性的实体时发生ClassCastException_Java_Jpa - Fatal编程技术网

Java 选择具有特定属性的实体时发生ClassCastException

Java 选择具有特定属性的实体时发生ClassCastException,java,jpa,Java,Jpa,我想选择具有特定属性的实体。检索整个实体不是一个选项,因为file属性返回一个字节[],这会降低应用程序的速度。但是它抛出ClassCastException 以下是实体: @NamedQuery(name = "findAllGarbage", query = "SELECT g.filename, g.description, g.uploadDate FROM Garbage g;") @Entity public class Garbage { @Id @GeneratedValue

我想选择具有特定属性的实体。检索整个实体不是一个选项,因为
file
属性返回一个
字节[]
,这会降低应用程序的速度。但是它抛出
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。方法
findallgarage()
是触发
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;
    }
}
@无状态(name=“ejbs/SearchEJB”)
公共类SearchEJB实现ISearchJB{
@持久上下文
私人实体管理者;
公共列表findallgarage(){
Query Query=em.createNamedQuery(“findallgarage”);
List gList=new ArrayList();
对于(对象o:query.getResultList()){
垃圾tmpG=新垃圾();
tmpG.setFilename(((垃圾)o.getFilename());
setUploadDate(((垃圾)o.getUploadDate());
setDescription(((垃圾)o).getDescription());
添加(tmpG);
}
返回闪光;
}
}

获取ClassCastException的原因是getAllGarbage查询不返回垃圾实例的集合。编写查询是为了专门返回与垃圾实例关联的值的子集,而不是完整的垃圾对象。如果调试该方法,您可能会注意到query.getResultsList()正在返回对象[]的集合。对象[]应与命名查询中指定的值相对应:文件名、说明和上载日期

下面是一个应该有效的结果使用示例

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
这将导致返回一个完整的垃圾实例,允许您的原始代码按预期执行


另一方面,我建议不要像在示例代码中所做的那样,对垃圾实例的每次访问都执行类强制转换。这种技术为应用程序增加了不必要的开销,并使代码更难长期维护。如果要多次使用铸造对象,请创建一个变量来存储铸造实例并重用它。

如果将文件信息设置为惰性,则不会降低应用程序的速度。当你有一个(或多个)包含大数据的字段时,这是一种常见的策略。

至于替代方案(顺便说一句,我也更喜欢),OP提到不知何故这不是一个选项,请参阅相关问题+答案:for loop修复了类强制转换异常。非常感谢。但糟糕的是,函数不起作用。我如何才能使实体中的一个属性不活跃?这也是一个好主意?@sfrj-检查Lob注释的文档,它们显示了这种确切的情况(因为Lob非常常见):