【发布时间】:2013-04-29 20:28:45
【问题描述】:
我目前正在尝试将遗留数据库架构(我无法轻易更改)映射到 JPA 1.0(提供程序是 Hibernate 3.3)。该模式是在磁盘空间非常宝贵的时代设计的,因此有几种情况会将多个不同的值打包到二进制字节数组中。例如,给定以下三个枚举:
enum ItemA { A, B, C }
enum ItemB { E, F }
enum ItemC { G, H, I, J }
这些将被压缩成一个单个位串列,其中:
- 前 2 位编码
ItemA(A = 0b01、B = 0b10、C = 0b11), - 下一位是
ItemB(0 = E,1 = F);和 - 接下来的 2 位是
ItemC(G = 0b00、H = 0b01、I = 0b10和J = 0b11)。
因此,为了映射它,我需要屏蔽每个 enum 的位范围,然后将其映射到相应的值。
更糟糕的是,每个enum 和enum 中的每个值使用的实际位位置和掩码取决于数据库中存储的其他一些配置表。唯一受支持的打包和解包这些值的方法是通过一组存储函数 (PL/SQL):
function pack_data(item_a in char(1), item_b in char(1), item_c in char(1)) returns raw...
function unpack_data_item_a(bit_string in raw) returns char(1) ..
function unpack_data_item_b(bit_string in raw) returns char(1) ..
etc
我当前的 JPA 映射如下所示:
@Entity
@Table(name = "some_table")
public class MyEntity {
@Id
@Column(name = "entity_id")
private Long id;
@Column(name = "bit_string")
private byte[] bitstring;
@Transient
private ItemA itemA;
@Transient
private ItemB itemB;
@Transient
private ItemC itemC;
...
}
问题是:如何在加载时自动填充(解包)这些 enum 字段,然后在插入/更新时再次自动将它们打包到位串中?如果它们被读取- 只有这样我才会将它们隐藏在视图中并将它们映射为只读。
可能的解决方案讨论:
我考虑过使用 @PrePersist/@PreUpdate 生命周期回调,但 Hibernate 文档说不要在这些回调中触摸 EntityManager,这使得访问数据库有些困难。我可以添加一个新的持久性单元并使用REQUIRES_NEW 事务来访问生命周期回调中的存储过程,也许?这似乎有点 hacky。
Hibernate 特定的 @SqlUpdate/@SqlInsert 注释是否可以覆盖 SQL 作为解决方案?这似乎是可能的,但我害怕依赖 Hibernate 期望绑定变量出现的(有点随意的)顺序 - 这随着时间的推移是否稳定?
编辑: 另一种可能性是使用视图进行读取并使用INSTEAD OF 触发器来填充位串。如果可能的话,我想避免这种情况,因为它对 JPA 是隐藏的,并且可能会混淆其他开发人员。
任何帮助表示赞赏!
【问题讨论】:
-
这个问题似乎在我不知情或未经我同意的情况下被编辑过。这是 SO 的常见行为吗?我对结果不感兴趣。
标签: hibernate jpa enums oracle11g