Spring JPA - 持久化嵌套对象
Spring JPA - persisting nested objects
我有一个简单的 JPA 存储库,如下所示:
public interface UserRepository extends JpaRepository<User, String>
{
User findByName(String name);
}
还有两个具有 OneToOne 映射的 类,如下所示:
@Entity
public class User
{
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
@Column(nullable = false, unique = true)
private String name;
@Column(nullable = false)
private String email;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user")
private PlayerCharacter playerCharacter;
//...
}
.
@Entity
public class PlayerCharacter
{
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
@OneToOne(optional = true)
private User user;
@Column(nullable = false)
private String characterName;
//...
}
现在,我知道我可以像这样轻松地编辑和保存用户实例:
User user = userRepository.findByName("Alice");
PlayerCharacter character = user.getPlayerCharacter();
character.setCharacterName("ConanTheBarbarian");
userRepository.save(user);
但是我如何在没有指向 User
实例的指针的上下文中保留 PlayerCharacter
实例,f.i.:
public void changePlayerCharacterName(PlayerCharacter character, String name){
character.setCharacterName(name);
// How to correctly persist the 'character' instance here?
}
我可以打电话给 userRepository.save(character);
吗?
我是否需要自动装配另一个存储库 (PlayerCharacterRepository
) 并在其上调用 .save()?
首先,您不会使用 UserRepository,而是 PlayerCharacterRepository。
但即便如此,JPA 的基本原则是它自动 使对托管实体所做的更改持久化。所以你不需要调用 save()。您只需获得一个受管理的玩家角色(使用 find(),或通过关联导航,或使用查询),然后更改其名称。这就是您所需要的。
这样做双向映射
@OnetoOne
@LazyCollection(LazyCollectionOption.FALSE)
private PlayerCharacter playerCharacter;
@OneToOne(fetch=FetchType.EAGER)
private Status status;
通过这种类型的映射,您可以同时使用 UserRepository 和 PlayerCharacterRepository 来保存这两个实例。
我有一个简单的 JPA 存储库,如下所示:
public interface UserRepository extends JpaRepository<User, String>
{
User findByName(String name);
}
还有两个具有 OneToOne 映射的 类,如下所示:
@Entity
public class User
{
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
@Column(nullable = false, unique = true)
private String name;
@Column(nullable = false)
private String email;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user")
private PlayerCharacter playerCharacter;
//...
}
.
@Entity
public class PlayerCharacter
{
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
@OneToOne(optional = true)
private User user;
@Column(nullable = false)
private String characterName;
//...
}
现在,我知道我可以像这样轻松地编辑和保存用户实例:
User user = userRepository.findByName("Alice");
PlayerCharacter character = user.getPlayerCharacter();
character.setCharacterName("ConanTheBarbarian");
userRepository.save(user);
但是我如何在没有指向 User
实例的指针的上下文中保留 PlayerCharacter
实例,f.i.:
public void changePlayerCharacterName(PlayerCharacter character, String name){
character.setCharacterName(name);
// How to correctly persist the 'character' instance here?
}
我可以打电话给 userRepository.save(character);
吗?
我是否需要自动装配另一个存储库 (PlayerCharacterRepository
) 并在其上调用 .save()?
首先,您不会使用 UserRepository,而是 PlayerCharacterRepository。
但即便如此,JPA 的基本原则是它自动 使对托管实体所做的更改持久化。所以你不需要调用 save()。您只需获得一个受管理的玩家角色(使用 find(),或通过关联导航,或使用查询),然后更改其名称。这就是您所需要的。
这样做双向映射
@OnetoOne
@LazyCollection(LazyCollectionOption.FALSE)
private PlayerCharacter playerCharacter;
@OneToOne(fetch=FetchType.EAGER)
private Status status;
通过这种类型的映射,您可以同时使用 UserRepository 和 PlayerCharacterRepository 来保存这两个实例。