JPA 是不是支持映射到 sql 视图?
Posted
技术标签:
【中文标题】JPA 是不是支持映射到 sql 视图?【英文标题】: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 扩展”的更多信息。 【参考方案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();
【讨论】:
以上是关于JPA 是不是支持映射到 sql 视图?的主要内容,如果未能解决你的问题,请参考以下文章
将 MySql 视图映射到 JPA 实体,使用哪个唯一 ID?
Mybatis/Hibernate/Spring Data Jpa选型对比