简体   繁体   中英

spring 3.1.0 Release Hibernate 4.1.2 Final - Database configuration via annotation how to set properties

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

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM