1

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?

6
  • Can you post the profile object content? Commented Jan 15, 2020 at 17:40
  • It adds new line means? New record? Commented Jan 15, 2020 at 17:49
  • @SandeshaJ I added more info pls take a look Commented Jan 15, 2020 at 17:57
  • @gnanajeyam95 New row to the table. Commented Jan 15, 2020 at 17:58
  • no id or not existing id -> "create", existing id -> "update" (?;) (talking about nested "profileContacts" (json) element) Commented Jan 15, 2020 at 19:30

5 Answers 5

2

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" } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Won't this allow the client to update any personalContact by simply passing along a random EntityId?
If the random number matches persisted entity id (database entry) then it will update. but we can restrict this by cascading I think so.
2

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" } } 

Comments

1
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" } }

Comments

1

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.

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.