가 나는 RoleEntity
과 UserEntity
을 절약. RoleEntity
에는 UserEntity
의 목록이 있고 그 반대의 경우는 Many-To-Many
관계입니다. 내 UserEntity
:
public class UserEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true, nullable = false)
private String username;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(nullable = false)
private String email;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
@JoinTable(name = "uas_user_role",
joinColumns = @JoinColumn(name = "uas_user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "uas_role_id", referencedColumnName = "id"),
uniqueConstraints = {
@UniqueConstraint(columnNames = {"uas_user_id", "uas_role_id"})}
)
private Set<RoleEntity> roles = new HashSet<>();
...
}
내 RoleEntity
:
public class RoleEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true, nullable = false)
private String name;
@ManyToMany(mappedBy = "roles")
private Set<UserEntity> users;
@ManyToMany
@JoinTable(
name = "uas_role_permission",
joinColumns
= @JoinColumn(name = "uas_role_id", referencedColumnName = "id"),
inverseJoinColumns
= @JoinColumn(name = "uas_permission_id", referencedColumnName = "id"),
uniqueConstraints = {
@UniqueConstraint(columnNames = {"uas_role_id", "uas_permission_id"})}
)
private Set<PermissionEntity> permissions;
...
}
목표
지금은 하나의 개체를 업데이트 간단하여 맵핑을 변경하고 싶습니다. 예를 들어 내가 가진 RoleEntity
에 UserEntity
을 추가 할 ID = 1 :
{
"id": 1,
"name": "Admin_Role",
"users": [{"id": 1}
]
}
저장이이 RoleEntity
의 역할 저장소 (JPARepository.saveAndFlush(Serializable)
)를 성공적으로 해결합니다 UserEntity
을 암시하고 업데이트 된 RoleEntity
{
"id": 1,
"name": "Admin_Role",
"users": [{
"id": 1,
"username": "admin",
"firstName": "Administrator",
"lastName": "Administrator",
"email": "[email protected]",
}
]
}
을 반환
문제
내 테스트는 모두 통과했기 때문에 테스트가 모두 통과했습니다. save 명령의 turn 값. 계속 발생 후 roleRepository.findOne(1)
을 할 때 지금 내가 발견, 나는 RoleEntity
다음을받을 것이다 :
{
"id": 1,
"name": "Admin_Role",
"users": []
}
UserEntity
매핑은 지속되지 않았다. 또한 spring.jpa.show-sql=true
을 설정할 때 saveAndFlush
명령 중에 SELECT
작업 만 실행됩니다. 매핑 엔티티의 편집을 허용하지 않으려는 경우에만 매핑을 만들려고합니다. 그 이유는 계단식을 비활성화했기 때문입니다.
이 방법을 사용하면 매핑이 생성 될 것으로 예상됩니다. 내가 도대체 뭘 잘못하고있는 겁니까?
언급 메르 Qarabsa 으로 해결 방법 : 는 양방향 매핑을 만들려면, 그것은 양쪽에 설정해야합니다. .saveAndFlush(roleEntity)
와
@Transactional
public RoleDto updateRole(RoleDto role) {
RoleEntity roleEntity = roleRepository.findOne(role.getId());
if (roleEntity==null){
throw new ResourceNotFoundException();
}
final RoleEntity savedRoleEntity = roleRepository.saveAndFlush(roleEntity);
savedRoleEntity.getUsers().forEach(user -> user.getRoles().add(savedRoleEntity));
return savedRoleEntity;
}
내가 먼저 RoleEntity
를 업데이트하고 JPA는 UserEntity
를 해결 드리겠습니다 : 이미 엔티티를 저장 한 후 한 줄을 추가하면 트릭을 수행합니다. 그 후에 역할의 각 UserEntity
에 RoleEntity
을 설정하기 만하면됩니다. 내 경우에는 수동으로 저장하지 않아도됩니다. 트랜잭션이 저장되지 않은 변경 사항을 유지 관리하기 때문입니다.
모든 필요한 정보를 얻을 수 있기 때문에 Jpa/Hibernate가 이에 관심을 기울일 것으로 기대했을 것입니다. 그렇다면이 경우가 아닙니까? –
@HerrDerb 아니요, jpa에서 처리 할 수 없습니다. 특히 nullable 시나리오에 대해 생각하는 경우 –
아, 알겠습니다. 사실 아주 간단하게 해결할 수 있습니다. 내 질문에 구체적인 해결책을 추가하겠습니다. 감사. –