hibernate 使用Reactive/Mutiny持久化实体后创建相关实体

b1zrtrql  于 2023-10-23  发布在  React
关注(0)|答案(1)|浏览(123)

我对Quarkus相对较新,对Reactive Java/Mutiny也是如此,但我试图在创建另一个实体后创建一个相关的数据库实体。示例:保存User对象,然后创建与User具有一对一关系的相关UserProfile对象。
在其他框架中,我会执行以下操作(在REST API函数调用中):
1.使用API payload创建User示例user1
1.保存用户示例后,使用profile.user_id = user1.id创建UserProfile示例
1.将上述所有内容打包到一个事务中
我在下面创建了一个UserResource。这看起来工作得很好--HTTP响应和数据库都包含预期的数据,但是有更好的方法吗?看来,这件事,可以一次交易就搞定?

@ApplicationScoped
@Path("/api/user")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {

  @Inject
  UserRepository userRepository;

  @Inject
  UserProfileRepository userProfileRepository;

  @GET
  public Uni<List<UserEntity>> list() {
    return userRepository.listAll();
  }

  @GET
  @Path("/{id}")
  public Uni<UserEntity> get(Long id) {
    return userRepository.findById(id);
  }

  @POST
  @Path("/")
  public Uni<Response> create(UserEntity user) {
    return Panache
        .withTransaction(() -> userRepository.persist(user))
        .onItem()
        .transformToUni(item -> {
          System.out.println(item);
          var userProfile = new UserProfileEntity();
          userProfile.setUser(item);
          userProfile.setDisplayName("My Name");
          return Panache.withTransaction(() -> userProfileRepository.persist(userProfile));
        })
        .invoke(item -> System.out.println(item))
        .replaceWith(Response.ok(user).status(Status.CREATED)::build);
  }
}
7vux5j2d

7vux5j2d1#

是的,你不应该使用两个交易。
根据您使用的Map,解决方案可能会有所不同。

不带cascade选项的仓库模式:

@POST
  @Path("/")
  public Uni<Response> create(UserEntity user) {            
   System.out.println(user);
   var userProfile = new UserProfileEntity();
   userProfile.setUser(user);
   // If bidirectional association: user.setUserProfile(userProfile)
   userProfile.setDisplayName("My Name");

    return Panache
        .withTransaction(() -> userRepository
            .persist(user)
            .call( () -> userProfileRepository.persist(userProfile)) 
        )
        .invoke(item -> System.out.println(item))
        .replaceWith(Response.ok(user).status(Status.CREATED)::build);
  }

带cascade选项的仓库模式:

@POST
  @Path("/")
  public Uni<Response> create(UserEntity user) {            
   System.out.println(user);
   var userProfile = new UserProfileEntity();
   userProfile.setUser(user);
   // If bidirectional association: user.setUserProfile(userProfile)
   userProfile.setDisplayName("My Name");

    return Panache
        .withTransaction(() -> userRepository.persist(user))
        .invoke(item -> System.out.println(item))
        .replaceWith(Response.ok(user).status(Status.CREATED)::build);
  }

Panache使用级联,不带仓库:

@POST
  @Path("/")
  public Uni<Response> create(UserEntity user) {            
   System.out.println(user);
   var userProfile = new UserProfileEntity();
   userProfile.setUser(user);
   // If bidirectional association: user.setUserProfile(userProfile)
   userProfile.setDisplayName("My Name");

    return Panache.withTransaction(user::persist)
        .invoke(item -> System.out.println(item))
        .replaceWith(Response.ok(user).status(Status.CREATED)::build);
  }

这里是指向Hibernate ORM文档中级联类型PERSIST文档的链接

相关问题