ClassCastException при выборе сущности с конкретными атрибутами - PullRequest
0 голосов
/ 30 марта 2011

Я хочу выбрать объект с определенными атрибутами. Извлечение всей сущности не является опцией из-за атрибута 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;
    }
}

Ответы [ 2 ]

5 голосов
/ 30 марта 2011

Причина, по которой вы получаете ClassCastException, заключается в том, что ваш запрос getAllGarbage не возвращает коллекцию экземпляров мусора. Запрос написан так, чтобы специально возвращать подмножество значений, связанных с экземпляром Garbage, а не полный объект Garbage. Если вы отладите метод, вы, вероятно, заметите, что query.getResultsList () возвращает коллекцию 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, как вы делаете в своем примере кода. Этот метод добавляет ненужные накладные расходы приложению и усложняет поддержку кода в долгосрочной перспективе. Если вы собираетесь использовать приведенный объект более одного раза, создайте переменную для хранения приведенного экземпляра и используйте его повторно.

1 голос
/ 30 марта 2011

Если вы сделаете информацию о файле ленивой, это не замедлит работу приложения. это общая стратегия, когда у вас есть поле (или поля), которое содержит большие данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...