我在Hibernate上创建了一个简单易用的小应用程序。
我有一个Country
对象和一个City
对象。一个国家可以拥有许多城市。
我有以下无法解决的问题:
save
方法在Countries表中创建记录,但不在相应的Cities表中创建记录。
list
方法引发以下StackOverFlow异常。堆栈跟踪是1027行,所以我只发布前10行,因为它似乎重复。
堆栈跟踪
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/datatracker] threw exception [Handler processing failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError
at java.lang.Integer.toString(Unknown Source)
at java.lang.Integer.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at com.johnsteed.datatracker.model.Country.toString(Country.java:93)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
代码如下:
城市类
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.springframework.stereotype.Component;
@Component
@Entity
@Table(name = "cities")
public class City {
@Id
@GeneratedValue
Integer id;
String name;
Boolean visited;
String mainAttraction;
@ManyToOne
@JoinColumn(name = "countryId")
Country country;
public City () { }
public City(Integer id, String name, Boolean visited, String mainAttraction, Country country) {
this.id = id;
this.name = name;
this.visited = visited;
this.mainAttraction = mainAttraction;
this.country = country;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getVisited() {
return visited;
}
public void setVisited(Boolean visited) {
this.visited = visited;
}
public String getMainAttraction() {
return mainAttraction;
}
public void setMainAttraction(String mainAttraction) {
this.mainAttraction = mainAttraction;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
@Override
public String toString() {
return "City [id=" + id + ", name=" + name + ", visited=" + visited + ", mainAttraction=" + mainAttraction + ", country=" + country + "]";
}
}
国家/地区类
首选的是获取提取类型
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.springframework.stereotype.Component;
@Component
@Entity
@Table(name = "countries")
public class Country {
@Id
@GeneratedValue
Integer id;
String name;
String continent;
Boolean visited;
String leader;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "country")
List<City> cities;
public Country() { }
public Country(Integer id, String name, String continent, Boolean visited, String leader, List<City> cities) {
this.id = id;
this.name = name;
this.continent = continent;
this.visited = visited;
this.leader = leader;
this.cities = cities;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContinent() {
return continent;
}
public void setContinent(String continent) {
this.continent = continent;
}
public Boolean getVisited() {
return visited;
}
public void setVisited(Boolean visited) {
this.visited = visited;
}
public String getLeader() {
return leader;
}
public void setLeader(String leader) {
this.leader = leader;
}
public List<City> getCities() {
return cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
@Override
public String toString() {
return "Country [id=" + id + ", name=" + name + ", continent=" + continent + ", visited=" + visited + ", leader=" + leader + ", cities=" + cities + "]";
}
}
道
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.johnsteed.datatracker.model.Country;
@SuppressWarnings("unchecked")
@Repository
@Transactional("DataTrackerTransactionManager")
@Component("Dao")
public class Dao {
// MEMBERS
@Autowired
@Qualifier("DataTrackerSessionFactory")
protected SessionFactory sessionFactory;
// DATABASE METHODS
@Transactional
public List<Country> getCountries(){
Criteria criteria = session().createCriteria(Country.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return criteria.list();
}
@Transactional
public void saveCountry(Country country){
session().save(country);
}
@Transactional
protected Session session() {
// convenience method
return sessionFactory.getCurrentSession();
}
}
调用Dao方法
@RequestMapping(value = "geography/testDao", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody void testDao() throws Exception {
System.out.println(dao.getCountries());
Country country = new Country();
country.setContinent("Asia");
country.setLeader("Xi Jinping");
country.setName("China");
country.setVisited(false);
City city1 = new City();
city1.setMainAttraction("Great Wall");
city1.setName("Beijing");
city1.setVisited(false);
List<City> cityList = new ArrayList<City>();
cityList.add(city1);
country.setCities(cityList);
dao.saveCountry(country);
}
Spring Dao配置类
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Component
@Configuration
@EnableTransactionManagement
public class DaoConfig {
@Bean(name="DataTrackerDataSource")
public DataSource getDataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
try {
String username = "root";
String password = "xxx";
String dbUrl = "jdbc:mysql://localhost:3306/geography";
String driverClassName = "com.mysql.jdbc.Driver";
ds.setDriverClassName(driverClassName);
ds.setUrl(dbUrl);
ds.setUsername(username);
ds.setPassword(password);
} catch (Exception e) {
e.printStackTrace();
}
return ds;
}
//Hibernate Beans
@Bean(name="DataTrackerTransactionManager")
@Autowired
public HibernateTransactionManager transactionManager(@Qualifier("DataTrackerSessionFactory") SessionFactory sessionFactory) {
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory);
return htm;
}
@Bean(name="DataTrackerHibernateTemplate")
@Autowired
public HibernateTemplate getHibernateTemplate(@Qualifier("DataTrackerSessionFactory") SessionFactory sessionFactory) {
HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
return hibernateTemplate;
}
@Bean(name="DataTrackerSessionFactory")
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean asfb = new LocalSessionFactoryBean();
asfb.setDataSource(getDataSource());
asfb.setHibernateProperties(getHibernateProperties());
asfb.setPackagesToScan(new String[] { "com.johnsteed.datatracker.dao", "com.johnsteed.datatracker.model" });
return asfb;
}
@Bean(name="DataTrackerHibernateProperties")
public Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
properties.put("hibernate.show_sql", "false");
properties.put("hibernate.hbm2ddl.auto", "update");
properties.put("hibernate.hbm2ddl.auto", "update");
return properties;
}
}
国家/地区表
id int(11)
name varchar(45)
continent varchar(45)
visited tinyint(4)
leader varchar(45)
城市表
id int(11)
name varchar(45)
countryId varchar(45)
visited tinyint(4)
mainAttraction varchar(45)
我感谢任何帮助/建议,因为我无法弄清楚为什么代码对于这两种基本方法是不正确的。