java Sping Boot /Spring data jpa -如何更新相关实体?

vngu2lb8  于 2023-04-19  发布在  Java
关注(0)|答案(5)|浏览(162)

我有以下实体:

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

...

}

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

}

我正在尝试通过将此JSON与更新发送到REST控制器来更新它:

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

所以最后它召唤

profileRepository.save(profile);

其中profileRepositoryProfileRepository类的示例:

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

spring-data-jpa接口。
但每次更新后,都是更新profile表,但在profile_contacts表(对应ProfileContacts实体的表)中增加new行,而不是更新现有的表,如何实现更新?

nle07wnf

nle07wnf1#

根据你的JSON结构。是的,它每次都会创建新的profileContacts条目。
每次保存profile实体时,你传递的是"id": 1,这意味着Hibernate可以通过这个id值(主键)识别实体,但对于profileContactsMap,你没有发送id,这就是为什么Hibernate认为它每次都有一个新实体。
要更新profileContacts实体,请确保传递它的ID。

  • 示例:*
{ 
"id": 1,
 "description": "an update", 
"profileContacts": {
"id" : yourEntityId
 "firstName": "John", 
"lastName": "Doe" 
}
 }
ev7lccsx

ev7lccsx2#

这是正常的行为
你没有告诉hibernate更新profileContacts
为了使框架能够更新它,您需要发送profileContact的主键-在您的例子中是ProfileContacts#id
就像这样:

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

92dk7w1h3#

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.

并且还需要在子实体的jason请求中包括Id {“id”:1、“说明”:“an update”,“profileContacts”:{“id”:1,“firstName”:“John”,“lastName”:{\fnSimHei\bord1\shad1\pos(200,288)}

xzlaal3s

xzlaal3s4#

好的,我明白问题所在了。正如@Matheus Cirillo指出的,你需要告诉hibernate更新该行。
现在,如何告诉hibernate更新一行--通过提供现有行的主键。
但是,创建一个具有主键集的对象是不够的,您需要将实体类附加到实体管理器和持久化上下文。
你可以有这样的东西,

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

希望这能帮上忙。

gj3fmq9x

gj3fmq9x5#

创建一个实体对象,并将过滤后的电子邮件分配给该实体对象,然后将值设置为该实体对象。

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

相关问题