Using Blaze-Persistence

Blaze-Persistence 提供一个流畅的查询构建器 API,在 Jakarta Persistence 之上,利用深入的 Hibernate ORM 集成,可以在 Jakarta Persistence 模型的范围内使用高级 SQL 功能,比如常用表格表达式。

Blaze-Persistence offers a fluent query builder API on top of Jakarta Persistence with a deep Hibernate ORM integration that enables the use of advanced SQL features like Common Table Expressions while staying in the realm of the Jakarta Persistence model.

除此之外,Blaze-Persistence Entity-View 模块允许进行 DTO 定义,可以将其应用于业务逻辑查询,然后将这些查询转换为优化的查询,仅提取构建 DTO 实例所需的数据。相同的 DTO 定义还可以用于应用数据库更新,从而大幅减少样板代码,并且不需要对象映射工具。

On top of that, the Blaze-Persistence Entity-View module allows for DTO definitions that can be applied to business logic queries which are then transformed to optimized queries that only fetch the data that is needed to construct the DTO instances. The same DTO definitions can further be used for applying database updates, leading to a great reduction in boilerplate code and removing the need for object mapping tools. Unresolved directive in blaze-persistence.adoc - include::{includes}/platform-include.adoc[]

Setting up and configuring Blaze-Persistence

该扩展为 CriteriaBuilderFactoryEntityViewManager 附带有默认的生产者,这些生产者在提供一个可用的 Hibernate ORM 配置时可以开箱即用。对于定制,可以通过 Quarkus CDI reference 中记录的标准机制覆盖默认生产者。如果您需要设置自定义的 Blaze-Persistence properties,则需要这样做。

The extension comes with default producers for CriteriaBuilderFactory and EntityViewManager that work out of the box given a working Hibernate ORM configuration. For customization, overriding of the default producers is possible via the standard mechanism as documented in the Quarkus CDI reference. This is needed if you need to set custom Blaze-Persistence properties.

在 Quarkus 中,您只需:

In Quarkus, you just need to:

  • @Inject CriteriaBuilderFactory or EntityViewManager and use it

  • annotate your entity views with @EntityView and any other mapping annotation as usual

添加以下依赖关系到您的项目:

Add the following dependencies to your project:

  • the Blaze-Persistence extension: com.blazebit:blaze-persistence-integration-quarkus-3

  • further Blaze-Persistence integrations as needed:

Example dependencies using Maven
<!-- Blaze-Persistence specific dependencies -->
<dependency>
    <groupId>com.blazebit</groupId>
    <artifactId>blaze-persistence-integration-quarkus-3</artifactId>
</dependency>
<dependency>
    <groupId>com.blazebit</groupId>
    <artifactId>blaze-persistence-integration-hibernate-6.2</artifactId>
    <scope>runtime</scope>
</dependency>
Using Gradle
implementation("com.blazebit:blaze-persistence-integration-quarkus-3")
runtimeOnly("com.blazebit:blaze-persistence-integration-hibernate-6.2")

在本地映像中使用需要依赖项实体视图注释处理器,该处理器可能提取到一个单独的 `native`配置文件中:

The use in native images requires a dependency on the entity view annotation processor that may be extracted into a separate native profile:

<profiles>
    <profile>
        <id>native</id>
        <dependencies>
            <dependency>
                <groupId>com.blazebit</groupId>
                <artifactId>blaze-persistence-entity-view-processor-jakarta</artifactId>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </profile>
</profiles>

根据通过 Hibernate-ORM extension提供的已配置 EntityManagerFactory,将创建 CriteriaBuilderFactory`和 `EntityViewManager

A CriteriaBuilderFactory and an EntityViewManager will be created based on the configured EntityManagerFactory as provided by the Hibernate-ORM extension.

您之后可以通过注入访问这些 Bean:

You can then access these beans via injection:

Example application bean using Hibernate
@ApplicationScoped
public class SantaClausService {
    @Inject
    EntityManager em; 1
    @Inject
    CriteriaBuilderFactory cbf; 2
    @Inject
    EntityViewManager evm; 3

    @Transactional 4
    public List<GiftView> findAllGifts() {
        CriteriaBuilder<Gift> cb = cbf.create(em, Gift.class);
        return evm.applySetting(EntityViewSetting.create(GiftView.class), cb).getResultList();
    }
}
1 Inject the EntityManager
2 Inject the CriteriaBuilderFactory
3 Inject the EntityViewManager
4 Mark your CDI bean method as @Transactional so that a transaction is started or joined.
Example Entity
@Entity
public class Gift {
    private Long id;
    private String name;
    private String description;

    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="giftSeq")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
Example Entity-View
@EntityView(Gift.class)
public interface GiftView {

    @IdMapping
    Long getId();

    String getName();
}
Example updatable Entity-View
@UpdatableEntityView
@CreatableEntityView
@EntityView(Gift.class)
public interface GiftUpdateView extends GiftView {

    void setName(String name);
}
Example Jakarta REST Resource
@Path("/gifts")
public class GiftResource {
    @Inject
    EntityManager entityManager;
    @Inject
    EntityViewManager entityViewManager;
    @Inject
    SantaClausService santaClausService;

    @POST
    @Transactional
    public Response createGift(GiftUpdateView view) {
        entityViewManager.save(entityManager, view);
        return Response.created(URI.create("/gifts/" + view.getId())).build();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<GiftView> getGifts() {
        return santaClausService.findAllGifts();
    }

    @PUT
    @Path("{id}")
    @Transactional
    public GiftView updateGift(@EntityViewId("id") GiftUpdateView view) {
        entityViewManager.save(entityManager, view);
        return entityViewManager.find(entityManager, GiftView.class, view.getId());
    }

    @GET
    @Path("{id"})
    @Produces(MediaType.APPLICATION_JSON)
    public GiftView getGift(Long id) {
        return return entityViewManager.find(entityManager, GiftView.class, view.getId());
    }
}

Blaze-Persistence configuration properties

有各种可选属性可用于优化您的 EntityViewManager`和 `CriteriaBuilderFactory,或指导 Quarkus 的猜测。

There are various optional properties useful to refine your EntityViewManager and CriteriaBuilderFactory or guide guesses of Quarkus.

只要 Hibernate ORM 扩展配置正确,就没有必需属性。

There are no required properties, as long as the Hibernate ORM extension is configured properly.

如果没有设置属性,则应用 Blaze-Persistence 默认值。

When no property is set, the Blaze-Persistence defaults apply.

此处列出的配置属性允许您覆盖这些默认值,并自定义和调整各个方面。

The configuration properties listed here allow you to override such defaults, and customize and tune various aspects.

Unresolved directive in blaze-persistence.adoc - include::{includes}/quarkus-blaze-persistence.adoc[]

除这些配置选项外,还可以通过观察事件 `CriteriaBuilderConfiguration`或 `EntityViewConfiguration`并对这些对象应用自定义,来应用进一步的配置和自定义。可在 Quarkus section of the entity-view documentation中找到各种自定义用例。

Apart from these configuration options, further configuration and customization can be applied by observing a CriteriaBuilderConfiguration or EntityViewConfiguration events and applying customizations on these objects. The various customization use cases can be found in the Quarkus section of the entity-view documentation.

Example CriteriaBuilderConfiguration and EntityViewConfiguration observing
@ApplicationScoped
public class BlazePersistenceConfigurer {

    public void configure(@Observes CriteriaBuilderConfiguration config) {
        config.setProperty("...", "...");
    }

    public void configure(@Observes EntityViewConfiguration config) {
        // Register custom BasicUserType or register type test values
        config.registerBasicUserType(MyClass.class, MyClassBasicUserType.class);
    }
}

Limitations

Apache Derby

Blaze-Persistence currently does not come with support for Apache Derby. This limitation could be lifted in the future, if there’s a compelling need for it and if someone contributes it.