【发布时间】:2022-10-07 19:43:05
【问题描述】:
这是我目前的回购结构,我正在寻找一种适用于 Postgres 和 OracleDB 的解决方案,并且最好不涉及更改我的数据库模式以适应 ORM。使用 Postgres 还是 Oracle 在 spring.datasource.url 文件中的 application.properties 中定义。
data class NewsCover(
@Id val tenantId: TenantId,
val openOnStart: Boolean,
val cycleDelay: Int,
@MappedCollection(idColumn = "tenant_id", keyColumn = "tenant_id")
val sections: Set<NewsCoverSection>,
)
data class NewsCoverSection(
@Id val id: NewsCoverSectionId,
val title: String,
val pinnedOnly: Boolean,
val position: Int,
val tenantId: TenantId,
... some other fields ...
)
interface NewsCoverRepo : CrudRepository<NewsCover, TenantId> { ... }
这适用于 Postgresql,但与 Oracle 一起使用时会产生错误:
SELECT "NEWS_COVER_SECTION"."ID" AS "ID", "NEWS_COVER_SECTION"."TITLE" AS "TITLE", "NEWS_COVER_SECTION"."POSITION" AS "POSITION", "NEWS_COVER_SECTION"."TENANT_ID" AS "TENANT_ID", "NEWS_COVER_SECTION"."PINNED_ONLY" AS "PINNED_ONLY"
FROM "NEWS_COVER_SECTION"
WHERE "NEWS_COVER_SECTION"."tenant_id" = ?
请参阅 @MappedCollection 中引用的 idColumn/keyColumn 名称。它们是小写的。这对 Postgres 来说很好,但不适用于 Oracle。将 tenant_id 更改为 TENANT_ID 可以解决 Oracle 的问题,但会破坏 Postgres。
我尝试了什么:
- Oracle 的NamingStrategy 覆盖,但我似乎无法覆盖那些引用的标识符。
- @MappedCollection 中的条件列名,但@MappedCollection 只接受编译时常量,不支持SpEL,所以我无法根据
spring.datasource.url属性进行区分。当数据库是 Postgres 和
"NEWS_COVER_SECTION"."TENANT_ID"当数据库是 Oracle 时,我有什么想法可以让它查询"news_cover_section"."tenant_id"吗?
【问题讨论】:
-
全部大写的查询在 Oracle 中应该可以正常工作。
-
我的问题是让它与 Postgres 和 Oracle 一起工作,这取决于哪个数据库被配置为数据源。我在 @MappedCollection 注释中引用了列标识符。
@MappedCollection(idColumn = "tenant_id", keyColumn = "tenant_id")与 Postgres 一起使用,@MappedCollection(idColumn = "TENANT_ID", keyColumn = "TENANT_ID")与 Oracle 一起使用。但两者都不适用于两个数据库。 -
你应该告诉你的混淆层绝不引用任何标识符。
-
谢谢,这似乎是目前最简单的解决方案。禁用 forceQuote 在其他地方产生了一些小问题,但这些问题很容易管理。
标签: spring postgresql oracle spring-data-jdbc