#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. Тогда единственный вариант для вас-зафиксировать родительский объект. Это устранит все эти сценарии проблем.