JPA - 从计算列设置实体类属性?

时间:2010-05-28 09:20:53

标签: java postgresql jpa eclipselink

我正在使用在Glassfish 3上运行的简单Java Web应用程序来处理JPA(持久性提供程序是EclipseLink)。到目前为止,我真的很喜欢它(netbeans / glassfish交互中的错误除外)但是我希望能够做到这一点,我不知道该怎么做。

我有一个映射到数据库表(article)的实体类(Article)。我正在尝试对返回计算列的数据库执行查询,但我无法弄清楚如何设置Article类的属性,以便在调用查询时属性由列值填充。

如果我定期“选择id,title,body from article”查询,我会得到一个精美的Article对象列表,其中填充了id,title和body属性。这很好。

但是,如果我这样做:

Query q = em.createNativeQuery("select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc",Article.class);

(这是在Postgres上使用tsearch2进行全文搜索 - 这是一个特定于数据库的函数,所以我使用的是NativeQuery)

你可以看到我正在获取一个名为标题的计算列。如何向我的文章类添加标题属性,以便它被此查询填充?

到目前为止,我已经尝试将其设置为@Transient,但这最终会导致它始终为null。

2 个答案:

答案 0 :(得分:8)

可能没有好办法,只能手动:

Object[] r = (Object[]) em.createNativeQuery(
    "select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc","ArticleWithHeadline")
    .setParameter(...).getSingleResult();

Article a = (Article) r[0];
a.setHeadline((String) r[1]);

-

@Entity
@SqlResultSetMapping(
    name = "ArticleWithHeadline",
    entities = @EntityResult(entityClass = Article.class),
    columns = @ColumnResult(name = "HEADLINE"))
public class Article {
    @Transient
    private String headline;
    ...
}

答案 1 :(得分:2)

AFAIK,JPA不为计算属性提供标准化支持。使用Hibernate,可以使用Formula,但EclipseLink没有直接的等价物。 James Sutherland在Re: Virtual columns (@Formula of Hibernate)提出了一些建议:

  

没有直接的等价物(请   记录增强功能),但取决于   你想做什么,有办法   完成同样的事情。

     

EclipseLink定义了一个   TransformationMapping可以映射一个   来自多个字段的计算值   值,或访问数据库。

     

您可以覆盖任何CRUD的SQL   使用它的类的操作   描述符的DescriptorQueryManager。

     

你可以在你的身上定义一个VIEW   执行该功能的数据库   并将您的实体映射到视图   而不是表格。

     

你也可以进行小调   翻译使用转换器或   property get / set methods。

另请查看评论中使用DescriptorEventListener的解决方案的enhancement request

当然,所有这些都是非标准的JPA。