【问题标题】:Does JPA support mapping to sql views?JPA 是否支持映射到 sql 视图?
【发布时间】:2010-10-13 06:35:51
【问题描述】:

我目前正在使用 Eclipselink,但我知道现在大多数 JPA 实现已经非常标准化。是否有将 JPA 实体映射到视图的本地方法?我不打算插入/更新,但问题实际上是如何处理 @Id 注释。 JPA 世界中的每个实体都必须有一个 ID 字段,但是我创建的许多视图并不符合这一点。 JPA 中是否有对此的本机支持,或者我是否需要使用 hack 来使其工作?我进行了很多搜索,但发现关于这样做的信息很少。

【问题讨论】:

  • 视图功能与普通表一样,但是如果您的视图不适合 JPA ORM 映射,您可以改为使用存储过程来返回由视图形成的自定义游标。您可以使用 @NamedStoredProcedureQuery 注释在 EclipseLink 中映射存储过程。有关此 Google 的“EclipseLink 扩展”的更多信息。

标签: java sql orm jpa view


【解决方案1】:

虽然使用带有直接支持类型的字段的 @Id 注释并不是指定实体身份的唯一方法(请参阅带有多个 @Id 注释的 @IdClass 或带有 @Embedded 的 @EmbeddedId),JPA 规范每个实体都需要一个主键。

也就是说,您不需要实体就可以将 JPA 与数据库视图一起使用。由于从 SQL 角度映射到视图与映射到表没有什么不同,因此您仍然可以使用本机查询(EntityManager 上的createNativeQuery)来检索标量值。

【讨论】:

  • JPA 库截至 2020 年 10 月抛出运行时异常“不是托管实体”
【解决方案2】:

我自己一直在研究这个,我发现了一个我不是 100% 确定作品但看起来很有希望的 hack。

在我的例子中,我在视图中有一个 FK 列,它可以有效地充当 PK —— 该外来对象的任何给定实例只能在视图中出现一次。我从一个字段中定义了两个对象:一个被指定为 ID,代表字段的原始值,另一个被指定为只读,代表被引用的对象。


@Id
@Column(name = "foreignid", unique = true, nullable = false)
public Long getForeignId() {
...

@OneToOne
@JoinColumn(name = "foreignid", insertable=false, updatable=false)
public ForeignObject getForeignObject() {
...

就像我说的,我不能 100% 确定这个答案(如果它不起作用,我会删除这个答案),但它让我的代码超过了一个特定的崩溃点。

不知道它是否适用于您的具体情况。而且很有可能在 11 个月后,您不再关心。 :-) 什么鬼,“死灵法师”徽章不只是靠自己挣来的......

【讨论】:

    【解决方案3】:

    在我看来,我有一个“唯一”的 id,所以我将它映射为实体 id。 效果很好:

    @Entity
    @Table(name="table")
    @NamedQuery(name="Table.findAll", query="SELECT n FROM Table n")
    public class Table implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @Id
        @Column(name="column_a")
        private int columnA;
    

    【讨论】:

      【解决方案4】:

      JPA - 2.5.4

          CREATE MATERIALIZED VIEW IF NOT EXISTS needed_article as select  product_id, count(product_id) as count from product_article group by product_id;
          CREATE MATERIALIZED VIEW IF NOT EXISTS available_article as select product_id, count(product_id) as count from article a inner join  product_article p
                                      on  a.id = p.article_id and a.stock >= p.amount_of group by product_id;
          
          CREATE UNIQUE INDEX productId_available_article ON available_article (product_Id);
          CREATE UNIQUE INDEX productId_needed_article ON needed_article (product_Id);
      

      Entity.java

      @Entity
      @Immutable // hibernate import
      @Getter
      @Setter
      public class NeededArticle {
          @Id
          Integer productId;
          Integer count;
      }
      

      Repository.java

      @Repository
      public interface AvailableProductRepository extends CrudRepository<AvailableArticle, Integer> {
      
          @Query("select available.productId from AvailableArticle available, NeededArticle needed where available.productId = needed.productId and available.count = needed.count")
          List<Integer> availableProduct();
      

      【讨论】:

        猜你喜欢
        • 2011-04-18
        • 2012-07-04
        • 2015-11-15
        • 2015-06-19
        • 1970-01-01
        • 2019-10-14
        • 1970-01-01
        • 2011-04-30
        • 1970-01-01
        相关资源
        最近更新 更多