Hibernate5忽略了延迟加载

时间:2018-09-10 20:43:12

标签: java spring hibernate spring-boot

我正在尝试使用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();

我没有做到这一点。 是否有任何技巧可以正常工作?还是我想念什么?

感谢帮助!

// edit,仅用于证书化,到目前为止,我一直在使用它,并决定使用更相关的方式:

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 :(得分:-1)

让我们假设父母是与孩子有@onetomany关系的第一个实体,并且在@onetomany上将lazyload设置为true

您仍然可以在服务类中调用parent.getChildren()方法,它将获取它们,但是,如果在控制器类中尝试此操作,则会得到延迟加载异常。

当您只需要父对象时,此方案非常有用,因此您只需检索父对象。 如果需要孩子,则调用刚才提到的方法,它将为您检索该父对象的所有孩子(在控制器类中)