问题
I am using configuration as in the code listed below. auto create/drop function seams not to work as it should (it does not create/maintain tables in the database (dataSource.setConnectionProperties(hibernateProperties());))
(It works when table is already created in the DB? I think that properties are not taken into consideration here?),
Config
package com.parisibw.persistance;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.parisibw.forms.Contact;
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
@Bean
public SessionFactory sessionFactory() {
return new LocalSessionFactoryBuilder(datasource()).addAnnotatedClasses(Account.class, Contact.class).buildSessionFactory();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new HibernateTransactionManager(sessionFactory());
}
@Bean
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "create");
//properties.put("hibernate.connection.driver_class", "org.h2.Driver");
//properties.put("hibernate.connection.url", "jdbc:h2:db/test;CIPHER=AES");
//properties.put("hibernate.connection.username", "root");
//properties.put("hibernate.connection.password", "root root");
//properties.put("hibernate.connection.pool_size", "1");
//properties.put("hibernate.format_sql", "true");
//properties.put("hibernate.use_sql_comments", "true");
//properties.put("hibernate.c3p0.min_size", "5");
//properties.put("hibernate.c3p0.max_size", "20");
//properties.put("hibernate.c3p0.timeout", "300");
//properties.put("hibernate.c3p0.max_statements", "50");
//properties.put("hibernate.c3p0.idle_test_period", "3000");
//properties.put("hibernate.cache.use_second_level_cache", "true");
//properties.put("hibernate.cache.region.factory_class",
//"org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
//properties.put("hibernate.cache.use_query_cache", "true");
//properties.put("hibernate.cache.use_minimal_puts", "true");
//properties.put("hibernate.max_fetch_depth", "10");
return properties;
}
@Bean
public DataSource datasource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://dbpath");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setConnectionProperties(hibernateProperties());
return dataSource;
}
}
Account
@Entity @Table(name="T_ACCOUNT")
public class Account {
@Id
private long id;
@Column
private double cashBalance;
@Column
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public double getCashBalance() {
return cashBalance;
}
public void setCashBalance(double cashBalance) {
this.cashBalance = cashBalance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "id: " + id + ", balance: " + cashBalance + ", name: " + name;
}
test class
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String homeTest(Model model) {
Account account = new Account();
try{
sessionFactory = new HibernateConfig().sessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
//account.setId(2);
account.setName("Marcin");
account.setCashBalance(1200);
session.save(account);
session.getTransaction().commit();
session.close();
}catch (Exception e) {
logger.info(e.toString());
}
model.addAttribute("serverTime" );
return "test";
}
回答1:
You're passing your hibernate properties as connection properties for your datasource. Instead, they should be passed to the sessionfactory.
@Bean
public SessionFactory sessionFactory() {
return new LocalSessionFactoryBuilder(datasource())
.addAnnotatedClasses(Account.class, Contact.class)
.addProperties(hibernateProperties())
.buildSessionFactory();
}
See http://docs.jboss.org/hibernate/core/3.6/javadocs/org/hibernate/cfg/Configuration.html?is-external=true (parent class for LocalSessionFactoryBuilder)
回答2:
The first problem I see here is that you're explicitly creating a new HibernateConfig instead of allowing spring to autowire it. So in your test class add the following property:
@Autowire
private SessionFactory sessionFactory;
Looking deeper, it looks like you might want to read up a little on Spring and IOC because you're kinda doing it in a strange way that looks like you might be a little confused. Everything you're trying to do is actually kinda already built into Spring so you're kinda reinventing the wheel. In short, you're creating new instances of things instead of getting them from spring's context so it has now way to hook things together for you.
Take a look at how this is being done here (yes it has other problems, but you should be able to get the general idea): Proper way to autowire a Hibernate Session in a Spring Transaction JUnit test
来源:https://stackoverflow.com/questions/10948539/spring-3-1-0-release-hibernate-4-1-2-final-database-configuration-via-annotati