Spring JPA - 持久化嵌套对象

时间:2016-06-13 17:01:22

标签: spring jpa spring-data-jpa repository

我有一个简单的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);

但是我如何在我没有指向PlayerCharacter实例的指针的情况下坚持User实例,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()?

2 个答案:

答案 0 :(得分:1)

首先,您不会使用UserRepository,而是使用PlayerCharacterRepository。

但即便如此,JPA的基金会原则是自动使对托管实体的更改持续存在。所以你不需要调用save()。您只需获取托管玩家角色(使用find(),或通过关联导航或使用查询),并更改其名称。这就是你所需要的一切。

答案 1 :(得分:0)

以这种方式进行双向映射。

@OnetoOne
@LazyCollection(LazyCollectionOption.FALSE)
private PlayerCharacter playerCharacter;


@OneToOne(fetch=FetchType.EAGER)
private Status status;

通过这种类型的映射,您可以使用UserRepository和PlayerCharacterRepository来保存这两个实例。