Как Джексон сериализует объект вне перехода - PullRequest
0 голосов
/ 31 мая 2018

Это немного странно для меня.Насколько я понимаю, если вы пытаетесь получить доступ к объекту вне сеанса Hibernate, вы должны получить исключение LazyInitializationException - без сеанса, но я не получаю это исключение.На самом деле кажется, что у меня все еще есть сеанс продолжения моего контроллера за пределами моего сервисного уровня с аннотацией @Transactional.

Вопрос

  • Так ли этотак должно быть?или что-то я не правильно настроил?

Структура

       User
        | 
     Profile { hierarchies entity }
        |
  +-----+-----+
  |           |
Teacher   Student

Пользователь

@Entity
@Table(name="user")
public class User {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;
 private String firstname;
 private String lastname;

 @OneToMany(fetch = FetchType.LAZY , mappedBy = "user")
 @JsonManagedReference
 @JsonInclude(JsonInclude.Include.NON_EMPTY)
 private List<Profile> profiles = new ArrayList<>();

Сервис

@Override
@Transactional
public User getUserById(Long id) {

    Optional<User> optionalUser = userRepo.findById(id);
    User user = optionalUser.get();

    logger.info("\n User -> {}", user);
    return user;
}

Controller :: Вместо Thow Exception или должен возвращать пустой массив.Hibernate выполнить левое соединение

@GetMapping(value="/{userId}", produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
public User getUser(@PathVariable("userId") Long userId) {

    logger.info("User Controller is called");

    User user = userService.getUserById(userId);

    logger.info("User is returned -> {}", user);

    logger.info("Profiles -> {}", user.getProfiles());  // <-- Expecting this to throw LazyInitializationException

    return user;
}

Консоль

    018-05-31 15:17:35.462  INFO 15599 --- [nio-8080-exec-1] c.d.c.controller.UserController          : User Controller is called
Hibernate: 
    select
        user0_.id as id1_4_0_,
        user0_.firstname as firstnam2_4_0_,
        user0_.lastname as lastname3_4_0_ 
    from
        user user0_ 
    where
        user0_.id=?
2018-05-31 15:17:35.467  INFO 15599 --- [nio-8080-exec-1] c.d.c.services.UserServiceImpl           : 
 User -> 
User [id=1, firstname=Hendric, lastname=Rosenberg]
2018-05-31 15:17:35.467  INFO 15599 --- [nio-8080-exec-1] c.d.c.controller.UserController          : User is returned -> 
User [id=1, firstname=Hendric, lastname=Rosenberg]
Hibernate: 
    select
        profiles0_.user_id as user_id2_3_0_,
        profiles0_.id as id1_3_0_,
        profiles0_.id as id1_3_1_,
        profiles0_.user_id as user_id2_3_1_,
        profiles0_1_.citizent_id as citizent1_2_1_,
        profiles0_1_.profile_type as profile_2_2_1_,
        profiles0_2_.license as license1_1_1_,
        profiles0_2_.practitioner_type as practiti2_1_1_,
        profiles0_2_.profile_type as profile_3_1_1_,
        profiles0_2_.specialized as speciali4_1_1_,
        case 
            when profiles0_1_.id is not null then 1 
            when profiles0_2_.id is not null then 2 
            when profiles0_.id is not null then 0 
        end as clazz_1_ 
    from
        profile profiles0_ 
    left outer join
        patient profiles0_1_ 
            on profiles0_.id=profiles0_1_.id 
    left outer join
        medical_profession profiles0_2_ 
            on profiles0_.id=profiles0_2_.id 
    where
        profiles0_.user_id=?
c.d.c.controller.UserController          : User is returned -> [
 Student [profileType=STUDENT, id=A1236578889], 
 Teacher [profileType=TEACHER, license=234SFLLWEKD32342]]

1 Ответ

0 голосов
/ 31 мая 2018

spring.jpa.open-in-view = true установлено по умолчанию.Таким образом, вы не получите LazyInitializationException

Это свойство зарегистрирует OpenEntityManagerInViewInterceptor

Перехватчик веб-запроса Spring, который связывает JPA EntityManager с потоком для всегообработка запроса.Предназначен для шаблона «Открыть EntityManager в представлении», т.е. для обеспечения отложенной загрузки в веб-представлениях, несмотря на то, что исходные транзакции уже завершены.Этот перехватчик делает JPA EntityManager доступным через текущий поток, который будет автоматически обнаруживаться менеджерами транзакций.Он подходит для транзакций уровня обслуживания через JpaTransactionManager или JtaTransactionManager, а также для нетранзакционного выполнения только для чтения.В отличие от OpenEntityManagerInViewFilter, этот перехватчик настроен в контексте приложения Spring и, таким образом, может использовать преимущества проводки бина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...