使用 spring 数据延迟加载 - 集合不与任何会话相关联
LazyLoading with spring data - collection is not associated with any session
我有一个大约有 20 个 jpa 实体的小项目;这一切都是关于插入和检索数据。
spring 数据对我来说是一个很好的解决方案,但现在我遇到了延迟加载的停止问题。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
metadata-complete="true"
version="2.5">
<description>Multi vendor</description>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root.springwebbasic</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SpringApplicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/SpringWebConfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
springWebconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.mao" />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" cache-period="3600" />
<mvc:default-servlet-handler />
</beans>
ApplicationContext.java 即 java 数据访问配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.mao.services")
public class ApplicationContext {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "ffs";
private static final String PROPERTY_NAME_DATABASE_URL = " jdbc:mysql://localhost:3306/myfdfd";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "fdfd";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "org.hibernate.dialect.MySQL5InnoDBDialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "true";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "org.hibernate.cfg.ImprovedNamingStrategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "true";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "com.mao.entites";
@Bean
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(PROPERTY_NAME_DATABASE_DRIVER);
dataSource.setJdbcUrl(PROPERTY_NAME_DATABASE_URL);
dataSource.setUsername(PROPERTY_NAME_DATABASE_USERNAME);
dataSource.setPassword(PROPERTY_NAME_DATABASE_PASSWORD);
return dataSource;
}
@Bean
public JpaTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN);
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
Properties jpaProterties = new Properties();
jpaProterties.put("hibernate.dialect", PROPERTY_NAME_HIBERNATE_DIALECT);
jpaProterties.put("hibernate.format_sql", PROPERTY_NAME_HIBERNATE_FORMAT_SQL);
jpaProterties.put("hibernate.ejb.naming_strategy", PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY);
jpaProterties.put("hibernate.show_sql", PROPERTY_NAME_HIBERNATE_SHOW_SQL);
entityManagerFactoryBean.setJpaProperties(jpaProterties);
return entityManagerFactoryBean;
}
}
我有这样的存储库
public interface VendorRepository extends JpaRepository<Vendor, Long> {
}
当我尝试获取惰性集合时,控制器出现问题
@Controller
@RequestMapping("/analysis")
public class Analysis {
@Resource
private VendorRepository vendorRepository;
@RequestMapping(value = "/vendors", method = RequestMethod.GET)
@ResponseBody
public String getVendors()
{
List<Vendor> vendorList= vendorRepository.findAll();
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
return vendorList.get(0).getVedorTechnologies().get(0).getName();
}
实体类
@Entity
@NamedQuery(name="Vendor.findAll", query="SELECT v FROM Vendor v")
public class Vendor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="vendor_id")
private int vendorId;
@Column(name="vendor_name")
private String vendorName;
//bi-directional many-to-one association to VedorTechnology
@OneToMany(mappedBy="vendor")
private List<VedorTechnology> vedorTechnologies;
public Vendor() {
}
}
希望你能找到问题所在!
更新
调用此行时
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
我遇到了这个异常
HibernateException: collection is not associated with any session
我认为 OpenEntityManagerInViewFilter
的平均想法不起作用。
我解决了这个问题。
缺少的是在控制器上方添加注释 @Transactional
。
@Transactional
@Controller
@RequestMapping("/analysis")
public class Analysis {
@Resource
private VendorRepository vendorRepository;
@RequestMapping(value = "/vendors", method = RequestMethod.GET)
@ResponseBody
public String getVendors()
{
List<Vendor> vendorList= vendorRepository.findAll();
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
return vendorList.get(0).getVedorTechnologies().get(0).getName();
}
我有一个大约有 20 个 jpa 实体的小项目;这一切都是关于插入和检索数据。 spring 数据对我来说是一个很好的解决方案,但现在我遇到了延迟加载的停止问题。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
metadata-complete="true"
version="2.5">
<description>Multi vendor</description>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root.springwebbasic</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/SpringApplicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/SpringWebConfig.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
springWebconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.mao" />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" cache-period="3600" />
<mvc:default-servlet-handler />
</beans>
ApplicationContext.java 即 java 数据访问配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.mao.services")
public class ApplicationContext {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "ffs";
private static final String PROPERTY_NAME_DATABASE_URL = " jdbc:mysql://localhost:3306/myfdfd";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "fdfd";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "org.hibernate.dialect.MySQL5InnoDBDialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "true";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "org.hibernate.cfg.ImprovedNamingStrategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "true";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "com.mao.entites";
@Bean
public DataSource dataSource() {
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(PROPERTY_NAME_DATABASE_DRIVER);
dataSource.setJdbcUrl(PROPERTY_NAME_DATABASE_URL);
dataSource.setUsername(PROPERTY_NAME_DATABASE_USERNAME);
dataSource.setPassword(PROPERTY_NAME_DATABASE_PASSWORD);
return dataSource;
}
@Bean
public JpaTransactionManager transactionManager() throws ClassNotFoundException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN);
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
Properties jpaProterties = new Properties();
jpaProterties.put("hibernate.dialect", PROPERTY_NAME_HIBERNATE_DIALECT);
jpaProterties.put("hibernate.format_sql", PROPERTY_NAME_HIBERNATE_FORMAT_SQL);
jpaProterties.put("hibernate.ejb.naming_strategy", PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY);
jpaProterties.put("hibernate.show_sql", PROPERTY_NAME_HIBERNATE_SHOW_SQL);
entityManagerFactoryBean.setJpaProperties(jpaProterties);
return entityManagerFactoryBean;
}
}
我有这样的存储库
public interface VendorRepository extends JpaRepository<Vendor, Long> {
}
当我尝试获取惰性集合时,控制器出现问题
@Controller
@RequestMapping("/analysis")
public class Analysis {
@Resource
private VendorRepository vendorRepository;
@RequestMapping(value = "/vendors", method = RequestMethod.GET)
@ResponseBody
public String getVendors()
{
List<Vendor> vendorList= vendorRepository.findAll();
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
return vendorList.get(0).getVedorTechnologies().get(0).getName();
}
实体类
@Entity
@NamedQuery(name="Vendor.findAll", query="SELECT v FROM Vendor v")
public class Vendor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="vendor_id")
private int vendorId;
@Column(name="vendor_name")
private String vendorName;
//bi-directional many-to-one association to VedorTechnology
@OneToMany(mappedBy="vendor")
private List<VedorTechnology> vedorTechnologies;
public Vendor() {
}
}
希望你能找到问题所在!
更新
调用此行时
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
我遇到了这个异常
HibernateException: collection is not associated with any session
我认为 OpenEntityManagerInViewFilter
的平均想法不起作用。
我解决了这个问题。
缺少的是在控制器上方添加注释 @Transactional
。
@Transactional
@Controller
@RequestMapping("/analysis")
public class Analysis {
@Resource
private VendorRepository vendorRepository;
@RequestMapping(value = "/vendors", method = RequestMethod.GET)
@ResponseBody
public String getVendors()
{
List<Vendor> vendorList= vendorRepository.findAll();
Hibernate.initialize(vendorList.get(0).getVedorTechnologies());
return vendorList.get(0).getVedorTechnologies().get(0).getName();
}