2016-06-13 116 views
3

我有一個簡單的JPA存儲庫,看起來像這樣:春天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情況下,網絡連接:

public void changePlayerCharacterName(PlayerCharacter character, String name){ 
    character.setCharacterName(name); 
    // How to correctly persist the 'character' instance here? 
} 

可我只是叫userRepository.save(character);

是否需要自動調用另一個存儲庫(PlayerCharacterRepository)並調用.save()?

回答

1

首先,你不會使用UserRepository,而是一個PlayerCharacterRepository。

但即使如此,JPA的基本原則是它自動使對託管實體所做的更改保持不變。所以你不需要調用save()。您只需獲得管理角色的玩家角色(使用find(),或通過關聯導航或使用查詢)並更改其名稱。這就是你需要的。

0

以這種方式進行雙向映射。

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


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

通過這種類型的映射,您可以同時使用UserRepository和PlayerCharacterRepository來同時存在兩個實例。

+1

爲什麼你會建議海報在不是JPA的一部分時使用一些專有註釋'@ LazyCollection'? –

+0

通過這個你可以有雙向映射。 – Deepanjan