JPA 2.1 ConstructorResult导致ClassCastException [英] JPA 2.1 ConstructorResult Causing ClassCastException

查看:168
本文介绍了JPA 2.1 ConstructorResult导致ClassCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的结果集中的对象被强制转换为'Object'而不是我在@SQLResultSetMapping对象中指定的对象。

The objects in my resultset are being cast to 'Object' instead of what I specified in the @SQLResultSetMapping objects.

我正在尝试处理ConstructorResult并创建了一个包含简单连接的查询,并尝试获取结果集并循环,但是将其打印出来以确保我正确。然而,当我进入循环时看起来应该是直截了当的不是。

I'm trying to get a handle on ConstructorResult and have created a query which contains a simple join and am trying to get the result set and loop though it printing it out to make sure I have it right. However when I get to the loop what looks like it should be straight forward isn't.

当我声明结果列表时,它被转换为类型。我逐步执行查询测试类,它成功运行查询并将其加载到结果中,但结果列表中的项目已键入Object而不是CommentInfoListItemDTO对象。因此,当我进入循环时,它会遇到类强制转换异常。为什么不将结果强制转换为CommentInfoListItemDTO对象?特别是在@SQLResultSetMapping中具体说明。

When I declare the result list it is cast to be of type . I step through the query test class and it successfully runs the query and loads it into the result, but the items in the results list have typed as 'Object' rather than CommentInfoListItemDTO objects. So when I get to the loop, it hits a class cast exception. Why wouldn't the result be cast to CommentInfoListItemDTO objects? Especially when this is specificied in the @SQLResultSetMapping.

代码发布在下面......我截断了一些列名,只是为了缩短它们。如果它有助于将其添加回来让我知道。

The code is posted below... I truncated some of the column names just to shorten them up. If it would help to add it back in let me know.

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 -

@SqlResultSetMapping --

EDITED - 显示它是如何放置在现有实体类中的。

EDITED -- to show how this was placed in an existing entity class.

EDITED - 我尝试将数据类型添加到映射中的列列表中。它没有帮助。结果集中的每个记录仍然被转换为在Hibernate内部的某个java.lang.Object,它不会让我把它强制转换回DTO。结果集映射由Hibernate绑定:

EDITED -- I tried adding the data types to the column listing in the mapping. It didn't help. Each record in the resultset is still being cast to java.lang.Object somewhere inside Hibernate and it won't let me cast it back to the DTO. The resultsetmapping is being bound by Hibernate:


INFO:绑定结果集映射:CommentInfoListItemDTOMapping

INFO: Binding resultset mapping: 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 {
...

POJO

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;
    }

最后一个来自调试器的screengrab将结果集显示为Objects而不是CommentInfoListItemDTO对象。然而,正确的信息在对象中。

And finally a screengrab from the debugger showing the resultset as Objects rather than CommentInfoListItemDTO objects. The correct information is in the objects however.

推荐答案


java .lang.ClassCastException:[Ljava.lang.Object;无法转换为YourDTO

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to YourDTO

当EclipseLink找不到 YourDTO

c $ c>传递给

is thrown when the EclipseLink can't find the name of YourDTO passed to the

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

Hibernate在类似情况下抛出的异常是:

The exception thrown by Hibernate in similar situation is:

org.hibernate.MappingException: Unknown SqlResultSetMapping [someNonExistingMappingName]

您必须确保持久性提供商注册了 YourDTO 如何?观察你的日志:

You have to ensure that YourDTO is registered by your persistence provider. How? Observe your logs:

Hibernate:

Hibernate:


DEBUG annotations.ResultsetMappingSecondPass - 绑定结果设置映射:YourDTO

DEBUG annotations.ResultsetMappingSecondPass - Binding result set mapping: YourDTO

EclipseLink:
我没有找到任何日志。

EclipseLink: I didn't find any logs for that.

对映射的另一个注释:对于不明确的类型,使用 @ColumnResult 类型

One additional remark to your mapping: Use @ColumnResult with type for ambiguous types:

@ColumnResult(name = "article_publish_date", type=Calendar.class)
@ColumnResult(name = "article_id", type=BigInteger.class)

这篇关于JPA 2.1 ConstructorResult导致ClassCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆