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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2927836/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-20 00:09:04  来源:igfitidea点击:

JPA - Setting entity class property from calculated column?

javapostgresqljpaeclipselink

提问by growse

I'm just getting to grips with JPA in a simple Java web app running on Glassfish 3 (Persistence provider is EclipseLink). So far, I'm really liking it (bugs in netbeans/glassfish interaction aside) but there's a thing that I want to be able to do that I'm not sure how to do.

我刚刚在 Glassfish 3 上运行的简单 Java Web 应用程序中掌握 JPA(持久性提供程序是 EclipseLink)。到目前为止,我真的很喜欢它(除了 netbeans/glassfish 交互中的错误),但有一件事情我希望能够做到,但我不知道该怎么做。

I've got an entity class (Article) that's mapped to a database table (article). I'm trying to do a query on the database that returns a calculated column, but I can't figure out how to set up a property of the Article class so that the property gets filled by the column value when I call the query.

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

If I do a regular "select id,title,body from article" query, I get a list of Article objects fine, with the id, title and body properties filled. This works fine.

如果我执行常规的“从文章中选择 id、标题、正文”查询,我会得到一个很好的文章对象列表,其中填充了 id、标题和正文属性。这工作正常。

However, if I do the below:

但是,如果我执行以下操作:

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

(this is a fulltext search using tsearch2 on Postgres - it's a db-specific function, so I'm using a NativeQuery)

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

You can see I'm fetching a calculated column, called headline. How do I add a headline property to my Article class so that it gets populated by this query?

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

So far, I've tried setting it to be @Transient, but that just ends up with it being null all the time.

到目前为止,我已经尝试将它设置为@Transient,但最终它始终为空。

回答by axtavt

There are probably no good ways to do it, only manually:

可能没有好的方法可以做到,只能手动:

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

回答by Pascal Thivent

AFAIK, JPA doesn't offer standardized support for calculated attributes. With Hibernate, one would use a Formulabut EclipseLink doesn't have a direct equivalent. James Sutherland made some suggestions in Re: Virtual columns (@Formula of Hibernate)though:

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

There is no direct equivalent (please log an enhancement), but depending on what you want to do, there are ways to accomplish the same thing.

EclipseLink defines a TransformationMapping which can map a computed value from multiple field values, or access the database.

You can override the SQL for any CRUD operation for a class using its descriptor's DescriptorQueryManager.

You could define a VIEW on your database that performs the function and map your Entity to the view instead of the table.

You can also perform minor translations using Converters or property get/set methods.

没有直接的等价物(请记录增强功能),但是根据您想要做什么,有多种方法可以完成相同的事情。

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

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

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

您还可以使用转换器或属性获取/设置方法执行次要翻译。

Also have a look at the enhancement requestthat has a solution using a DescriptorEventListenerin the comments.

还可以查看在评论中使用 a 的解决方案的增强请求DescriptorEventListener

All this is non standard JPA of course.

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