Сохраните ребенка и обновите родителя

#java #jpa #mapping

Вопрос:

Я работаю над проектом Spring boot, в котором я использую spring data jpa. У меня есть сущности, связанные с родителями и детьми.

Я хочу обновить несколько столбцов родителя при сохранении ребенка.

Когда я сохраняю дочернюю сущность со ссылкой на родителя, ее дочерний объект сохраняется с идентификатором родителя. Однако, когда я сохраняю ребенка с несколькими обновленными столбцами в родительском, сохраняется только ребенок, а родитель не обновляется.

Пожалуйста, найдите ниже код и, пожалуйста, примите решение по этому вопросу.

Родительский класс

 @AllArgsConstructor
@NoArgsConstructor
@Entity
@Builder
@Data
@Table(
        name = "tbl_user",
        uniqueConstraints = {
                @UniqueConstraint(
                        name = "email_unique",
                        columnNames = "email"),
                @UniqueConstraint(
                        name = "uniqueId_unique",
                        columnNames = "uniqueId")
        }
)
public class User {

    @Id
    @SequenceGenerator(name = "user_sequence", sequenceName = "user_sequence", allocationSize = 1)
    @GeneratedValue(generator = "user_sequence", strategy = GenerationType.SEQUENCE)
    private Long userId;
    private String name;
    private String email;
    private Byte status;
    private String uniqueId;
    private Long createdBy;
    private Long updatedBy;

    private ZonedDateTime createdOn;
    private ZonedDateTime updatedOn;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
    private UserProfile userProfile;

}
 

Детский класс

 @NoArgsConstructor
@AllArgsConstructor
@Data
@ToString(exclude = "user")
@Builder
@Entity
@Table(name = "tbl_user_profile", uniqueConstraints = {@UniqueConstraint(name = "phone_number_unique", columnNames = "phoneNumber")})
public class UserProfile {

    @Id
    @SequenceGenerator(name = "user_profile_sequence", sequenceName = "user_profile_sequence", allocationSize = 1)
    @GeneratedValue(generator = "user_profile_sequence", strategy = GenerationType.SEQUENCE)
    private Long profileId;
    private String firstName;
    private String lastname;
    private String phoneNumber;
    private Byte status;
    private String description;
    private ZonedDateTime createdOn;
    private ZonedDateTime updatedOn;
    private Long createdBy;
    private Long updatedBy;

    @OneToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "user_id", referencedColumnName = "userId")
    private User user;

}
 

Вызывающий код — Пользователь с идентификатором пользователя = 1 уже существует в tbl_user

 @SpringBootTest
class UserProfileRepositoryTest {

    @Autowired
    private UserProfileRepository userProfileRepository;

    private Random random = new Random();
    private User existingUser;
    private UserProfile newUserProfile;

    @BeforeEach
    void setUp() {
        String id = String.format("d", random.nextInt(10000));
        String name = "Brijesh "   id;
        existingUser = User.builder()
                .userId(1L)
                .build();

        newUserProfile = UserProfile.builder()
                .firstName("Brijesh")
                .lastname("Yadav")
                .phoneNumber(id)
                .status((byte) 1)
                .description("This is just for testing UserProfileRepository")
                .createdBy(1L)
                .updatedBy(1L)
                .createdOn(ZonedDateTime.now())
                .updatedOn(ZonedDateTime.now())
                .build();
    }

    @Test
    public void createProfileAndUpdateUser() {
        // Given
        existingUser.setUpdatedBy(2L);
        existingUser.setUpdatedOn(ZonedDateTime.now());
        UserProfile testUserProfile = newUserProfile;
        testUserProfile.setUser(existingUser);
        System.out.println("testUserProfile = "   testUserProfile);
        System.out.println("user = "   testUserProfile.getUser());

        // When
        UserProfile result = userProfileRepository.save(testUserProfile);
        System.out.println("result = "   result);
        System.out.println("user = "   result.getUser());

        // Then
        assertThat(result).isNotNull();
        assertThat(result.getProfileId()).isGreaterThan(0);

    }

}
 

Комментарии:

1. попробуйте cascade = ALL для пользователя в профиле пользователя

2. каскад = ВСЕ также приведет к каскадному удалению операции для пользователя. Когда профиль удаляется, соответствующий пользователь не должен удаляться.

3. Тогда единственный вариант для вас-зафиксировать родительский объект. Это устранит все эти сценарии проблем.