【问题标题】:JPA 2.1 ConstructorResult Causing ClassCastExceptionJPA 2.1 ConstructorResult 导致 ClassCastException
【发布时间】:2014-12-10 02:49:49
【问题描述】:

我的结果集中的对象被转换为“对象”,而不是我在@SQLResultSetMapping 对象中指定的对象。

我正在尝试获取 ConstructorResult 的句柄,并创建了一个包含简单连接的查询,并尝试获取结果集并循环,尽管它打印出来以确保我做对了。但是,当我进入循环时,看起来应该是直截了当的。

当我声明结果列表时,它被强制转换为 type 。我单步执行查询测试类,它成功运行查询并将其加载到结果中,但结果列表中的项目键入为“对象”而不是 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 --

已编辑——显示它是如何放置在现有实体类中的。

已编辑——我尝试将数据类型添加到映射中的列列表中。它没有帮助。结果集中的每条记录仍被转换为 Hibernate 内某处的 java.lang.Object,它不会让我将其转换回 DTO。结果集映射被Hibernate绑定:

INFO:绑定结果集映射: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;
    }

最后是来自调试器的屏幕截图,将结果集显示为对象而不是 CommentInfoListItemDTO 对象。然而,正确的信息在对象中。

【问题讨论】:

  • 您的@SqlResultSetMapping 是否放在CommentInfoListItemDTO 上?如果是,则将其放在(任何)@Entity 类中,以便 JPA 提供者可以获取它。
  • 我没有将 @SqlResultSetMapping 放在 CommentInfoListItemDTO 上。我编辑了我的问题以表明我已将其添加到现有实体中。与此同时,我将创建一个数据库视图并在其上创建一个实体。我只是想要更轻量级的方式来进行连接以返回我需要的信息。我并不总是想从连接表中带回所有信息,以便将其呈现给用户......只是几个选择列。一个简单的查询结果集到一个对象不应该这么难弄清楚。只是沮丧。有点想知道其他人是否有同样的感觉。
  • 你对 DTO 的理由是完全有效的。
  • 你的 Eclipselink 版本是什么?
  • @BillR 我感觉到你的痛苦。我花了几天时间试图弄清楚,但还没有运气。

标签: java jpa jpa-2.1 sqlresultsetmapping


【解决方案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

Eclipse 链接: 我没有找到任何日志。

对映射的补充说明:使用 @ColumnResulttype 表示不明确的类型:

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

【讨论】:

  • 谢谢,我会检查日志并显式转换列结果列表。使用休眠 4.3.6。大约一年前开始做这件事时,我想使用 Eclipselink,但我使用的是 PostgreSQL,而 Eclipselink 的使用不如 Hibernate。
  • 按照您的建议设置变量类型,但仍然没有运气。 Hibernate 也找到了 POJO。 “INFO:绑定结果集映射:CommentInfoListItemDTOMapping”我将此作为 Hibernate 的错误输入。与此同时,我可能刚开始使用 MyBatis 进行这些类型的查询。配置完成后就更直接了。
  • 我向 Hibernate 提交的错误被那里的某个人链接到一个现有的错误。所以可能就是这样。 Hibernate ORM HHH-9445 JPA 2.1 ConstructorResult 导致 ClassCastException hibernate.atlassian.net/browse/HHH-9445
猜你喜欢
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
相关资源
最近更新 更多