DataNucleus jpa适配华为云&Gaussdb

举报
yd_282553764 发表于 2024/12/11 10:12:00 2024/12/11
【摘要】 文章介绍使用DataNucleus 和 JPA ,适配华为云&Gaussdb

DataNucleus 和 JPA 介绍

1. DataNucleus

概述

DataNucleus 是一个开源的 Java 数据持久化框架,支持多种持久化 API 和数据存储,具有极高的灵活性和扩展性。它是 Java 持久化生态的一部分,主要用来管理应用程序与数据存储之间的交互。

主要特性

1. 支持多种 API

JPA (Java Persistence API):用于对象关系映射 (ORM)。

JDO (Java Data Objects):Java 数据对象的规范。

REST 和 JSON:支持通过 REST API 持久化数据。

2. 支持多种数据存储

关系型数据库:MySQL、PostgreSQL、Oracle、SQL Server 等。

NoSQL 数据库:MongoDB、Cassandra、HBase 等。

文件系统、Excel 文件和其他非传统存储。

3. 增强机制

提供代码增强(Enhancement),用于优化字节码,以提高延迟加载和代理性能。

4. 灵活的配置

支持 XML 配置和注解的混合使用。

可扩展性强,可根据需求添加自定义插件。

优点

支持多种数据库类型,适合复杂项目。

提供对 JPA 和 JDO 的完整实现,兼容性强。

允许开发者在一个框架中同时使用关系型和 NoSQL 数据存储。

缺点

社区相对较小,问题解决可能需要更多时间。

相比 Hibernate 或 EclipseLink,学习曲线较高。

2. JPA (Java Persistence API)

概述

JPA 是 Java 的官方持久化标准,定义了对象与关系数据库之间的映射。它是一种规范,没有具体实现,需要通过实现框架(如 Hibernate、EclipseLink 或 DataNucleus)来工作。

核心概念

1. Entity(实体)

Java 类通过注解(如 @Entity)被映射为数据库表。

2. EntityManager

核心接口,用于管理实体的生命周期(如增删改查)。

3. Persistence Unit

定义数据源和 JPA 配置的单元,通常在 persistence.xml 文件中配置。

4. JPQL(Java Persistence Query Language)

类似于 SQL,但面向对象,用于查询和操作实体。

常用实现

1. Hibernate

最流行的 JPA 实现之一,功能强大,支持广泛。

2. EclipseLink

Oracle 提供的 JPA 参考实现,功能全面。

3. DataNucleus

支持 JPA 的完整实现,适合多数据存储场景。

优点

简化了持久化操作,屏蔽了数据库差异。

提供标准化 API,提高了框架的可移植性。

支持多种查询方式(JPQL、Criteria API)。

缺点

依赖具体的实现框架。

需要对 ORM 和数据库映射有一定的理解。

DataNucleus 和 JPA 的关系

DataNucleus 是 JPA 的实现之一:它提供了对 JPA 标准的完整支持,并在此基础上扩展了对非关系型存储的支持。

JPA 是一个规范,DataNucleus 是实现:类似于 Java Servlet 规范与 Tomcat 的关系。

使用场景对比


特性 DataNucleus JPA (规范)

目标 提供全面的数据存储支持,包括关系型和非关系型存储。 提供对象与关系数据库的标准化持久化接口。

灵活性 支持多种存储类型,灵活性极高。 灵活性取决于具体实现(如 Hibernate 或 EclipseLink)。

学习曲线 相对较高,功能强大,但复杂度高。 较易上手,简单场景可以快速开发。

社区支持 社区较小,资料相对较少。 社区活跃,生态丰富(基于实现)。

性能优化 提供增强功能,适合性能调优。 优化取决于具体实现。


步骤1:fork 仓库

本次任务是使用jpa规范和datanucleus在欧拉os上测试否则正常运行。

fork demo的仓库,demo中有基于servicecomb实现的完整的微服务脚实例,仓库信息如下:

https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiDemoJava/overview

步骤2:本地编译并运行

主要步骤:

  • 执行mvn clean install -DskipTests

步骤3:适配思路

集成datanucleus和jpa相关的jar包,在demo上增加一个查询接口,测试是否可行。

官方文档如下:https://www.datanucleus.org/products/accessplatform/jdo/tutorial.html#step4

我的适配项目:https://gitcode.com/chenzhida/opensource-demo-datanucleus-jpa-241209/overview

分支:dev_datanucleus_jpa

步骤3:适配过程的问题

与jdo不同的是,jdo需要执行mvn datanucleus:enhance进行增强,而通过jpa只是部分需要增强。

增强的常见场景

1. 字段级延迟加载(Lazy Loading):如果你在实体类中配置了 @Basic(fetch = FetchType.LAZY)@OneToMany(fetch = FetchType.LAZY) 等延迟加载策略,增强是必须的。

2. JDO 使用场景:如果你使用的是 JDO 而不是纯 JPA,也需要增强。

3. 提升性能:DataNucleus 的增强机制可以减少运行时代理的开销,提升性能。


问题1:这个错误 org.hibernate.LazyInitializationException 是一个典型的 Hibernate 懒加载异常,表示在尝试访问懒加载的属性时,Session 已经关闭或者不可用。这里的关键问题是:在 Student 实体的 age 属性被 Jackson 序列化时,Hibernate 试图延迟加载数据,但没有有效的 Session

Caused by: org.hibernate.LazyInitializationException: could not initialize proxy [org.apache.servicecomb.fence.resource.Student#1] - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:314) ~[hibernate-core-6.5.2.Final.jar:6.5.2.Final]

解决:避免直接返回实体,使用 DTO 或 VO 映射需要的数据:

public class StudentDTO {
    private String name;
    private int age;

    public StudentDTO(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
@Transactional
public StudentDTO getStudentDTO(Long id) {
    Student student = studentRepository.findById(id).orElseThrow();
    return new StudentDTO(student.getName(), student.getAge());
}

步骤4:购买华为云Gaussdb和ECS,上云测试

购买华为云Gaussdb,并且购买公网IP,不然无法访问。配置如下:

产品名称

产品类型

数据库引擎版本

性能规格

实例类型

部署形态

备注

云数据库 GaussDB

基础版

8.201

独享型1:4

集中式

1主2备

推荐


产品名称 CPU架构 实例类型 公共镜像 镜像版本 备注
弹性云服务器 鲲鹏计算 鲲鹏通用计算增强型 Huawei Cloud EulerOS Huawei Cloud EulerOS 2.0 标准版 64位 ARM版(10GiB) 推荐


步骤5:部署并访问

结果如下:




【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。