在使用时出现了LazyInitializationException无法初始化代理-没有会话的问题。

16 浏览
0 Comments

在使用时出现了LazyInitializationException无法初始化代理-没有会话的问题。

我在使用Hibernate时遇到了著名的LazyInitializationException问题。我已经看了很多关于这个问题的问题,但仍然无法解决我的问题。\n我有一个多对多的关系,如下所示:\nTeen.java\n

public class Teen implements Serializable {
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "TEEN_FOLLOWER",
            joinColumns = @JoinColumn(name = "teenEmail"),
            inverseJoinColumns = @JoinColumn(name = "followerEmail"))
    private List followerList;
}

\nFollower.java\n

public class Follower implements Serializable {
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "TEEN_FOLLOWER",
            joinColumns = @JoinColumn(name = "followerEmail"),
            inverseJoinColumns = @JoinColumn(name = "teenEmail"))
    private List teenList;
}

\n一个Teen有n个Follower,一个Follower可以关注n个Teen。\n我的数据库中已经有一些记录,我正在获取所有的Teen。\n

List teens = (List) teenDao.findAll();
for (Teen item : teens) {
    System.out.println("teen " + item.getEmail());
    List followers = item.getFollowerList();
    for (Follower follower : followers) {
        System.out.println("follower " + follower.getEmail());
    }
}

\n当我尝试从getFollowerList()方法获取的followers列表中读取时,我在上面的代码中遇到了异常。\n

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.capstone.server.model.Teen.followerList, could not initialize proxy - no Session
    org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:572)
    org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:212)
    org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:551)
    org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:140)
    org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:294)
    com.capstone.server.controller.TeenController.visualizar(TeenController.java:38)
    ...

\n真的不知道该怎么办了。我已经尝试在引发错误的方法中添加了@Transactional注解,并且是有效的。然而,当我将Teen对象发送到我的Android应用程序时,转换对象为json时我遇到了相同的异常。\n我的配置文件如下:\nservlet-context.xml\n



    
    
    
    
    
    
    
        
        
    
    
        
        
    
    
        
        
        
    
    
        
            
        
    
    
    
        
            
                
            
        
    
    
    
    
    
    
    
        
    
    
        
        
    
    

\nPersistenceJPAConfig.java\n

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:application.properties")
public class PersistenceJPAConfig {
    @Resource
    private Environment env;
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] {
                Constants.PACKAGE_NAME
        });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        return em;
    }
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        // Connection data
        dataSource.setDriverClassName(env.getRequiredProperty("db.driver"));
        dataSource.setUrl(env.getRequiredProperty("db.url"));
        dataSource.setUsername(env.getRequiredProperty("db.username"));
        dataSource.setPassword(env.getRequiredProperty("db.password"));
        return dataSource;
    }
    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }
    Properties additionalProperties() {
        Properties properties = new Properties();
        // Hibernate properties
        properties.setProperty("hibernate.dialect", env.getRequiredProperty("hibernate.dialect"));
        properties.setProperty("hibernate.show_sql", env.getRequiredProperty("hibernate.show_sql"));
        properties.setProperty("hibernate.format_sql",
                env.getRequiredProperty("hibernate.format_sql"));
        // Updates the database and generate tables, if needed
        properties.setProperty("hibernate.hbm2ddl.auto",
                env.getRequiredProperty("hibernate.hbm2ddl.auto"));
        // Initializes database with admin entry in User table
        properties.setProperty("hibernate.hbm2ddl.import_files",
                env.getRequiredProperty("hibernate.hbm2ddl.import_files"));
        properties.setProperty("hibernate.hbm2ddl.import_files_sql_extractor",
                env.getRequiredProperty("hibernate.hbm2ddl.import_files_sql_extractor"));
        return properties;
    }
}

0
0 Comments

(Issue with LazyInitializationException could not initialize proxy - no Session)这个问题的出现的原因是在事务边界之外传递实体对象。解决方法有两种:一种是在dao中调用teen.getFollower().size()方法来贪婪地获取相关实体对象;另一种是不要直接返回实体对象,而是将需要的数据复制到POJO中并传递给更高层。

0
0 Comments

在使用事务时,当你有一个延迟加载字段时,你无法获取该字段的值,因为你在事务之外,并且你的会话已经被释放。

一种方法是,在你的控制器上放置事务注解,或者将控制器的内容委托给一个被标记为事务的服务类,并在该服务类的方法中进行操作。

当然,在事务之外你无法调用延迟加载字段。

关于这个问题的解决方法,下面是一个例子:

首先,在你的控制器类上添加`@Transactional`注解,以确保在执行控制器方法时会开启一个事务。例如:

@Controller
@Transactional
public class MyController {
    // controller methods
}

然后,将控制器中的操作委托给一个被标记为事务的服务类。例如:

@Service
@Transactional
public class MyService {
    // service methods
}

在服务类中的方法中执行你的操作,这样事务就会被正确地管理,并且你可以在方法中访问延迟加载字段的值。例如:

@Service
@Transactional
public class MyService {
    @Autowired
    private MyRepository myRepository;
    public void doSomething() {
        // perform operations using myRepository
    }
}

通过这种方式,你可以在事务中正确地访问延迟加载字段的值,避免出现`LazyInitializationException`异常。希望这个解决方法对你有帮助!

0
0 Comments

懒加载异常的问题通常出现在使用Hibernate框架时,当我们尝试访问一个尚未初始化的代理对象时会抛出该异常。下面是一个解决这个问题的方法。

解决方法是创建一个新的方法,在需要加载数据的时候传递一个布尔参数"forceLoad",以下是具体实现方式:

在原有的teenDao.findAll()方法中,只获取懒加载的数据,然后创建一个新的方法,接收一个boolean类型的参数"forceLoad",具体实现如下:

public Teen find(String email) {
    return find(email, false);
}
public Teen find(String email, boolean forceLoad) {
    Teen teen = em.find(Teen.class, email);
    if(teen != null && forceLoad) {
        Hibernate.initialize(teen.getUser());
        Hibernate.initialize(teen.getFollowerList());
        Hibernate.initialize(teen.getPendingFollowerList());
        Hibernate.initialize(teen.getCheckInList());
    }
    return teen;
}

通过上述代码,我们只在传递"forceLoad"参数为true时,初始化我们需要的列表数据。这样可以避免懒加载异常的问题。

0