Примерно в 2013–2014 годах есть несколько аналогичных ответов на вопросы, но решения, похоже, не работают для меня, поэтому я надеюсь, что с тех пор что-то, возможно, изменилось, и что я не упускаю что-то явно очевидное. (новый проект: Spring-boot 2.0.2.RELEASE и спящий режим 5.2.17.Final)
Проблема: У меня есть объект, который содержит отображение OneToOne (FetchType.LAZY) на другой объект, оба из которых являются таблицами в базе данных MySQL. Я хотел бы, чтобы сопоставление между двумя объектами было ленивым, чтобы спящий режим не выполнял второй запрос для извлечения сопоставленного объекта. Связь никогда не будет нулевой, т. Е. Необязательной.
Ожидал: Учитывая две сущности, например Человек и Адрес (как описано ниже), при выполнении запроса HQL или JPA для извлечения одного Человек из базы данных я ожидал (и хочу) увидеть только следующий запрос sql спящего режима:
Hibernate: select person0_.id as id1_1_ from person person0_
Действительный: Вместо этого я также вижу нетерпеливую выборку для получения сущности Адрес:
Hibernate: select person0_.id as id1_1_ from person person0_
Hibernate: select address0_.id as id1_0_0_ from address address0_ where address0_.id=?
Попытки решения: Я пробовал следующие варианты:
optional = false (Hibernate: индивидуальная отложенная загрузка, необязательно = false)LazyToOneOption.NO_PROXY (Ленивая загрузка гибернации с помощью @LazyToOne (LazyToOneOption.NO_PROXY))@JsonIgnoreЛюбая помощь будет принята с благодарностью!
Упрощенный пример воспроизведения проблемы: Для упрощенного примера я использовал в качестве ссылки этот пост, в котором OP заявляет, что у них есть рабочее решение: Hibernate: индивидуальная отложенная загрузка, необязательно = false
Следуя этому руководству, я создал новый проект Spring Boot: https://www.callicoder.com/spring-boot-rest-api-tutorial-with-mysql-jpa-hibernate/ с начальным проектом, созданным с помощью http://start.spring.io/ (Maven + Ява + Весенняя загрузка 2.0.2 и зависимости Интернет + JPA + MySQL + DevTools)
Сущность (Человек), которую я хочу запросить, определяется следующим образом:
@Entity
public class Person {
@Id
@SequenceGenerator(name = "person_sequence", sequenceName = "sq_person")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_sequence")
@Column(name = "id")
private long personID;
@LazyToOne(value = LazyToOneOption.NO_PROXY)
@OneToOne(mappedBy = "person", cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
@JsonIgnore
private Address address;
// .. getters, setters
}
Отображаемый объект (Адрес) определяется как:
@Entity
public class Address {
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = @Parameter(name = "property", value = "person"))
private long personID;
@PrimaryKeyJoinColumn
@OneToOne(fetch = FetchType.LAZY)
private Person person;
}
Запись в приложении:
@SpringBootApplication
public class OneToOneMappingApplication {
public static void main(String[] args) {
SpringApplication.run(OneToOneMappingApplication.class, args);
}
}
JpaRepository:
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
RestController:
@RestController
@RequestMapping("/api")
public class PersonController {
@Autowired
PersonRepository personRepository;
// Get All Persons
public List<Person> getAllPersons() {
return personRepository.findAll();
}
}
В application.properties я попросил spring jpa показать SQL:
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://localhost:3306/onetone_app?useSSL=false
spring.datasource.username = username
spring.datasource.password = password
# Show SQL
spring.jpa.show-sql = true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
# Bytecode enhancement for NO_PROXY usage (?)
hibernate.ejb.use_class_enhancer = true
Один Человек с id = 0 и один Адрес с id = 0 были вставлены в базу данных для выполнения вышеуказанного теста.
Спасибо @AlanHay! Я перешел по ссылке здесь vladmihalcea.com/… и увидел, что мне не хватает плагина спящий режим-улучшение-maven-плагин в моем pom.xml, который активирует улучшение байтового кода. Это устраняет проблему, по крайней мере, в простом случае использования!





См. Обсуждение здесь. discourse.hibernate.org/t/…. Второе упомянутое решение должно работать, но требует улучшения байтового кода во время компиляции. Вы это настроили?