Reputation: 1046
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 ProfileContacts
entity) instead of updating existing ones.
How can I achieve updating?
Upvotes: 1
Views: 5513
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
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
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
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
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