如何根据父属性使用过滤器进行 @OneToOne 映射?
我正在编写一个应用程序,该应用程序可以直接只读访问最初在 Ruby on Rails 应用程序中使用的旧数据库。数据库很大,但这是我想在 Hibernate 中进行映射的部分。
有一个表,其中有 item_type
字段,该字段是 item1
、item2
、item3
之一代码> 还有 item_id
字段。它取决于 item_type
字段的值。例如,如果 item_type
为 item1
,则 item_id
表示 item1
表中的 ID。 这些表没有外键并且根本没有连接。
问题是,如何使 item1
、item2
和 item3
映射当且仅当 item_type
被设置为相应的值。例如,如果 item_type
设置为 item2
,则 Reference
的 item2
字段具有对 item 对象的引用,并且另外两个(item1
,item3
)是null
:
@Entity
@Getter
@StandardException
@NoArgsConstructor
@Table(name = "reference")
class Reference extends PanacheEntity {
@Column(name = "field_a")
private String fieldA;
@OneToOne(fetch = FetchType.LAZY)
private Item1 item1;
@OneToOne(fetch = FetchType.LAZY)
private Item2 item2;
@OneToOne(fetch = FetchType.LAZY)
private Item3 item3;
}
我尝试使用@JoinColumnOrFormula
+ @JoinFormula
注释,但它似乎不适合这样做。 referencedColumnName
必须是 item1
表的列。但我需要指定 reference
表中的列。
@OneToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(value = "'item1'", referencedColumnName = "item_type")),
@JoinColumnOrFormula(column = @JoinColumn(name = "item_id", referencedColumnName = "id"))
})
private Item1 item1;
我尝试的另一个选项是 @Where 注释,如下所示:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id", referencedColumnName = "id")
@Where(clause = "item_type = 'item1'")
private Item1 item1;
但 hibernate 仍然假设该子句是针对 item
表的。它产生错误的sql,其中item_type
是来自错误表的引用,如下所示:
select <here goes field list>
from reference r
join item1 i1 on i1.id = r.item_id
and i1.item_type = 'item1' -- wrong! item_type column is in the reference table, not in item1
我也尝试了@Where(clause = "reference.item_type = 'item1'")
但仍然没有运气,它只是忽略注释,就好像它不存在一样。
有什么想法吗?这是可行的吗?
I'm writing an application that has direct and readonly access to a legacy database which initially is used in Ruby on Rails app. The DB is huge, but here is part that I want to make a mapping for in Hibernate.
There is a table that has item_type
field, which is one of item1
, item2
, item3
And there is also item_id
field. It depends on the value of the item_type
field. For example, if item_type
is item1
, then item_id
means ID from item1
table.
The tables have no foreign keys and are not connected at all.
The question is, how do I make so that item1
, item2
and item3
mapped if and only if the item_type
is set to the corresponding value. For example, if item_type
set to item2
, then item2
field of Reference
has reference to the item object and the other two (item1
, item3
) are null
:
@Entity
@Getter
@StandardException
@NoArgsConstructor
@Table(name = "reference")
class Reference extends PanacheEntity {
@Column(name = "field_a")
private String fieldA;
@OneToOne(fetch = FetchType.LAZY)
private Item1 item1;
@OneToOne(fetch = FetchType.LAZY)
private Item2 item2;
@OneToOne(fetch = FetchType.LAZY)
private Item3 item3;
}
I tried to use @JoinColumnOrFormula
+ @JoinFormula
annotation, but it does not seem to be suited for that. referencedColumnName
must be the column of the item1
table. But I need to specify column from reference
table.
@OneToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula = @JoinFormula(value = "'item1'", referencedColumnName = "item_type")),
@JoinColumnOrFormula(column = @JoinColumn(name = "item_id", referencedColumnName = "id"))
})
private Item1 item1;
The other option I tried is @Where
annotation, like this:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id", referencedColumnName = "id")
@Where(clause = "item_type = 'item1'")
private Item1 item1;
But hibernate still assumes that the clause is for the item
table. It produces wrong sql, where item_type
is being references from the wrong table, like this:
select <here goes field list>
from reference r
join item1 i1 on i1.id = r.item_id
and i1.item_type = 'item1' -- wrong! item_type column is in the reference table, not in item1
I tried also @Where(clause = "reference.item_type = 'item1'")
but still no luck, it just ignores the annotation as if it was not there.
Any ideas? Is it doable at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论