Vertica 集成 Hibernate:连接指南¶
关于 Vertica 连接指南¶
Vertica 连接指南提供将第三方合作伙伴产品连接到 Vertica 的基本说明。连接指南基于我们在特定版本的 Vertica 和合作伙伴产品上的测试。
Vertica 与 Hibernate:软件版本¶
本文档基于 Hibernate 5.4.1 与 Vertica 9.2 的测试结果。
要求¶
使用 Hibernate 与 Vertica 需要:
- JDK 8.0 或更高版本
- VerticaDialect.jar
- Hibernate 5 或更高版本
- Vertica 客户端 9.0 或更高版本
- Vertica 服务器 9.0 或更高版本
Hibernate 概述¶
Hibernate 是 Java 编程语言的 ORM(对象-关系映射)工具。Hibernate 提供了将面向对象的领域模型映射到关系数据库的框架。Hibernate 是免费的开源软件。
使用 VerticaDialect 与 Hibernate¶
Hibernate 方言(dialect)指定底层数据库的 SQL 方言,以便 Hibernate 生成适当的 SQL 语句。
本文档引导您完成创建基于控制台�� Hibernate 应用程序的过程。使用此应用程序通过 VerticaDialect 建立到 Vertica 数据库的连接,并执行所有 CRUD 操作,包括插入、删除和简单 SQL 语句。
本文档使用以下 SQL 语句作为示例:
SELECT class_desc, Item_DESC, sum(units_received)
FROM lookup_item, Inventory_orders
WHERE lookup_item.item_nbr = Inventory_ORDERS.item_id
GROUP BY class_desc, Item_DESC
ORDER BY class_desc, Item_DESC
搭建环境¶
下载和安装 Hibernate¶
从 https://sourceforge.net/projects/hibernate/files/hibernate-orm/ 下载 Hibernate 发行版,按照 Hibernate 安装向导的说明安装。
下载和安装 JDK¶
按照 Oracle 网站上的说明下载和安装 Java Development Kit (JDK)。
下载 Vertica 客户端驱动¶
- 导航至 Vertica 网站上的 Client Drivers 页面
- 下载 JDBC 驱动程序包(注意:有关客户端和服务器兼容性的详细信息,请参阅 Vertica 文档)
- 将 Vertica JDBC .jar 文件复制到客户端外部库目录
下载 VerticaDialect.jar¶
- 右键点击此链接
- 选择 Save link as... 将 VerticaDialect.jar 保存到您的计算机
- 将 VerticaDialect.jar 复制到客户端外部库目录
创建 Hibernate 映射文件¶
必须创建 Hibernate 映射文件,以便 Hibernate 可以加载和存储持久化类的对象。映射文件告诉 Hibernate 将哪些数据库表和列映射到 Java 类。
在本示例中,将为两个表创建类对象映射:Inventory_Orders 表和 Lookup_Item 表。还包括两个对象之间的关联。
InventoryOrders.hbm.xml¶
Item.hbm.xml¶
创建 Java 持久化类¶
InventoryOrders.java¶
package com.sample;
public class InventoryOrders {
float item_id;
float units_received;
public float getItem_id() { return item_id; }
public void setItem_id(float item_id) { this.item_id = item_id; }
public float getUnits_received() { return units_received; }
public void setUnits_received(float units_received) { this.units_received = units_received; }
}
Item.java¶
package com.sample;
public class Item {
float item_nbr;
String class_desc;
String item_desc;
InventoryOrders inventoryorders;
public InventoryOrders getInventoryorders() { return inventoryorders; }
public void setInventoryorders(InventoryOrders inventoryorders) { this.inventoryorders = inventoryorders; }
public float getItem_nbr() { return item_nbr; }
public void setItem_nbr(float item_nbr) { this.item_nbr = item_nbr; }
public String getClass_desc() { return class_desc; }
public void setClass_desc(String class_desc) { this.class_desc = class_desc; }
public String getItem_desc() { return item_desc; }
public void setItem_desc(String item_desc) { this.item_desc = item_desc; }
}
创建配置文件条目¶
Hibernate 配置文件 (hibernate.cfg.xml)¶
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.vertica.jdbc.Driver</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.connection.url">jdbc:vertica://<host>:<port>/<database></property>
<property name="hibernate.connection.username">dbadmin</property>
<property name="hibernate.dialect">org.hibernate.dialect.VerticaDialect</property>
<property name="hibernate.show_sql">true</property>
</session-factory>
</hibernate-configuration>
创建主类¶
package com.sample;
import java.util.Iterator;
import org.hibernate.Query;
import org.hibernate.Session;
public class TestHibernate {
public static void main(String[] args) {
Session session = SessionFactoryUtil.getSessionFactory().openSession();
session.beginTransaction();
queryInventory(session);
System.out.println("done");
}
private static void queryInventory(Session session) {
Query query = session.createQuery(
"select a.class_desc, a.item_desc, sum(b.units_received) " +
"from Item a, InventoryOrders b " +
"where a.item_nbr = b.item_id " +
"group by a.class_desc, a.item_desc " +
"order by a.class_desc, a.item_desc");
System.out.println("Class Desc \t\t Item Desc \t\t Total Unit");
for (Iterator it = query.iterate(); it.hasNext();) {
Object[] row = (Object[]) it.next();
System.out.print(row[0]);
System.out.print("\t\t" + row[1]);
System.out.print("\t\t" + row[2]);
System.out.println();
}
session.close();
}
}
构建和运行 Hibernate 应用程序¶
构建和运行命令¶
使用以下命令编译和运行(需要将所有依赖 jar 添加到 classpath):
java -cp "C:\Hibernate\lib\antlr-2.7.7.jar";"C:\Hibernate\lib\classmate-1.3.4.jar";
"C:\Hibernate\lib\commons-collections-3.2.1.jar";"C:\Hibernate\lib\dom4j-2.1.1.jar";
"C:\Hibernate\lib\byte-buddy-1.9.5.jar";"C:\Hibernate\lib\FastInfoset-1.2.15.jar";
"C:\Hibernate\lib\hibernate-commons-annotations-5.1.0.Final.jar";
"C:\Hibernate\lib\hibernate-jpa-2.1-api-1.0.0.Final.jar";
"C:\Hibernate\lib\jandex-2.0.5.Final.jar";"C:\Hibernate\lib\javassist-3.24.0.GA.jar";
"C:\Hibernate\lib\jboss-logging-3.3.2.Final.jar";
"C:\Hibernate\lib\jboss-transaction-api_1.2_spec-1.1.1.Final.jar";
"C:\Hibernate\lib\slf4j-api-1.5.8.jar";"C:\Hibernate\lib\VerticaDialect.jar";
"C:\Hibernate\lib\vertica-jdbc-9.2.0-0.jar";"C:\Hibernate\lib\hibernate-core-5.4.1.Final.jar";
"C:\Hibernate\lib\istack-commons-runtime-3.0.7.jar";
"C:\Hibernate\lib\javax.activation-api-1.2.0.jar";
"C:\Hibernate\lib\javax.persistence-api-2.2.jar";"C:\Hibernate\lib\jaxb-api-2.3.1.jar";
"C:\Hibernate\lib\jaxb-runtime-2.3.1.jar";"C:\Hibernate\lib\stax-ex-1.8.jar";
"C:\Hibernate\lib\txw2-2.3.1.jar" com.sample.TestHibernate
使用 VerticaDialect 的自定义函数¶
要添加 Hibernate 4 支持的 VerticaDialect 自定义函数,创建一个扩展 VerticaDialect 的 Java 类并注册函数:
package org.hibernate.dialect;
import org.hibernate.dialect.VerticaDialect;
import org.hibernate.dialect.function.NvlFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;
public class VerticaDialectCustom extends VerticaDialect {
public VerticaDialectCustom() {
super();
registerFunctions();
}
protected void registerFunctions() {
registerFunction("substring", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
registerFunction("bit_length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "vsize(?1)*8"));
registerFunction("coalesce", new NvlFunction());
}
}
使用 CustomVerticaDialect 的 hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.vertica.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.CustomVerticaDialect</property>
...
</session-factory>
</hibernate-configuration>
Hibernate 批处理操作¶
Hibernate 批量插入将大量结果集作为一批记录上传到 Vertica 数据库,而不是每次插入单行时都上传。
在配置中设置批处理大小:
batch_size 的值取决于对象大小和总结果集数量。
已知限制¶
由于 Vertica 是 OLAP 数据库,不完全遵循 OLTP 数据库的所有特性,Hibernate 不维护主键的唯一性。
尝试以下操作时 Hibernate 会报错:
-
插入重复记录到主键表:
org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session -
表包含重复数据时删除记录:Hibernate 执行基于主键的 DELETE,但表中可能存在重复数据
注意: 可以通过使用 Vertica 9.x 引入的 Constraint Enforcement Parameters 来避免此问题。启用此参数后,Vertica 强制主键和唯一键约束,Hibernate 可以正常工作。
更多信息¶
- Hibernate
- Vertica Community Edition
- Vertica User Community
- Vertica Documentation
截图¶

原文来源:https://www.vertica.com/kb/HPE-Vertica-Integration-with-Hibernate-Connection-Guide/Content/Partner/HPE-Vertica-Integration-with-Hibernate-Connection-Guide.htm