JPA 2.1 ConstructorResult, вызывающий ClassCastException

Объекты в моем наборе результатов преобразуются в «Объект» вместо того, что я указал в объектах @SQLResultSetMapping.

Я пытаюсь получить дескриптор ConstructorResult и создал запрос, который содержит простое соединение, и пытаюсь получить набор результатов и выполнить цикл, хотя он распечатывает его, чтобы убедиться, что я прав. Однако, когда я добираюсь до цикла, то, что выглядит так, должно быть прямолинейным, но это не так.

Когда я объявляю список результатов, он приводится к типу . Я прохожу через тестовый класс запроса, и он успешно выполняет запрос и загружает его в результат, но элементы в списке результатов имеют тип «Объект», а не объекты CommentInfoListItemDTO. Поэтому, когда я добираюсь до цикла, он попадает в исключение приведения класса. Почему бы результат не привести к объектам CommentInfoListItemDTO? Особенно, когда это указано в @SQLResultSetMapping.

Код размещен ниже... Я обрезал некоторые имена столбцов, чтобы сократить их. Если это поможет добавить его обратно, дайте мне знать.

public List<CommentInfoListItemDTO> getCommentTitleListByPersonId(BigInteger personId) {
    String queryString = "select c.article_id, "
                        ***[columns removed for brevity]***
                        + "c.person_id as comment_person_id, "
                        + "a.party_id as aticle_party_id "
                        + "from article_comment c "
                        + "join article a "
                        + "on a.article_id = c.article_id "
                        + "where c.person_id = :personId";

    Query q = em.createNativeQuery(queryString, "CommentInfoListItemDTOMapping");
    q.setParameter("personId", personId);

    List<CommentInfoListItemDTO> commentInfoList = q.getResultList();

    ***[throws exception on the next line]***
    ***[java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com...CommentInfoListItemDTO]***

    for (CommentInfoListItemDTO listElement : commentInfoList){
            System.out.println("COMMENT TITLE LIST: " + listElement.toString());
        }
    return (commentInfoList);
}

@SqlResultSetMapping --

EDITED - чтобы показать, как это было помещено в существующий класс сущностей.

EDITED - я попытался добавить типы данных в список столбцов в сопоставлении. Это не помогло. Каждая запись в наборе результатов по-прежнему передается в java.lang.Object где-то внутри Hibernate, и это не позволяет мне вернуть ее обратно в DTO. Отображение набора результатов связано с Hibernate:

ИНФОРМАЦИЯ: сопоставление набора результатов привязки: CommentInfoListItemDTOMapping

@Entity
@SqlResultSetMapping(name = "CommentInfoListItemDTOMapping", classes = {
    @ConstructorResult(targetClass = CommentInfoListItemDTO.class,
            columns = {
            @ColumnResult(name = "article_id", type=BigInteger.class),
            @ColumnResult(name = "article_comment_id", type=BigInteger.class),
            @ColumnResult(name = "parent_comment_id", type=BigInteger.class),
            @ColumnResult(name = "article_title", type=String.class),
            @ColumnResult(name = "article_published", type=Boolean.class),
            @ColumnResult(name = "article_publish_date", type=Calendar.class),
            @ColumnResult(name = "article_availability_state", type=String.class),
            @ColumnResult(name = "article_enable_comments", type=Boolean.class),
            @ColumnResult(name = "comment_title", type=String.class),
            @ColumnResult(name = "comment_hide", type=Boolean.class),
            @ColumnResult(name = "comment_created_timestamp", type=Calendar.class),
            @ColumnResult(name = "comment_person_id", type=BigInteger.class),
            @ColumnResult(name = "aticle_party_id", type=BigInteger.class)
            })
})

@Table(name = "article_comment")
@NamedQueries({
    @NamedQuery(name = "ArticleComment.findAll", query = "SELECT e FROM ArticleComment e")})

public class ArticleComment implements Serializable {
...

ПОЖО

public class CommentInfoListItemDTO implements Serializable {

    private Integer id;
    private BigInteger articleId;
    private BigInteger articleCommentId;
    private BigInteger parentCommentId;
    private String articleTitle;
    private Boolean articlePublished;
    @Temporal(javax.persistence.TemporalType.DATE)
    private Calendar articlePublishDate;
    private String articleAvailabilityState;
    private Boolean articleEnableComments;
    private String commentTitle;
    private Boolean commentHide;
    @Temporal(javax.persistence.TemporalType.DATE)
    private Calendar commentCreatedTimestamp;
    private BigInteger commentPersonId;
    private BigInteger articlePartyId;

    public CommentInfoListItemDTO() {
    }

    public CommentInfoListItemDTO(BigInteger articleId, BigInteger articleCommentId, 
            BigInteger parentCommentId, String articleTitle, Boolean articlePublished, 
            Calendar articlePublishDate, String articleAvailabilityState, 
            Boolean articleEnableComments, String commentTitle, Boolean commentHide, 
            Calendar commentCreatedTimestamp, BigInteger commentPersonId, 
            BigInteger articlePartyId) {
        this.articleId = articleId;
        this.articleCommentId = articleCommentId;
        this.parentCommentId = parentCommentId;
        this.articleTitle = articleTitle;
        this.articlePublished = articlePublished;
        this.articlePublishDate = articlePublishDate;
        this.articleAvailabilityState = articleAvailabilityState;
        this.articleEnableComments = articleEnableComments;
        this.commentTitle = commentTitle;
        this.commentHide = commentHide;
        this.commentCreatedTimestamp = commentCreatedTimestamp;
        this.commentPersonId = commentPersonId;
        this.articlePartyId = articlePartyId;
    }

И, наконец, снимок экрана из отладчика, показывающий набор результатов как объекты, а не объекты CommentInfoListItemDTO. Однако правильная информация содержится в объектах.

И, наконец, снимок экрана из отладчика, показывающий набор результатов как объекты, а не объекты CommentInfoListItemDTO.


person Bill Rosmus    schedule 15.10.2014    source источник
comment
Ваш @SqlResultSetMapping надет на CommentInfoListItemDTO? Если да, то поместите его в (любой) класс @Entity, чтобы поставщик JPA мог его подобрать.   -  person zbig    schedule 15.10.2014
comment
Я не помещал @SqlResultSetMapping в CommentInfoListItemDTO . Я отредактировал свой вопрос, чтобы показать, что я добавил его к существующему объекту. Тем временем я создам представление базы данных и создам на нем сущность. Мне просто нужен более легкий способ соединения, чтобы вернуть нужную мне информацию. Я не всегда хочу возвращать каждый бит информации из объединенных таблиц, чтобы представить ее пользователю... всего несколько выбранных столбцов. Простой набор результатов запроса к объекту не должен быть таким сложным для понимания. Просто расстроен. Любопытно узнать, чувствуют ли другие то же самое.   -  person Bill Rosmus    schedule 15.10.2014
comment
Ваше обоснование DTO совершенно справедливо.   -  person zbig    schedule 16.10.2014
comment
Какая у вас версия Eclipselink?   -  person zbig    schedule 16.10.2014
comment
@BillR Я чувствую твою боль. Я потратил дни, пытаясь что-то понять, но пока безуспешно.   -  person jeff    schedule 13.03.2015
comment
Я вернул данные с помощью MyBatis. Он был прост в использовании/настройке. Я решил, что для быстрого поиска это проще в использовании, чем JPA. Я буду продолжать использовать JPA для львиной доли, но MyBatis для презентационных данных, которые JPA извлекает из задницы   -  person Bill Rosmus    schedule 08.04.2015


Ответы (1)


java.lang.ClassCastException: [Ljava.lang.Object; нельзя привести к YourDTO

возникает, когда EclipseLink не может найти имя YourDTO, переданное в

em.createNativeQuery("SELECT...","YourDTO");

Исключение, выдаваемое Hibernate в подобной ситуации:

org.hibernate.MappingException: Unknown SqlResultSetMapping [someNonExistingMappingName]

Вы должны убедиться, что YourDTO зарегистрирован вашим поставщиком сохраняемости. Как? Наблюдайте за своими журналами:

Спящий режим:

DEBUG annotations.ResultsetMappingSecondPass — сопоставление набора результатов привязки: YourDTO

EclipseLink: я не нашел никаких журналов для этого.

Еще одно замечание к вашему сопоставлению: используйте @ColumnResult с type для неоднозначных типов:

@ColumnResult(name = "article_publish_date", type=Calendar.class)
@ColumnResult(name = "article_id", type=BigInteger.class)
person zbig    schedule 16.10.2014
comment
Спасибо, я проверю журналы и явно приведу список результатов столбца. Использование спящего режима 4.3.6. Я хотел использовать Eclipselink, когда начал это дело год назад или около того, но я использую PostgreSQL, и Eclipselink не работает с ним так же хорошо, как с Hibernate. - person Bill Rosmus; 16.10.2014
comment
Установите типы переменных, как вы предложили, но все равно не повезло. Также Hibernate обнаружил файл POJO. ИНФОРМАЦИЯ: сопоставление набора результатов привязки: CommentInfoListItemDTOMapping Я ввел это как ошибку с Hibernate. Тем временем я мог бы просто начать использовать MyBatis для этих типов запросов. Это намного проще, как только конфигурация завершена. - person Bill Rosmus; 17.10.2014
comment
Ошибка, которую я отправил в Hibernate, была связана кем-то там с существующей ошибкой. Так что может быть просто так. Hibernate ORM HHH-9445 JPA 2.1 ConstructorResult, вызывающий ClassCastException hibernate.atlassian.net/browse/HHH-9445< /а> - person Bill Rosmus; 17.10.2014