gpt4 book ai didi

java - LazyInitializationException 问题无法初始化代理 - 无 session

转载 作者:行者123 更新时间:2023-11-30 03:15:14 25 4
gpt4 key购买 nike

我在 hibernate 中遇到了这个著名的 LazyInitializationException 问题。我看到了很多关于此的问题,但仍然无法解决我的问题。

我有这样的多对多关系:

青少年.java

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<Follower> followerList;
}

Follower.java

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<Teen> teenList;
}

一名青少年拥有 n 个关注者,并且一名关注者可以关注 n 个青少年。

我的数据库中已经有一些条目,我正在从中获取所有青少年。

List<Teen> teens = (List<Teen>) teenDao.findAll();

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

当我尝试读取从 getFollowerList() 方法获取的关注者列表时,我遇到了上述代码的异常。

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)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

真的不知道该怎么办了。我已经尝试在导致错误的方法中添加 @Transaction 注释,并且这有效。但是,当我将 Teen 对象发送到我的 Android 应用程序时,在将对象转换为 json 时遇到相同的异常。

我的配置文件是:

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />

<!-- Resolves views selected for rendering by @Controllers to .jsp resources
in the /WEB-INF/views directory -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>

<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages" />
<beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>

<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="en" />
<beans:property name="cookieName" value="myAppLocaleCookie"></beans:property>
<beans:property name="cookieMaxAge" value="3600"></beans:property>
</beans:bean>

<interceptors>
<beans:bean
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="locale" />
</beans:bean>
</interceptors>

<!-- Configure to plugin JSON as request and response in method handler -->
<beans:bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter" />
</beans:list>
</beans:property>
</beans:bean>

<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>

<!-- Enable @Transactional annotation -->
<tx:annotation-driven />

<mvc:interceptors>
<beans:bean class="com.capstone.server.interceptor.LoginInterceptor" />
</mvc:interceptors>

<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<!-- Setting maximum upload size -->
<beans:property name="maxUploadSize" value="1000000" />
</beans:bean>

<context:component-scan base-package="com.capstone.server" />

</beans:beans>

持久化JPAConfig.java

@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;
}
}

最佳答案

这是我最终的做法:

相反,我只有一个仅获取惰性数据的 teenDao.findAll() 方法,我创建了另一个接收 boolean 参数 forceLoad 的方法。实现是这样的:

@Transactional
public Teen find(String email) {
return find(email, false);
}

@Transactional
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 时,我仅初始化所需的列表。

关于java - LazyInitializationException 问题无法初始化代理 - 无 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32788987/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com