We are configuring Hibernate using java, here is our code to configure hibernate.
#Configuration
#EnableTransactionManagement
#ComponentScan({ "org.npcc.ccms.config" })
#PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
final static Logger logger = LogManager.getLogger(HibernateConfiguration.class);
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "org.npcc.ccms.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean(destroyMethod="")
public DataSource dataSource() {
JndiTemplate jndi = new JndiTemplate();
DataSource dataSource = null;
try {
dataSource = (DataSource) jndi.lookup(environment.getRequiredProperty("datasource"));
} catch (NamingException e) {
logger.error("NamingException for java:comp/env/jdbc/ccms_cp1_orcl", e);
}
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
My question is how can configure another datasource within same hibernate configuration class? I found solution here but using xml configuration, how this works using java configuration? Thanks in advance.
You will need two different beans annotated as follows:
#Bean(name="SessionFactory")
public SessionFactory sessionFactory() {
}
and:
#Bean(name="OtherSessionFactory")
public SessionFactory otherSessionFactory() {
}
And two datasources configured appropriately.
Then when you want to use the other SessionFactory you just need:
#Autowired
#Qualifier("SessionFactory")
SessionFactory sessionFactory
or
#Autowired
#Qualifier("OtherSessionFactory")
SessionFactory sessionFactory
Related
I use spring version 5.0.1, hibernate version 5.2.12.
When I call getHibernateTemplate (), I get null
what am I doing wrong?
Dao confif:
#PropertySource(value = {"classpath:hibernate.properties"})
#ComponentScan("ru.bochkarev.hmcs.dao")
#EnableTransactionManagement
#Configuration
public class DaoConfig {
#Autowired
private Environment environment;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("hibernate.connection.driver_class"));
dataSource.setUrl(environment.getRequiredProperty("hibernate.connection.url"));
dataSource.setUsername(environment.getRequiredProperty("hibernate.connection.username"));
dataSource.setPassword(environment.getRequiredProperty("hibernate.connection.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
return properties;
}
#Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("ru.bochkarev.hmcs.model");
sessionFactory.setHibernateProperties(hibernateProperties());
try {
sessionFactory.afterPropertiesSet();
} catch (IOException e) {
e.printStackTrace();
}
return sessionFactory.getObject();
}
#Bean
public HibernateTransactionManager hibernateTransactionManager(){
return new HibernateTransactionManager(sessionFactory());
}
#Bean
public HibernateTemplate hibernateTemplate() {
return new HibernateTemplate(sessionFactory());
}
}
.................................................................
Implement dao:
#Transactional
#Repository
public class DaoTest extends HibernateDaoSupport {
public void save(TestModel testModel) {
getHibernateTemplate().saveOrUpdate(testModel);
}
}
When I call getHibernateTemplate (), I get null
Try below code for your DAO class and let us know if it works.
#Transactional
#Repository
public class DaoTest {
#Autowired
private HibernateTemplate hibernateTemplate;
public void save(TestModel testModel) {
getHibernateTemplate().saveOrUpdate(testModel);
}
}
I get ORA-00942: table or view does not exist at runtime when the code reaches this line : session.merge(role);
So how to show the query text executed during this merge ?
update :
here is how I configured the app :
#Configuration
#ComponentScan("com.ambre.pta")
#EnableTransactionManagement
#PropertySources({
#PropertySource("classpath:jdbc.properties"),
#PropertySource("classpath:fr/global.properties"),
#PropertySource("classpath:fr/main.properties"),
#PropertySource("classpath:fr/admin.properties"),
#PropertySource("classpath:fr/referentiel.properties"),
#PropertySource("classpath:fr/departement.properties"),
#PropertySource("classpath:fr/exercice.properties"),
#PropertySource("classpath:fr/defi.properties")
})
public class ApplicationContextConfig {
#Autowired
private Environment env;
#Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean(name = "viewResolver")
public InternalResourceViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean(name = "dataSource")
public DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:#"+env.getProperty("jdbc.server")+":"+env.getProperty("jdbc.port")+":"+env.getProperty("jdbc.instance"));
dataSource.setUsername(env.getProperty("jdbc.login.default"));
dataSource.setPassword(env.getProperty("jdbc.pwd.default"));
return dataSource;
}
#Autowired
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.ambre.pta.model");
return sessionBuilder.buildSessionFactory();
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Autowired
#Bean(name = "utilisateurDao")
public UtilisateurDAO getUtilisateurDao(SessionFactory sessionFactory) {
return new UtilisateurDAOImpl(sessionFactory);
}
#Autowired
#Bean(name = "menuDao")
public MenuDAO getMenuDao(SessionFactory sessionFactory) {
return new MenuDAOImpl(sessionFactory);
}
...
}
Please add the below tag to your hibernate config
<property name="show_sql">true</property>
look into
hibernate config file
application.yml file, there might be hibernate configuration and show-sql: true option.
I have a simple Spring Boot application with the following auto-configuration properties:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/mywebapp
spring.datasource.username=username
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=validate
These work fine and I'm able to setup Spring Data JpaRepositories:
public interface UserRepository extends JpaRepository<User, String>
{
User findByName(String name);
}
...for the following entities:
#Entity
public class User
{
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
protected String uuid;
#Column(nullable = false)
private String name;
#Column(nullable = false)
private String password;
#Column(nullable = false)
private String email;
}
...and use them like this:
#Transactional
public void updatePassword(String username, String password)
{
User user = userRepository.findByName(username);
user.setEmail("test#example.com"); // This gets persisted automatically by the JpaRepository.
}
Now I'm struggling to configure the same thing manually. I've tried the following:
#Configuration
#EnableTransactionManagement
public class PersistenceConfig
{
#Bean
public DataSource dataSource()
{
DataSource dataSource = new DataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/mywebapp");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan("com.example.persistent");
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "validate");
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean
public HibernateTransactionManager transactionManager()
{
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
...but while no exceptions are thrown and i can now successfully read from the database, it seems that none of the changes I make to the entities are being persisted.
Does anyone have an idea what I'm missing for the persistence to work?
OP here.
I seem to have misunderstood that JPA needs an EntityManager instead of a session.
The following configuration works:
#Configuration
#EnableTransactionManagement
public class PersistenceJpaConfig
{
#Bean
public DataSource dataSource()
{
DataSource dataSource = new DataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/mywebapp");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.example.persistent");
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.setProperty("hibernate.hbm2ddl.auto", "validate");
em.setJpaProperties(properties);
return em;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf)
{
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
{
return new PersistenceExceptionTranslationPostProcessor();
}
}
I am running a JUnit test case with the following spring config. THe automatic schema creation is not happening.
#Configuration
public class DatabaseConfiguration {
#Bean
DataSource dataSource() {
BasicDataSource ret = new BasicDataSource();
ret.setDriverClassName("com.mysql.jdbc.Driver");
ret.setUrl("jdbc:mysql://localhost:3306/mydb");
ret.setUsername("root");
ret.setPassword("root");
return ret;
}
#Bean
SessionFactory sessionFactoryBean(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(
dataSource);
sessionBuilder.scanPackages("com.mypackage.domain");
sessionBuilder.addProperties(getHibernateProperties());
return sessionBuilder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.show_sql", "true");
properties.put("hbm2ddl.auto", "create");
properties.put("hibernate.dialect",
"org.hibernate.dialect.MySQLDialect");
return properties;
}
#Bean
HibernateTransactionManager transactionManager(SessionFactory lsfb) {
HibernateTransactionManager mgr = new HibernateTransactionManager();
mgr.setSessionFactory(lsfb);
return mgr;
}
}
I have debugged to make sure that the schema creation is actually getting skipped.
Any idea why the schema creation might get skipped?
Try with hibernate.hbm2ddl.auto instead of hbm2ddl..auto
I try to setup a project with spring-test using TestNg in Maven. The code is like:
#ContextConfiguration(classes={WebMvcTestConfig.class})
public class MyResourceParserTest extends AbstractTestNGSpringContextTests {
#BeforeMethod
public void setup() throws Exception {
}
A WebMvcTestConfig class simply defined a bean:
#Configuration
#ComponentScan(basePackages={"com.test.myapp.model"})
#EnableTransactionManagement
public class WebMvcTestConfig {
private static final String relativeConfigURI = "\\MyAppSpringConfig\\";
private static final String userHomeURI = System.getProperty("user.home");
private static final String jdbcPropertiesFileName = "jdbc.properties";
private static final String hibernatePropertiesFileName = "hibernate.properties";
#Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new FileSystemResource(userHomeURI + relativeConfigURI + jdbcPropertiesFileName));
return propertySourcesPlaceholderConfigurer;
}
#Bean
public DataSource dataSource(
#Value("${jdbc.driverClassName}") String driverClass,
#Value("${jdbc.url}") String jdbcUrl,
#Value("${jdbc.username}") String username,
#Value("${jdbc.password}") String password) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(jdbcUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
#Bean
public LocalSessionFactoryBean localSessionFactoryBean() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource("", "", "", ""));
sessionFactory.setPackagesToScan("com.test.myapp.model.domain");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
try {
hibernateProperties.load(new FileInputStream(userHomeURI + relativeConfigURI + hibernatePropertiesFileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
return hibernateProperties;
}
#Bean
public PlatformTransactionManager platformTransactionManager() {
return new HibernateTransactionManager(localSessionFactoryBean().getObject());
}
}
I got error for Failed to load ApplicationContext when running mvn test from command line:
java.lang.IllegalStateException: Failed to load ApplicationContext
Can you help me?
3 things I notice from your configuration.
Your loading of configuration files is strange, use Spring for that instead of rolling your own. Simply use #PropertySource for that.
The propertySourcesPlaceholderConfigurer() must be static
Your call to datasource will lead to an invalid datasource configuration.
Try the following configuration class.
#Configuration
#ComponentScan(basePackages={"com.test.myapp.model"})
#EnableTransactionManagement
#PropertySource({"${user.home}/MyAppSpringConfig/jdbc.properties","${user.home}/MyAppSpringConfig/hibernate.properties"}
public class WebMvcTestConfig {
#Autowired
private Environment env;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new new PropertySourcesPlaceholderConfigurer();
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getRequiredProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("env.username", ""));
dataSource.setPassword(env.getProperty("env.password", ""));
return dataSource;
}
#Bean
public LocalSessionFactoryBean localSessionFactoryBean() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.test.myapp.model.domain");
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
// Other properties
return hibernateProperties;
}
#Bean
public PlatformTransactionManager platformTransactionManager() {
return new HibernateTransactionManager(localSessionFactoryBean().getObject());
}
}