I am relatively new to Quarkus, and much so with Reactive Java/Mutiny, but I am trying to create a related database entity after creating another entity. Example: Saving a User
object, then creating a related UserProfile
object that has a one-to-one relationship with User
.
我对Quarkus比较陌生,对Active Java/Mutiny也是如此,但我正在尝试在创建另一个实体之后创建一个相关的数据库实体。示例:保存User对象,然后创建与User具有一对一关系的相关UserProfile对象。
In other frameworks I would do the following (within a REST API function call):
在其他框架中,我将执行以下操作(在REST API函数调用中):
- Use API payload to create a
User
instance, user1
.
- With user instance saved, create a
UserProfile
instance with profile.user_id = user1.id
- Wrap all the above in a transaction
I've created a UserResource
below. This seems to work fine -- both HTTP response and database contain the expected data, but is there a better way? It seems like this could be done with just one transaction instead?
我已经在下面创建了一个用户资源。这似乎工作得很好--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);
}
}
更多回答
优秀答案推荐
Yes, you shouldn't have to use two transactions.
是的,你不应该使用两个交易。
The solution may change depending on the mapping you are using.
根据您使用的贴图,解决方案可能会有所不同。
Repository pattern without cascade option:
@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);
}
Repository pattern with cascade option:
@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 using cascading, without repository:
@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);
}
Here's the link to the documentation of cascade type PERSIST in Hibernate ORM documentation
下面是指向Hibernate ORM文档中级联类型持久化的文档的链接
更多回答
我是一名优秀的程序员,十分优秀!