#java #spring #spring-boot #hibernate
Вопрос:
Предположительно, у меня есть две сущности, объединенные как таковые, следующие:
@Entity
public class User {
@Id
private Long id;
private String username;
private String password;
@ManyToOne
@JoinColumn(name="role_id", referencedColumnName = "id") //Table user in database has foreign key role_id
private Role role;
}
@Entity
public class Role {
@Id
private Long id;
private String name;
}
Как создать сущность пользователя только с одним атрибутом роли, а не со всем? (например, только имя роли)
Я ожидаю чего-то вроде
@Entity
public class User {
@Id
private Long id;
private String username;
private String password;
// Some prefix or annotation maybe?
private String role_name;
}
Комментарии:
1. Ты не можешь. Если имя вашей роли уникально, вы можете использовать его как PK и сопоставить его как есть в
User
сущности. Любое другое поле, которое не является частьюUser
таблицы (или какой-либо таблицы соединений), не может быть отображено вUser
таблице.2. Даже с помощью @Query или какого-то подхода к представлению (SQL)?
3. Ну, вы могли бы использовать проекции DTO . Таким образом, у вас может быть объект с любым полем, которое вам нравится, но вы не сможете выполнять какие-либо манипуляции, как на an
@Entity
.4. Я читал некоторые подходы DTO. Хотя это может решить проблему, я полагаю, что возникнет проблема N 1
5. Нет, этого не произойдет. У вас есть только 1 запрос, и вы сопоставляете результат с DTO. Вы не перебираете лениво загруженное
*ToMany
отношение.
Ответ №1:
Как вы уже читали в комментариях, для этого вам понадобится подход DTO, и я думаю, что это идеальный вариант использования для представлений сущностей с сохраняемостью Blaze.
Я создал библиотеку, позволяющую легко сопоставлять модели JPA с пользовательским интерфейсом или абстрактными моделями, определенными классами, что-то вроде весенних прогнозов данных на стероидах. Идея заключается в том, что вы определяете свою целевую структуру(модель домена) так, как вам нравится, и сопоставляете атрибуты(получатели) с помощью выражений JPQL с моделью сущности.
Модель DTO для вашего варианта использования может выглядеть следующим образом с представлениями сущностей Blaze-Persistence:
@EntityView(User.class)
public interface UserDto {
@IdMapping
Long getId();
String getUsername();
String getPassword();
@Mapping("role.name")
String getRoleName();
}
Запрос-это вопрос применения представления сущности к запросу, самым простым из которых является просто запрос по идентификатору.
UserDto a = entityViewManager.find(entityManager, UserDto.class, id);
Интеграция данных Spring позволяет использовать ее почти как проекции данных Spring: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
Page<UserDto> findAll(Pageable pageable);
Самое приятное то, что он будет получать только то состояние, которое действительно необходимо!