这可能是重复的,但我现在几天都在努力解决这个问题。经过几十个教程,书籍,堆栈答案等等,我处于死胡同。
这是RESTfull Spring hibernate app
控制器:
@RestController
public class CountryController {
@Autowired
CountryService countryService;
@RequestMapping(value = "/getAllCountries", method = RequestMethod.GET, headers = "Accept=application/json")
public List<Country> getCountries() {
List<Country> listOfCountries = countryService.getAllCountries();
return listOfCountries;
}
@RequestMapping(value = "/getCountry/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
public Country getCountryById(@PathVariable int id) {
return countryService.getCountry(id);
}
// .....
}
DAO:
@Repository
public class CountryDAO {
@Autowired
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sf) {
this.sessionFactory = sf;
}
public List<Country> getAllCountries() {
Session session = this.sessionFactory.getCurrentSession();
List<Country> countryList = session.createQuery("from Country").list();
return countryList;
}
public Country getCountry(int id) {
Session session = this.sessionFactory.getCurrentSession();
Country country = (Country) session.load(Country.class, new Integer(id));
return country;
}
// ......
}
服务:
@Service("countryService")
public class CountryService {
@Autowired
CountryDAO countryDao;
@Transactional
public List<Country> getAllCountries() {
return countryDao.getAllCountries();
}
@Transactional
public Country getCountry(int id) {
return countryDao.getCountry(id);
}
}
实体:
@Entity
@Table(name="COUNTRY")
public class Country{
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
int id;
@Column(name="countryName")
String countryName;
@Column(name="population")
long population;
public Country() {
super();
}
public Country(int i, String countryName,long population) {
super();
this.id = i;
this.countryName = countryName;
this.population=population;
}
// getters and setters...
}
Spring config 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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url"
value="..." />
<beans:property name="username" value="postgres" />
<beans:property name="password" value="..." />
</beans:bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>org.arpit.java2blog.model.Country</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<context:component-scan base-package="org.arpit.java2blog" />
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
</beans:beans>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
答案 0 :(得分:1)
您的问题来自Session.load()
方法,该方法不返回对象,而是在第一次访问非标识符属性时初始化的对象的代理。
Hibernate文档:
T load(Class theClass, 可序列化的id)
返回具有给定标识符的给定实体类的持久化实例,假设是 实例存在。此方法可能返回一个代理实例 当访问非标识符方法时,按需初始化。
对于你而言,这意味着当Spring试图对该对象进行编组时会初始化它,即会话结束时。
要修复它,您可以在类级别添加@org.hibernate.annotations.Proxy(lazy = false)
,在dao中使用Session.get()
而不是Session.load()
来获取完全加载的对象(取决于成员的惰性策略) )。
或者,当Session仍然是通过调用对象的任何成员(比如在集合上调用List.size()
来强制加载)时手动触发延迟加载。