Как определить только выбранные внешние атрибуты в spring entity

#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);
 

Самое приятное то, что он будет получать только то состояние, которое действительно необходимо!