Blaze-Persistenceの使用
Blaze-Persistenceは、Jakarta Persistenceの上に流暢なクエリビルダAPIを提供し、Hibernate ORMとの深い統合により、Jakarta Persistenceモデルの領域に留まりながらCommon Table Expressionsなどの高度なSQL機能を使用することができます。
さらに、Blaze-Persistence Entity-Viewモジュールは、ビジネスロジッククエリに適用出来るDTO定義を可能にし、そのクエリはDTOインスタンスを構築するために必要なデータのみを取得する最適化されたクエリに変換されます。同じDTO定義をデータベースの更新にも使用することができます。これにより、ボイラプレートコードが大幅に削減され、オブジェクトマッピングツールの必要性がなくなります。
このエクステンションはサードパーティによって開発されたもので、Quarkus Platformの一部です。 |
Blaze-Persistenceのセットアップと設定
このエクステンションには、 CriteriaBuilderFactory
と EntityViewManager
のデフォルトプロデューサーが付属しており、動作する Hibernate ORM 設定があればすぐに動作します。カスタマイズのために、 Quarkus CDIリファレンス に記載されている標準的なメカニズムを使用して、デフォルトのプロデューサーをオーバーライドすることができます。これは、カスタムの Blaze-Persistenceプロパティー を設定する場合に必要です。
Quarkusでは、以下を実施するだけです:
-
@Inject
CriteriaBuilderFactory
またはEntityViewManager
を使用します -
エンティティービューに
@EntityView
やその他のマッピングアノテーションを通常通りにアノテーションします
以下の依存関係をプロジェクトに追加してください:
-
Blaze-Persistence エクステンション:
com.blazebit:blaze-persistence-integration-quarkus
-
必要に応じて、さらにBlaze-Persistenceの統合を行います:
-
Jackson の場合、
blaze-persistence-integration-jackson
-
Jakarta REST の場合、
blaze-persistence-integration-jaxrs
-
<!-- Blaze-Persistence specific dependencies -->
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-quarkus</artifactId>
</dependency>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-integration-hibernate-5.6</artifactId>
<scope>runtime</scope>
</dependency>
implementation("com.blazebit:blaze-persistence-integration-quarkus")
runtimeOnly("com.blazebit:blaze-persistence-integration-hibernate-5.6")
ネイティブイメージでの使用には、別の native
プロファイルに抽出される可能性のあるエンティティービューアーノテーションプロセッサーへの依存関係が必要です:
<profiles>
<profile>
<id>native</id>
<dependencies>
<dependency>
<groupId>com.blazebit</groupId>
<artifactId>blaze-persistence-entity-view-processor</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
</profiles>
CriteriaBuilderFactory
と EntityViewManager
は、 Hibernate-ORM エクステンション で提供される設定済の EntityManagerFactory
に基づいて作成されます。
その後、注入によってこれらのBeanにアクセスすることができます:
@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 | EntityManager を注入 |
2 | CriteriaBuilderFactory を注入 |
3 | EntityViewManager を注入 |
4 | トランザクションが開始またはトランザクションに参加されるように、CDI Beanメソッドを @Transactional としてマークします。 |
@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;
}
}
@EntityView(Gift.class)
public interface GiftView {
@IdMapping
Long getId();
String getName();
}
@UpdatableEntityView
@CreatableEntityView
@EntityView(Gift.class)
public interface GiftUpdateView extends GiftView {
void setName(String name);
}
@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の設定プロパティー
EntityViewManager
と CriteriaBuilderFactory
を洗練させたり、またはQuarkusの推測をガイドするのに便利な様々なオプションのプロパティーがあります。
Hibernate ORMエクステンションが適切に設定されている限り、必須のプロパティーはありません。
プロパティーが設定されていない場合は、Blaze-Persistenceのデフォルトが適用されます。
ここに記載されている設定プロパティーでは、このようなデフォルトを上書きしたり、様々な面をカスタマイズしたり調整したりすることができます。
ビルド時に固定される設定プロパティ - その他の設定プロパティは実行時にオーバーライド可能です。
型 |
デフォルト |
|
---|---|---|
起動時にすべてのビューテンプレートキャッシュを準備することを可能にするブール値フラグ。デフォルトでは、起動時のパフォーマンスを向上させるためにビューテンプレートのイーガーローディングは無効になっています。このプロパティーに有効な値は Show more |
boolean |
|
エンティティービューの属性のデフォルトバッチサイズを定義する整数値です。デフォルトでは、この値は 1 であり、 Show more |
int |
|
相関値、ビュールート、埋め込みビューのバッチングが期待されるかを指定するモードです。デフォルトでは Show more |
string |
|
エンティティー表示アップデーターキャッシュをスタートアップで準備することを可能にするブールフラグ。デフォルトでは、スタートアップパフォーマンスを向上するために、エンティティー表示更新の一括読み込みが無効化されています。このプロパティーに使用できる値は、 Show more |
boolean |
|
所有されている関係の更新可能なエンティティー表示タイプを使用できないようにする厳格な検証を無効にできるブール値のフラグ。デフォルトでは、できないように設定されています ( Show more |
boolean |
|
更新可能または作成可能なエンティティ・ビューをカスケード属性に関連付ける前に、カスケード属性以外の属性に設定することを禁止する厳密なカスケード・チェックを無効にするためのブール値フラグです。無効にすると、Jakarta Persistenceのように、更新可能なエンティティ・ビューが更新をカスケードする属性と関連付けられていない場合に、そのビューに加えられた変更がフラッシュされない可能性があります。デフォルトでは、このプロパティは有効であり、デフォルト値は Show more |
boolean |
|
厳密なカスケードチェックが有効なときに、無効な複数の属性セッターに遭遇したときに、警告からブートタイム検証エラーに切り替えることができるブール値フラグです。 Show more |
boolean |
|
Show more |
boolean |
|
— 完全修飾式キャッシュ実装クラス名 — |
string |
|
trueに設定すると、CTEクエリーはデフォルトでインライン化されます。このプロパティに有効な値は Show more |
boolean |
これらの設定オプションとは別に、 CriteriaBuilderConfiguration
や EntityViewConfiguration
のイベントを観測し、これらのオブジェクトにカスタマイズを適用することで、さらなる設定やカスタマイズを適用することができます。様々なカスタマイズの使用例については、 エンティティビューのドキュメントのQuarkusのセクション を参照してください。
@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);
}
}