Это пример двунаправленной связи между объектами Java в веб-службе REST с API Джексона .
- Предположим, у нас есть двунаправленные отношения между двумя сущностями: Родителем и Ребенком.
- Использование MySQL Workbench для генерации файла схемы SQL для этих двух таблиц.
0102030405060708091011121314151617181920212223242526272829303132
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;
- Затем мы вставим некоторые данные в эти две таблицы с помощью этих операторов вставки:
123
INSERT INTO `bidirectional_schema`.`parent` (`PARENT_ID`, `PARENT_CONTENT`) VALUES (
'1'
,
'First Parent'
);
INSERT INTO `bidirectional_schema`.`child` (`CHILD_ID`, `CHILD_CONTENT`, `PARENT_PARENT_ID`) VALUES (
'1'
,
'First Child'
,
'1'
);
INSERT INTO `bidirectional_schema`.`child` (`CHILD_ID`, `CHILD_CONTENT`, `PARENT_PARENT_ID`) VALUES (
'2'
,
'Second Child'
,
'1'
);
- Зависимости Maven для API Джексона, необходимые для этого примера.
010203040506070809101112131415
<
dependency
>
<
groupid
>com.fasterxml.jackson.core</
groupid
>
<
artifactid
>jackson-annotations</
artifactid
>
<
version
>2.5.2</
version
>
</
dependency
>
<
dependency
>
<
groupid
>com.fasterxml.jackson.core</
groupid
>
<
artifactid
>jackson-core</
artifactid
>
<
version
>2.5.2</
version
>
</
dependency
>
<
dependency
>
<
groupid
>com.fasterxml.jackson.core</
groupid
>
<
artifactid
>jackson-databind</
artifactid
>
<
version
>2.5.2</
version
>
</
dependency
>
Кроме того, вы можете подобрать требуемые зависимости Java EE по этой ссылке: https://wikis.oracle.com/display/GlassFish/Java+EE+7+Maven+Coordinates
- Использование Eclipse для генерации сущностей из приведенных выше таблиц. Файл -> Создать -> Другое, затем в мастере выберите JPA Entities из таблиц. Появится мастер для создания соединения с уже созданной схемой. Затем выберите две таблицы: дочернюю и родительскую. Наконец убедитесь, что «Список сгенерированных классов в persistence.xml».
Вы можете продолжить и следовать настройкам по умолчанию, но я выбрал настройки отображения как показано ниже:
- В файле persistence.xml нет ничего особенного. Но есть два момента, которые следует учитывать. Во-первых, я не указывал поставщика постоянства, поскольку я склонен использовать WildFly, поэтому приложение будет использовать поставщик постоянства по умолчанию, который называется Hibernate. Во-вторых, я создал источник данных в WildFly, чтобы его можно было использовать для подключения к нашей схеме. В-третьих, я использовал EclipseLink, поэтому я использую этот JPA-провайдер org.eclipse.persistence.jpa.PersistenceProvider. Проверьте этот пост, чтобы указать WildFly на EclipseLink.
123456789
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
persistence
version
=
"2.1"
xmlns
=
"http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
>
<
persistence-unit
name
=
"BidirectionalPU"
>
<
provider
>org.eclipse.persistence.jpa.PersistenceProvider</
provider
>
<
jta-data-source
>java:jboss/datasources/Bidirectional_DataSource</
jta-data-source
>
<
class
>com.ithinkisink.entity.Child</
class
>
<
class
>com.ithinkisink.entity.Parent</
class
>
</
persistence-unit
>
</
persistence
>
- Первый класс, который мы реализуем, — это класс ApplicationConfiguration, который будет указывать на родительский путь наших будущих служб REST.
010203040506070809101112131415
package
com.ithinkisink;
import
javax.inject.Singleton;
import
javax.ws.rs.ApplicationPath;
import
javax.ws.rs.core.Application;
/**
*
* @author Belal
*
*/
@Singleton
@ApplicationPath
(
"rest"
)
public
class
ApplicationConfiguration
extends
Application {
}
- Затем мы создадим класс MyService, который будет иметь два веб-сервиса REST. Первый извлечет родителя с выбранными детьми. Второй вариант противоположен этому и будет извлекать ребенка с его родителями.
0102030405060708091011121314151617181920212223242526272829303132333435363738
package
com.ithinkisink.service;
package
com.ithinkisink.service;
import
javax.ejb.EJB;
import
javax.ws.rs.GET;
import
javax.ws.rs.Path;
import
javax.ws.rs.Produces;
import
javax.ws.rs.core.MediaType;
import
com.ithinkisink.entity.Child;
import
com.ithinkisink.entity.Parent;
/**
*
* @author Belal
*
*/
@Path
(
"MyService"
)
public
class
MyService {
@EJB
MyServiceDAO myServiceDAO;
@GET
@Path
(
"/retrieveParentWithChildren"
)
@Produces
(MediaType.APPLICATION_JSON)
public
Parent retrieveParentWithChildren() {
return
myServiceDAO.retrieveParentWithChildren();
}
@GET
@Path
(
"/retrieveChildWithParent"
)
@Produces
(MediaType.APPLICATION_JSON)
public
Child retrieveChildWithParent() {
return
myServiceDAO.retrieveChildWithParent();
}
}
- Затем мы создадим ServiceDAO и заметим, что EntityManager внедряется с подключением к постоянному модулю, который мы уже определили в файле persistence.xml. Я передал название единицы персистентности, чтобы прояснить этот момент. Но вы можете просто использовать аннотацию @PersistenceContext без указания атрибута unitName, тогда он будет использовать наш модуль постоянства, поскольку в нашем приложении не определено никакого другого модуля постоянства.
010203040506070809101112131415161718192021222324252627282930
package
com.ithinkisink.service;
import
javax.ejb.Stateless;
import
javax.persistence.EntityManager;
import
javax.persistence.PersistenceContext;
import
javax.persistence.Query;
import
com.ithinkisink.entity.Child;
import
com.ithinkisink.entity.Parent;
@Stateless
public
class
MyServiceDAO {
@PersistenceContext
(unitName=
"BidirectionalPU"
)
protected
EntityManager entityManager;
public
Parent retrieveParentWithChildren() {
int
parentId =
1
;
Query q = entityManager.createQuery(
"SELECT p FROM "
+
"Parent "
+
"p JOIN FETCH p.childs WHERE p.parentId = :parentId "
);
q.setParameter(
"parentId"
, parentId);
return
(q.getResultList().size() >
0
) ? (Parent) q.getResultList().get(
0
) :
null
;
}
public
Child retrieveChildWithParent() {
int
childId =
1
;
Query q = entityManager.createQuery(
"SELECT c FROM "
+
"Child "
+
"c JOIN FETCH c.parent WHERE c.childId = :childId "
);
q.setParameter(
"childId"
, childId);
return
(q.getResultList().size() >
0
) ? (Child) q.getResultList().get(
0
) :
null
;
}
}
- Теперь, когда наше приложение готово к тестированию, добавим его на сервер WildFly. Тогда запуск сервера должен быть успешным.
- Для простоты я использовал Postman для тестирования запущенных веб-сервисов REST. Итак, ниже приведены скриншоты из результатов на Почтальоне.
- Вы можете найти полный пример на моем Github по этой ссылке: https://github.com/belalgalal/Blogging/tree/master/BidirectionalRESTJson
Ссылка: | Двунаправленные отношения с Джексоном в веб-сервисах REST в WildFly от нашего партнера JCG Белала Галала в « Я думаю, я тону»! блог. |