【问题标题】:JPA: Read from view update tableJPA:从视图更新表中读取
【发布时间】:2012-01-29 02:07:33
【问题描述】:

是否可以让 JPA 从视图中读取实体,然后更新表。

举个例子:

我们有一个从 SuppliersInvoice_VW 读取的实体。 此视图和关联实体将包含 InvoiceNo、SupplierCode、SupplierName 和值。

用户看到以下内容:

发票编号:1234
供应商:乔斯五金
值:50

这让他意识到值应该是509,所以他相应地更新

发票编号:1234
供应商:乔斯五金
值:509

这会触发我们的 SuppliersInvoice 实体的更新。

我已映射@Table("SuppliersInvoice_vw"),这意味着它从 SuppliersInvoice_vw 读取数据,但这也意味着它将通过该视图进行更新。

有没有办法让 JPA 从视图中读取(SuppliersInvoice_vw)并更新表(SuppliersInvoice)?

另一种策略是只更新视图,但我一直被建议不要这样做。该建议是否具有性能基础,还是更像是“注意通过视图更新时可能出现的问题”。

【问题讨论】:

  • 你的意思是当用户在视图(例如网页)上更改某些内容时,JPA 会以某种方式直接检测更改并更新数据库?
  • @Mr.J4mes 不,我对用户界面不感兴趣。这是询问 JPA 是否可以从视图中读取然后更新表。
  • 没有。对于这种情况,JPA 中没有任何内容。

标签: java jpa


【解决方案1】:

我认为用 JPA 透明地做你想做的事情是不可能的。

JPA 规范只允许每个 @Entity 有一个 @Table。处理这个问题的最简单(也是最便携)的方法可能是拥有两个单独的@Entity 类,一个用于视图,一个用于表,具有相似的属性,并根据上下文选择使用哪一个重新阅读或写作。

如果属性对齐,您可以使用 commons BeanUtils.copyProperties 从视图一中初始化可写对象。

本质上,任何映射到数据库视图的只读实体都类似于 DTO,您可以这样对待它。

【讨论】:

    【解决方案2】:

    我之前在视图/表和实体方面遇到过同样的问题。我不知道您使用的是什么后端数据库,但就我而言,我运行的是 PostgreSQL 9.x。为了解决这个问题,我在数据库中创建了触发器,允许我在视图中插入或更新,然后通过触发器适当地更新视图后面的基础表。这样,您仍然可以像往常一样使用 JPA 更新您的 SuppliersInvoice 实体对象并保留更改,但后端数据库将根据您提供的更新适当地更新实际表。

    这是 PostgreSQL 9.1 中的 INSERT/UPDATE/DELETE rules 文档的链接,您可以自己查看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-02
      • 2012-01-01
      • 2019-08-12
      • 1970-01-01
      • 2016-04-11
      • 2018-02-08
      • 1970-01-01
      • 2013-12-16
      相关资源
      最近更新 更多