2010-05-28 39 views
5

我刚开始与JPA交手在Glassfish上运行3一个简单的Java Web应用程序(持久性提供者的EclipseLink)。到目前为止,我真的很喜欢它(虫子在NetBeans/GlassFish实现交互除外),但有,我希望能够做到这一点,我不知道如何做的事情。JPA - 从计算列设置实体类属性?

我已经得到了被映射到数据库表(文章)的实体类(文章)。我试图做一个返回计算列在数据库上查询,但我想不出如何设置Article类的属性,这样的属性,都会被列值填充当我打电话查询。

如果我做一个普通的“选择ID,标题,正文从文章”查询,我得到的第一个对象列表细末,用充满了ID,标题和正文属性。这工作正常。

但是,如果我做了如下:

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一个全文搜索 - 这是一个特定的DB-功能,所以我使用的是NativeQuery)

你可以看到我正在读取一个名为标题的计算列。如何将标题属性添加到我的Article类中,以便它通过此查询填充?

到目前为止,我已经尝试将其设定为@Transient,但只是同在一处空所有的时间结束。

回答

7

可能不会有好的办法做到这一点,只能手动:

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

据我所知,JPA不提供计算属性标准化的支持。有了Hibernate,可以使用Formula,但EclipseLink没有直接的等价物。詹姆斯·萨瑟兰在Re: Virtual columns (@Formula of Hibernate)提出了一些建议,但:

没有直接等价(请 日志增强),但根据 你想要做什么,有办法 完成同样的事情。

的EclipseLink限定 TransformationMapping其可以从多个现场 值映射一个 计算值,或访问数据库。

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

你可以在执行功能 您 数据库定义视图和你的实体映射到视图 而不是表。

您还可以使用转换器或 属性获取/设置方法执行较小的 转换。

也看看enhancement request有注解中使用DescriptorEventListener的解决方案。

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