Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring JPA - persisting nested objects

I have a simple JPA repository that looks like this:

public interface UserRepository extends JpaRepository<User, String>
{
    User findByName(String name);
}

And two classes that have a OneToOne mapping, like this:

@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;

    //...
}

Now, I know that I can easily edit and persist a User instance like this:

User user = userRepository.findByName("Alice");
PlayerCharacter character = user.getPlayerCharacter();
character.setCharacterName("ConanTheBarbarian");
userRepository.save(user);

But how would I persist a PlayerCharacter instance from within a context where I don't have a pointer back to the User instance, f.i.:

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

Can I just call userRepository.save(character);?

Do I need to autowire another repository (PlayerCharacterRepository) and call .save() on it?

like image 641
glhr Avatar asked Oct 18 '22 07:10

glhr


1 Answers

First of all, you wouldn't use a UserRepository, but a PlayerCharacterRepository.

But even then, JPA's fundamuntal principle is that it automatically makes the changes made to managed entities persistent. So you don't need to call save(). You just get a managed player character (using find(), or by navigating through associations, or by using a query), and change its name. That's all you need.

like image 142
JB Nizet Avatar answered Oct 29 '22 13:10

JB Nizet