如何用 Hibernate 映射用户数据类型(复合类型)

Posted

技术标签:

【中文标题】如何用 Hibernate 映射用户数据类型(复合类型)【英文标题】:How to map User Data Type (Composite Type) with Hibernate 【发布时间】:2012-03-14 18:20:12 【问题描述】:

我对 Hibernate 世界很陌生。 我已经通过 ER CASE TOOL (TOAD) 对我的数据库进行了建模,并且我已经定义了几种用户数据类型(复合类型)。例如,假设我在 PostgreSQL 中有一个类型 Contact 声明如下

CREATE TYPE Contact AS
( "email" Varchar,
"phone" Varchar,
"mobile" Varchar,
"other" Varchar );

现在假设我像下面的 SQL 代码一样在用户实体上使用它

CREATE TABLE Users(
idUser Serial NOT NULL,
login Character varying(20) NOT NULL,
password Character varying(20) NOT NULL,
name Character varying(30),
surname Character varying(50),
contact Contact
)  

-- Add keys for table Users

ALTER TABLE Users ADD CONSTRAINT pkIdUser PRIMARY KEY (idUser)
;

我已配置并使用 Hibernate 工具对 ER 模型进行逆向工程,但我对 Contact 用户类型的定义有疑问,因为它被映射为 Serializable 而不是自定义类型,我想拥有什么是定义一个 Contact Hibernate UserType 并根据 Hibernate Tools 的 reverse.xml 文件进行更改.....但是当我尝试使用我的 UserType 实现时,我收到此消息:

"org.hibernate.cfg.JDBCBinderException:在表中找到的类型 it.mypackage.FullContactInfoType:用户列:fullcontactinfo 跨越多个列。只允许单个列类型。 在 Table: users column: fullcontactinfo 上找到的类型 it.mypackage.FullContactInfoType 跨越多个列。只允许单列类型。 "

您是否有一些关于如何实现此目的的简单示例的链接?直到现在我还不能映射用户数据类型...我正在考虑从 ER 模型中删除用户数据类型并分解它组成的字段。

我使用的是 Hibernate 3.5.4

提前致谢并感谢您的支持。

【问题讨论】:

【参考方案1】:

如果这能解决问题,请告诉我。这是一个postgres/hibernate实现的例子http://www.hibernatespatial.org/tutorial.html

或其他可能对这种情况有用的信息是:

我假设您已经使用实体注释声明了您的 Java 对象。创建一个扩展 Hibernate Usertype 对象的 ContactUsetype 对象。

public Object nullSafeGet(ResultSet resultSet, String[] email, String[] phone, String[] mobile, String[] other, Object owner)
throws HibernateException, SQLException 
assert email.length == 1;
assert phone.length == 1;
assert mobile.length==1;
assert other.length==1

if (resultSet.wasNull()) 
return null;

final Contact contactVariable = new Contact(resultSet.getObject(email[0]).toString()
                                       ,resultSet.getObject(phone[0]).toString(),
                                        resultSet.getObject(mobile[0]).toString(),
                                        resultSet.getObject(other[0]).toString());
return contactVariable;


public void nullSafeSet(PreparedStatement statement, Object value, int index)
throws HibernateException, SQLException 
statement.setObject(index, value);


最后当你创建用户对象时

Users user= new User(..., new Contact ("(some@email.com,123-456-4566,111-11-1111,aim)")

【讨论】:

嗨 Sathish 谢谢你的回答,我已经在玩 UserType 但我没有成功,当我在 reveng.xml 配置文件中声明与我的用户类型的映射时,我获得了一个org.hibernate.cfg.JDBCBinderException 正如我在帖子中所写的那样。我正在尝试对我已经通过 ER 建模的内容进行逆向工程......但是我会进一步研究你的建议并再次尝试这个解决方案......只是一个问题 nullSafeGet 的签名是(ResultSet resultSet ,字符串 [] 名称,对象所有者)而不是您报告的那个...或者我错过了什么?问候 你是正确的 nullSafeGet,没有意识到我为每个对象创建了一个数组,谢谢。另一项验证,如果您碰巧查看了hibernatespatial.org/tutorial.html 链接上的映射?有一个示例映射文件可能对同行评审有用。干杯。 实际上我已经开发了一个 RowEconder,它可以将任何对象图转换为 postgresql 用来定义结构的行格式,我成功地让它与我的 UserType 中的 PGObject 绑定,但是当我查看生成的 SQL 代码出错了,因为在它没有做的地方添加 '....当我给 PGObject setStringParameter 方法时,它在内部使用....所以这是结果 'ROW(ROW(''Italy'', ''Country'',''Via Test'',345,''00155''),ROW(''pippo@pippo.it'',null,null,null))' 而不是 ROW(ROW('Italy ','国家','Via Andrea Noale',345,'00155'),ROW('pippo@pippo.it',null,null,null))'.... 进一步看来,org.postgresql.jdbc2.AbstractJdbc2Statement 语句类在内部不支持 Types.STRUCT ....所以有人知道是否有支持它的替代 jdbc 驱动程序?

以上是关于如何用 Hibernate 映射用户数据类型(复合类型)的主要内容,如果未能解决你的问题,请参考以下文章

如何用 JPA/Hibernate 映射 XMLType

Hibernate配置文件和映射元素解释

Hibernate:复合主键 - 外键:如何在两个表之间映射各个字段

Hibernate 表映射 主键生成策略与复合主键

hibernate 复合主键映射

Hibernate复合主键映射