java - Hibernate5 忽略延迟加载
问题描述
我正在尝试使用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;
}
解决方案
让我们假设 parent 是第一个与 children 有 @onetomany 关系的实体,并且lazyload 在 @onetomany 上设置为 true
你仍然可以在服务类中调用 parent.getChildren() 方法,它会获取它们,但是如果你在你的控制器类中尝试这个,你会得到延迟加载异常。
当您只需要父对象时,此场景很有用,因此您只需检索父对象。如果您需要孩子,请调用您刚才提到的方法,它将为您检索该父母的所有孩子(在您的控制器类中)