Hibernate5 игнорирует Ленивая загрузка - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь использовать hibernate5:

мой настраиваемый класс:

@Configuration
@EnableTransactionManagement
public class HibernateConfiguration {

    @Value("${db.driver}")
    private String DB_DRIVER;

    @Value("${db.password}")
    private String DB_PASSWORD;

    @Value("${db.url}")
    private String DB_URL;

    @Value("${db.username}")
    private String DB_USERNAME;

    @Value("${hibernate.dialect}")
    private String HIBERNATE_DIALECT;

    @Value("${hibernate.show_sql}")
    private String HIBERNATE_SHOW_SQL;

    @Value("${entitymanager.packagesToScan}")
    private String ENTITYMANAGER_PACKAGES_TO_SCAN;

    @Value("${hibernate.enable_lazy_load_no_trans}")
    private String ENABLE_LAZY_LOAD;

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    public PlatformTransactionManager hibernateTransactionManager() {
        HibernateTransactionManager transactionManager
                = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }


    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(DB_DRIVER);
        dataSource.setUrl(DB_URL);
        dataSource.setUsername(DB_USERNAME);
        dataSource.setPassword(DB_PASSWORD);
        return dataSource;
    }

    private final Properties hibernateProperties() {
        Properties hibernateProperties = new Properties();
        hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
        hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
        hibernateProperties.put("hibernate.enable_lazy_load_no_trans", ENABLE_LAZY_LOAD);

        return hibernateProperties;
    }

}

и мой DAO:

@Service("userDAO_mysql")
@Transactional
public class UserDAOImpl implements UserDAO {
    @Override
    public User getAllUsers(){
        Session session = sessionFactory.getCurrentSession();
        return session.getSession().get(User.class,0);
    }
}

У моего пользователя FetchType установлено значение LazyLoad для любого отношения @OneToMany. Тем не менее, все отношения загружаются только с помощью:

User u = userDAO.getAllUsers();

Я не смог сделать это иначе. Есть ли какие-нибудь хитрости, чтобы это работало как надо? Или я что-то упустил?

Спасибо за помощь!

// редактировать, просто для уточнения, я использовал это до этой даты, и решил использовать более подходящий способ:

public class HibernateUtil {
    private static StandardServiceRegistry registry;
    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                // Create registry
                registry = new StandardServiceRegistryBuilder()
                        .configure()
                        .build();

                // Create MetadataSources
                MetadataSources sources = new MetadataSources(registry);

                // Create Metadata
                Metadata metadata = sources.getMetadataBuilder().build();

                // Create SessionFactory
                sessionFactory = metadata.getSessionFactoryBuilder().build();

            } catch (Exception e) {
                e.printStackTrace();
                if (registry != null) {
                    StandardServiceRegistryBuilder.destroy(registry);
                }
            }
        }
        return sessionFactory;
    }

    public static void shutdown() {
        if (registry != null) {
            StandardServiceRegistryBuilder.destroy(registry);
        }
    }
}

public User getUserById(int id) {
    User u = null;
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;
    Integer employeeID = null;

    try {
        tx = session.beginTransaction();
        Criteria cr = session.createCriteria(User.class).add(Restrictions.eq("id",id));
        u = (User) cr.uniqueResult();
    } catch (HibernateException e) {
        if (tx!=null) tx.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }
    return u;
}

Таким образом, ленивая загрузка не была проигнорирована, ленивая загрузка:

    @OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.LAZY,
orphanRemoval=true)
    public Set<Topic> getTopics() {
        return topics;
    }

public void setTopics(Set<Topic> topics) {
    this.topics = topics;
}

1 Ответ

0 голосов
/ 11 сентября 2018

давайте предположим, что parent - это первая сущность, которая имеет отношение @onetomany к дочерним элементам, а для lazyload установлено значение true для @ onetomany

, вы все равно можете вызвать метод parent.getChildren () в классе обслуживания, этобудет извлекать их, но если вы попробуете это в своем классе контроллера, вы получите исключение для отложенной загрузки.

этот сценарий полезен, когда вам нужен только родитель, поэтому вы просто извлекаете родительский объект.если вам нужны дети, вы вызываете метод, который вы только что упомянули, и он извлечет всех детей этого родителя для вас (в вашем классе контроллера)

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