我有一个遗留数据库,我正在尝试重新设计以适应 21 世纪。现有的数据结构之一涉及包含二维值矩阵的特定类。如果我要从数据库对此类进行逆向工程,我最终会得到一系列属性,例如:
private BigDecimal NODE_1_MATRIX_POS_1_1;
private BigDecimal NODE_1_MATRIX_POS_1_2;
等等。由于这是一个 6x6 矩阵,因此有很多这样的列。
我一直在寻找更好的方法,但我不确定我是否在那里。我想做的是这样的:
@Entity
public class TestClass {
@Id
private long id;
@CollectionOfElements
@JoinTable(
name="MATRIX_DATA",
joinColumns=@JoinColumn(name="ENTRY_ID"))
private List<List<BigDecimal>> matrix;
但这失败了:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: MATRIX_DATA, for columns: [org.hibernate.mapping.Column(element)]
我想我应该四处询问并尝试找到正确的方法来解决此映射,而不是仅仅尝试修复错误挑战。有人对通过 JPA 映射多维数组感到成功和满意吗?
I have a legacy database I'm trying to redesign into the 21st century. One of the existing data structures involves a particular class which contains a 2-dimensional matrix of values. If I were to reverse-engineer this class from the database, I'd end up with a series of attributes like:
private BigDecimal NODE_1_MATRIX_POS_1_1;
private BigDecimal NODE_1_MATRIX_POS_1_2;
and so on. Since this is a 6x6 matrix, there are a lot of such columns.
I've been looking for a better way, but I'm not sure I'm there. What I'd like to do is something like this:
@Entity
public class TestClass {
@Id
private long id;
@CollectionOfElements
@JoinTable(
name="MATRIX_DATA",
joinColumns=@JoinColumn(name="ENTRY_ID"))
private List<List<BigDecimal>> matrix;
But this fails:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: MATRIX_DATA, for columns: [org.hibernate.mapping.Column(element)]
Rather than just trying to fix the error, I thought I'd ask around and try to find the right approach to solving this mapping challenge. Has anyone found success and satisfaction mapping multidimensional arrays via JPA?
发布评论
评论(2)
AFAIK,标准 JPA 不支持嵌套集合。 JPA wiki 书中有关于这个主题的很好的部分(我只引用了其中的一部分):
这就是我的建议。例如:
MatrixLine
的位置(省略许多细节):或者也许您可以使用自定义用户类型(我不太确定这将如何工作)。
或者(毕竟,您已经在使用不可移植注释)看看这个问题,看看如何扩展 Hibernate:
Map>
,使用 hibernate JPA 注释?AFAIK, nested collections are not supported by standard JPA. The JPA wiki book has a good section on this topic (I'm quoting only a part of it):
And that would be my suggestion. For example:
Where
MatrixLine
would be (omitting many details):Or maybe you could use a custom user type (I'm not too sure how this would work).
Or (after all, you're already using non portable annotations) have a look at this question to see how you could extend Hibernate:
Map<Key,List<Values>>
, with hibernate JPA annotations?Hypersistence Utils 项目
您可以使用 Hypersistence Utils 项目映射 PostgreSQL 多维数组。
您可以选择在实体属性端使用Java数组或使用
List
。数据库表
例如,假设您有以下
plane
数据库表:其中
seat_status
是 PostgreSQL 枚举:JPA 实体
您可以映射
seatGrid
使用EnumArrayType
的列:因此,您需要声明要使用的适当的 Hibernate 类型。对于枚举,您需要使用
EnumArrayType
:@Type
注释允许您将参数传递给 Hibernate 类型,就像 SQL 数组类一样:测试时间
现在,当您持久化以下
Post
实体:Hibernate 将发出正确的 SQL INSERT 语句:
并且,在获取实体时,一切都会按预期工作:
Hypersistence Utils project
You can map a PostgreSQL multidimensional array using the Hypersistence Utils project.
You can choose to use a Java array on the entity attribute side or use
List
.Database table
For example, assuming you have the following
plane
database table:Where the
seat_status
is a PostgreSQL enum:JPA entity
You can map the
seatGrid
column using theEnumArrayType
:So, you need to declare the appropriate Hibernate Type to use. For enums, you need to use the
EnumArrayType
:The
@Type
annotation allows you to pass parameters to the Hibernate Type, like the SQL array class:Testing time
Now, when you persist the following
Post
entity:Hibernate will issue the proper SQL INSERT statement:
And, when fetching the entity, everything works as expected: