Hibernate один в один ленивая загрузка с Spring - PullRequest
0 голосов
/ 12 июня 2018

Есть несколько похожих вопросов с ответами примерно в 2013/2014, но решения, похоже, не работают для меня, поэтому я надеюсь, что с тех пор что-то, возможно, изменилось, и что я не пропускаю что-то явно очевидное.(новый проект: spring-boot 2.0.2.RELEASE и hibernate 5.2.17.Final )

Проблема: У меня есть объект, который содержит OneToOne (FetchType.LAZY), сопоставленный с другим объектом, оба из которых являются таблицами в базе данных MySQL.Мне бы хотелось, чтобы отображение между двумя объектами было ленивым, чтобы hibernate не выполнял второй запрос для извлечения сопоставленного объекта.Ассоциация никогда не будет нулевой, т. Е. Необязательной.

Ожидается: Учитывая две сущности, например Персона и Адрес (как описано ниже), при выполнении запроса HQL или JPA для извлечения одного Person из базы данных я ожидал (и хочу) видеть только следующий SQL-запрос Hibernate:

Hibernate: выберитеperson0_.id как id1_1_ от personperson0_

Actual: Вместо этого я также вижу нетерпеливую выборку для получения Address entity:

Hibernate: выберите person0_.id как id1_1_ от лица person0_

Hibernate: выберите address0_.id как id1_0_0_ с адреса address0_, где address0_.id =?

Попытки решения: Я испробовал следующие варианты:

Любая помощь будет принята с благодарностью!


Упрощенный пример для воспроизведения проблемы: Для упрощенного примера я использовал в качестве ссылки этот пост, в котором OP заявляет, что у них есть рабочее решение: Hibernate: отложенная загрузка один к одному, необязательно = false

Я создал новый проект Spring Boot после этого урока: https://www.callicoder.com/spring-boot-rest-api-tutorial-with-mysql-jpa-hibernate/ с начальным проектом, сгенерированным с помощью http://start.spring.io/ ( Maven + Java + Spring Boot 2.0.2 и зависимости Веб + JPA + MySQL + DevTools )

Сущность ( Person ), которую я хочу запросить, определяется следующим образом:

@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
}

Сопоставленная сущность ( Address ) определяется как:

@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

Один Персона с идентификатором = 0 и один Адрес с идентификатором =0 были вставлены в базу данных для выполнения вышеуказанного теста.

...