WildFly 中 REST Web 服务中与 Jackson 的双向关系

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

这是 REST Web 服务中 Java 实体与 Jackson API 之间 双向关系 的示例。

1- 假设我们在两个实体父子之间存在双向关系。

2- 使用 MySQL workbench 为这两个表生成 SQL 模式文件。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

3-然后我们将通过此插入语句向这两个表插入一些数据:


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

4- 此示例所需的 Jackson API 的 Maven 依赖项。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

此外,您可以从此链接获取所需的 Java EE 依赖项。
https://wikis.oracle.com/display/GlassFish/Java+EE+7+Maven+Coordinates
5- 使用 Eclipse 从上述表格中生成实体。
File -> New -> Other,然后从向导中选择 JPA Entities from Tables。将显示一个向导来创建与已创建架构的连接。然后选择child和parent这两个表。最后确保“List generated classes in persistence.xml”。

您可以继续并遵循默认设置,但我选择了如下映射设置:

6- persistence.xml 没什么特别的。但有两点需要考虑。首先,我没有指定持久性提供程序,因为我倾向于使用 WildFly,因此应用程序将使用默认的持久性提供程序,即 Hibernate。其次,我在 WildFly 上创建了一个数据源,以便它可以用于连接到我们的模式。第三,我使用了 EclipseLink,这就是我使用这个 JPA 提供程序 org.eclipse.persistence.jpa.PersistenceProvider 的原因。检查 帖子以将 WildFly 指向 EclipseLink。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

7- 我们将实现的第一个类是 ApplicationConfiguration 类,它将指向我们即将推出的 REST 服务的父路径。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

8- 然后我们将创建具有两个 REST Web 服务的 MyService 类。第一个将检索带有子项的父项。第二个与此相反,它将检索一个带有其父项的子项。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

9- 然后我们将创建 ServiceDAO 并注意到 EntityManager 被注入到我们已经在 persistence.xml 中定义的持久单元的连接。我通过了持久化单元的名称来明确这一点。但是您可以只使用注解@PersistenceContext 而无需指定 unitName 属性,那么它将使用我们的持久化单元,因为我们的应用程序中没有定义其他持久化单元。


 DROP SCHEMA IF EXISTS `bidirectional_schema` ;
CREATE SCHEMA IF NOT EXISTS `bidirectional_schema` DEFAULT CHARACTER SET utf8 ;
USE `bidirectional_schema` ;

-- Table bidirectional_schema.PARENT


DROP TABLE IF EXISTS bidirectional_schema.PARENT ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.PARENT ( PARENT_ID INT NOT NULL , PARENT_CONTENT VARCHAR(45) NULL , PRIMARY KEY (PARENT_ID) ) ENGINE = InnoDB;


-- Table bidirectional_schema.CHILD


DROP TABLE IF EXISTS bidirectional_schema.CHILD ;

CREATE TABLE IF NOT EXISTS bidirectional_schema.CHILD ( CHILD_ID INT NOT NULL , CHILD_CONTENT VARCHAR(45) NULL , PARENT_PARENT_ID INT NOT NULL , PRIMARY KEY (CHILD_ID) , INDEX fk_CHILD_PARENT_idx (PARENT_PARENT_ID ASC) , CONSTRAINT fk_CHILD_PARENT FOREIGN KEY (PARENT_PARENT_ID ) REFERENCES bidirectional_schema.PARENT (PARENT_ID ) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE = InnoDB;

10- 现在我们的应用程序已准备好进行测试,将其添加到 WildFly 服务器。然后启动服务器应该会成功。
11- 为了简单起见,我使用 Postman 来测试正在运行的 REST Web 服务。下面是 Postman 上的结果截图。


您可以从此链接在我的 Github 上找到完整示例:
https://github.com/belalgalal/Blogging/tree/master/BidirectionalRESTJson