Нужно сделать ленивую загрузку для объектов, не вызывая org.hibernate.LazyInitializationException.
конфигурация JPA :
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
entityManagerFactory.setPackagesToScan("education.web.platform");
entityManagerFactory.setJpaPropertyMap(hibernateJpaProperties());
return entityManagerFactory;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(emf);
return jpaTransactionManager;
}
private Map<String, ?> hibernateJpaProperties() {
HashMap<String, String> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("hibernate.connection.driver_class"));
dataSource.setUrl(environment.getRequiredProperty("hibernate.connection.url"));
dataSource.setUsername(environment.getRequiredProperty("hibernate.connection.username"));
dataSource.setPassword(environment.getRequiredProperty("hibernate.connection.password"));
return dataSource;
}
Пример возникновения проблемы:
Загружаемый класс:
@Entity
@Table(name = "theory_tasks")
@PrimaryKeyJoinColumn(name = "task_id")
public class TheoryTask extends Task {
...
@OneToMany(targetEntity = ProbablyAnswer.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "task")
private List<ProbablyAnswer> probablyAnswers = new ArrayList<>();
...
Класс объектов для ленивой загрузки:
@Entity
@Table(name = "probably_answers")
public class ProbablyAnswer implements Serializable{
...
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "task_id")
private Task task;
...
Если метод получающий список объектов в DAO
помечен @Transactional
то при обращении к списку ProbablyAnswers
в TheoryTask
они не подгружаются и при передаче его на страницу выбрасывается org.hibernate.LazyInitializationException.
Если пометить @Transactional
метод в сервисе или контроллере то ленивая загрузка игнорируется и рекурсивно загружается весь граф объектов.
Метод которым я получаю сущность:
public List<T> getAll(){
String genericClassName = persistentClass.toGenericString();
genericClassName = genericClassName.substring(genericClassName.lastIndexOf('.')+1);
String hql = "FROM "+genericClassName;
return entityManager.createQuery(hql,persistentClass).getResultList();
}
В дальнейшем сущности выводятся на html страницу.
Перед тем как использовать полученный список, проинициализируйте его утилитой Hibernate.initialize(yourList)
public List<T> getAll(){
String genericClassName = persistentClass.toGenericString();
genericClassName = genericClassName.substring(genericClassName.lastIndexOf('.')+1);
String hql = "FROM "+genericClassName;
List<T> list = entityManager.createQuery(hql,persistentClass).getResultList();
Hibernate.initialize(list);
return list;
}
Все сущности с дочерними можно получить одним запросом к БД, для этого переопределите в имплементации Ваш метод и укажите какие дочерние объекты нужно прогрузить, например так:
public List<TheoryTask> getAll(){
String hql = "FROM TheoryTask t LEFT JOIN FETCH t.probablyAnswers";
return entityManager.createQuery(hql,TheoryTask.class).getResultList();
}
В БД будет идти один запрос и будет применятся только для этого метода.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
field должен быть добавлен в объект класса JWindow или JFrame, которому необходимо задать границы и включить видимостьСама по себе JPanel отрисовываться...
Доброго времени сутокСобственно, вопрос в том, какой практический смысл конструкции, когда выделяется блок внутри метода
Можно ли в java переименовать Label, прописав это в коде самостоятельно?