Don_Quijote
Don_Quijote

Reputation: 1046

Spring boot/Spring data jpa - how to update related entity?

I have following entities:

@Entity
@Table(name = "profile")
public class Profile {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    private ProfileContacts profileContacts;

...

}

and

@Entity
@Table(name = "profile_contacts")
public class ProfileContacts {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "description")
    private String description;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

}

I am trying to update it by sending this JSON with update to REST controller:

{
        "id": 1,
        "description": "an update",
        "profileContacts": {
            "firstName": "John",
            "lastName": "Doe"
        }
 }

so in the end it calls

profileRepository.save(profile);

where profileRepository is instance of ProfileRepository class:

public interface ProfileRepository extends JpaRepository<Profile, Long> {
}

which is spring-data-jpa interface.

But each time after such update it updates profile table but adds new row to profile_contacts table (table which corresponds to ProfileContactsentity) instead of updating existing ones. How can I achieve updating?

Upvotes: 1

Views: 5513

Answers (5)

Ibrahim Hossain
Ibrahim Hossain

Reputation: 71

Make an entity object and assign the filtered email and set the value to the entity object.

User user2 = registrationRepo.findByEmail(newPasswordDTO.getEmail());
             user2.setPassword(newPasswordDTO.getPassword());
             registrationRepo.save(user2);

Upvotes: 0

Naanavanalla
Naanavanalla

Reputation: 1522

Ok, I see the problem. As @Matheus Cirillo pointed out, you need to tell the hibernate to update the row.

Now, how do you tell the hibernate to update a row - By providing the primary key of the existing row.

But, creating an object with the primary key set is not enough. You need that entity class to be attached to the entity manager and the persistence context.

You can have something like,

//This attaches the entity to the entity manager
ProfileContacts existingProfileContacts = profileContactRepository.getOne(2);
Profile profile = new Profile();
....
....
profile.setProfileContacts(existingProfileContacts);
profileRepository.save(profile);

I hope this helps.

Upvotes: 1

Matheus
Matheus

Reputation: 3370

Well, that's the expected behavior.

You're not telling hibernate to update the profileContacts.

For the framework to be able to update it, you need to send the profileContact's primary key - which in your case is the ProfileContacts#id.

Something like this:

{
  "id": 1,
  "description": "an update",
  "profileContacts": {
    "id": 1
    "firstName": "John",
    "lastName": "Doe"
  }
}

Upvotes: 2

GnanaJeyam
GnanaJeyam

Reputation: 3170

As per your JSON structure. Yes it will create new profileContacts entry for every time.

The problem every time while saving profile entity you are passing "id": 1 that means Hibernate can identify the entity by this id value (primary key) but for profileContacts mapping you are not sending the id that's why Hibernate considering it has a new entity every time.

To update your profileContacts entity make sure to pass the id of it.

Example:

{ 
"id": 1,
 "description": "an update", 
"profileContacts": {
"id" : yourEntityId
 "firstName": "John", 
"lastName": "Doe" 
}
 }

Upvotes: 2

Sekhar
Sekhar

Reputation: 61

Need to specify the join column in the parent Entity.
@Entity
@Table(name = "profile")
public class Profile {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@OneToOne(cascade = CascadeType.ALL)
**@JoinColumn(name = "id")** //
private ProfileContacts profileContacts;

...

}
Now when you try to save Profile entity it will save the child entity also. 

And also needs to include Id in jason request for child entity also { "id": 1, "description": "an update", "profileContacts": { "id": 1, "firstName": "John", "lastName": "Doe" } }

Upvotes: 1

Related Questions