简体   繁体   English

JPA - Hibernate - OneToOne

[英]JPA - Hibernate - OneToOne

I have a OneToOne relation between tables User and Profile defined like so:我在表 User 和 Profile 之间有一个 OneToOne 关系,定义如下:

@Entity
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name="users", uniqueConstraints = { 
        @UniqueConstraint(columnNames = "username"),
        @UniqueConstraint(columnNames = "email")
    }
)
public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idUser;
    private String username;
    private String email;
    private String password;
    
    @OneToOne(cascade=CascadeType.ALL, orphanRemoval=true)  
    @JoinColumn(name="id_profile", referencedColumnName="idProfile")
    private Profile profile;
    
    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Role> roles = new LinkedHashSet<Role>();

}
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name="profile",
    uniqueConstraints = @UniqueConstraint(columnNames = "discordId")
)
public class Profile implements Serializable {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idProfile;
    private Date birthday;
    private String discordId;
    private String description; 
    @ElementCollection(fetch=FetchType.EAGER)
    private Set<String> spokenLanguages = new LinkedHashSet<String>();

    @OneToMany(fetch=FetchType.EAGER)
    private Set<ProfileGame> profileGames = new LinkedHashSet<>();
    
    @OneToOne(mappedBy="profile")
    private User user;
    
    @ManyToOne
    private TimeSlot timeSlot;
    
}

Then I run a test to make some fixtures in my database:然后我运行测试以在我的数据库中制作一些固定装置:

Profile profile = this.profileRepository.save(Profile.builder()
                    .birthday(new Date())
                    .discordId("discord-" + i)
                    .description("Description de user-" + i)
                    .spokenLanguages(spokenLanguages)
                    .timeSlot(timeSlot)
                    .build());
            user.setProfile(profile);
            System.err.println(user);

Everything works fine here, System.err.println(user) returns correct values.这里一切正常, System.err.println(user) 返回正确的值。

The issue comes from the database, which doesn't "apply" the id_profile in my User table:问题来自数据库,它没有在我的 User 表中“应用” id_profile:

在此处输入图像描述

What did I miss?我错过了什么?

Try to do something like this:尝试做这样的事情:

Profile profile = Profile.builder()
   .birthday(new Date())
   .discordId("discord-" + i)
   .description("Description de user-" + i)
   .spokenLanguages(spokenLanguages)
   .timeSlot(timeSlot)
   .user(user)
   .build();
user.setProfile(profile);
profile = this.profileRepository.save(profile);

You use a bidirectional @OneToOne association, so you should make sure both sides are in-sync at all times.您使用双向@OneToOne关联,因此您应该确保双方始终保持同步。

Also, as you need to propagate persistent state to the user, you should add cascade = CascadeType.ALL to the Profile.user like below:此外,由于您需要将持久性 state 传播给用户,您应该将cascade = CascadeType.ALL添加到Profile.user中,如下所示:

@Entity
public class Profile implements Serializable {
    
    // ...

    @OneToOne(mappedBy="profile", cascade=CascadeType.ALL)
    private User user;
    
}

Class User: Class 用户:

@OneToOne(mappedBy = "user", cascade = CascadeType.ALL,
    fetch = FetchType.LAZY, optional = false)   
private Profile profile;

Class Profile: Class 简介:

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="id_user")
private User user;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM