Spring Data, lazy загрузка связанной сущности

297
22 марта 2017, 15:45

Есть две сущности Тема (Topic) и ответы для неё (Answer). Правильно ли работает Lazy?

@Entity

@Table (name = "answer") @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") public class Answer {

@Id
@GeneratedValue
private Long id;
@Column (name="answer_name")
private String answerName;
@Column (name="count_voices")
private int countVoice;
@ManyToOne
@JoinColumn(name = "id_topic")
private Topic topic;
public Answer() {
    super();
}

}

И сущность Topic:

@Entity

@Table (name = "topic") @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id") public class Topic {

@Id
@GeneratedValue
@Column (name = "id_topic")
private Long id;
private String topicName;
private Date startDate;
private Date endDate;
@OneToMany(mappedBy = "topic", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Answer> answer;

}

Получаю все записи из таблицы Topic:

@Service

public class TopicServiceImpl implements TopicService{

@Autowired
private TopicRepository topicRepository;
@Override
public Topic findById(long id) {
    return topicRepository.findOne(id);
}
@Override
@Transactional
public void deleteTopicById(long id) {
    topicRepository.delete(id);     
}
@Override
public List<Topic> findAllTopics() {
    return topicRepository.findAll();
}

1) Когда делаю вызов findAll, то вытягиваются все Topic со связанными Answer. Разве так должно быть? 2) Как сделать, что бы findall возвращало только Topic, а не тянуло еще и Answer для каждой записи? Если я правильно понимаю, то Answer должен тянуться, когда будет вызван findOne? Как оптимально сделать код, как делают в продакшене, объясните?

результат findAll():

{ 
"id": 1, 
"topicName": "Хочешь сладких апельсинов?", 
"startDate": 1486872742000, 
"endDate": null, 
"answerList": [ 
  { 
"id": 1, 
"answerName": "Да", 
"countVoice": 7, 
"topic": 1 
}, 
  { 
"id": 2, 
"answerName": "Нет", 
"countVoice": 2, 
"topic": 1 
}, 
  { 
"id": 3, 
"answerName": "У меня на них аллергия", 
"countVoice": 1, 
"topic": 1 
} 
], 
}

ссылка на проект gitHub Код

Answer 1

Lazy - ленивый. В данном случае ленивая загрузка. Значит, что список answer-ов будет загружен только при обращении к полю. Пока его никто не трогает, ничего не произойдёт.

Это никак не связано ни с findAll, ни с findOne. Как видно из названия методов:
findAll загрузит список всех topic-ов
findOne выдаст только одного из них (если сможет конечно:).

Они сами по себе не приводят к загрузке или не загрузке чего бы то ни было, связанного с topic-ами.

И в том и другом случае будут получены topic-и/topic, у которых список answer-ов не загружен.

Так откуда они взялись в Вашем выводе? Элементарно, Ватсон!
Процедура, которая готовит Ваш json, пробегает по всем полям topic-а, в том числе и по answer, что и приводит к его загрузке!

Просто не трогайте List<Answer> answer когда не надо и всё.
(как заставить процедуру подготовки json обходить его стороной - ищите сами)

Кстати, отношения XxxToMany по умолчанию подразумевают fetch Lazy. Можно сэкономить не наборе лишних букв.

READ ALSO
Как в IDEA вернуть закрытую вкладку с логами

Как в IDEA вернуть закрытую вкладку с логами

Запускаю проект, во вкладке RUN вижу вкладки для console и logСлучайно закрываю log и не понимаю как её вернуть без перезапуска проекта

277
Свёртывание в Jar

Свёртывание в Jar

Написал приложение на Intellij IDEAСворачиваю в jar

208
Java. Создание image и последующая передача

Java. Создание image и последующая передача

Мне необходимо создать класс, в котором при помощи Graphics, рисуешь необходимые элементы из линий, после сохраняешь их в image и передаёшь основному...

209
EditText данные по умочанию

EditText данные по умочанию

Есть EditText в который необходимо вводить только целые числаВ xml файле пометил свойством inputType="number"

272