Hibernate(Java Configuration) - no persistence units parsed from classpath* meta-inf/persistence.xml spring? - spring

in my Vaadin-Project configured the Spring, now trying to set up giberneyt, and read on the forums - all recommend to add a folder and file. That is understandable, but why? I want all configuration register in java-file.
Here is my config file.
#Configuration
#ComponentScan(basePackageClasses = ApplicationInitializer.class)
#EnableTransactionManagement
#PropertySource("classpath:database.properties")
#EnableJpaRepositories(basePackages = "com.jdev.blog.admin.crud.repositories")
public class ApplicationConfiguration {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
return properties;
}
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
Error at startup.
20:51:23,476 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-1) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactor
y' defined in class com.jdev.blog.admin.config.ApplicationConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalStateException: No persistence units parsed from {classpath*:META-INF/persistence.xml}
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553) [spring-beans-4.0.6.RELEASE.jar:4.0.6.RELEASE]

I think you need emfb.setPackagesToScan("com.package.entity") to insead of persistence.xml
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean emfb =
new LocalContainerEntityManagerFactoryBean();
emfb.setDataSource(dataSource);
emfb.setJpaVendorAdapter(jpaVendorAdapter);
emfb.setPackagesToScan("com.package.entity");
return emfb;
}

Related

Spring boot configuration for #Transactional for both JPA and spring-JDBC-templete

in my project, I am using both JPA and spring-jdbc-template & NamedParameterTemplate.
I need to get transaction support for both.
So how to configure #Transactional for both JPA & spring-JDBC ?
Here are the 2 classes I used for configuring those.
Class number 1: PersistenceConfiguration
This is the class that declares transaction-management should be enabled.
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = {"com.google.product.repository"},
excludeFilters = #ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.google.product.repository.mongoRepository.*.*Repository"))
public class PersistenceConfiguration {
#Autowired
private DataSource dataSource;
#Autowired
private Properties entityManagerProperties;
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.google.product.model");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(entityManagerProperties);
return em;
}
}
Class number 2: ProdDatabaseConfiguration
This is the class that declares beans releted toJDBC & JPA. for example primaryJdbcTemplate ,secondaryJdbcTemplate & entityManagerProperties.
#Configuration
#PropertySource({"classpath:database-prod.properties"})
#Profile("prod")
public class ProdDatabaseConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(ProdDatabaseConfiguration.class);
#Value("${jdbc.jndiName}")
private String jndiName;
#Value("${hibernate.dialect}")
private String hibernateDialect;
#Value("${hibernate.show_sql}")
private String hibernateShowSql;
#Value("${hibernate.cache.use_second_level_cache}")
private String hibernateSecondLevelCache;
#Value("${hibernate.cache.use_query_cache}")
private String hibernateQueryCache;
#Value("${jadira.usertype.databaseZone}")
private String databaseZone;
#Value("${jadira.usertype.javaZone}")
private String javaZone;
#Value("${mongo.jndiName}")
private String mongoJndiName;
#Bean
public DataSource dataSource() {
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
return jndiDataSourceLookup.getDataSource(jndiName);
}
#Bean(name = "entityManagerProperties")
public Properties additionalProperties() {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "none");
hibernateProperties.setProperty("hibernate.dialect", hibernateDialect);
hibernateProperties.setProperty("hibernate.show_sql", hibernateShowSql);
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", hibernateSecondLevelCache);
hibernateProperties.setProperty("hibernate.cache.use_query_cache", hibernateQueryCache);
hibernateProperties.setProperty("jadira.usertype.databaseZone", databaseZone);
hibernateProperties.setProperty("jadira.usertype.javaZone", javaZone);
return hibernateProperties;
}
#Bean(name = "primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate() {
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
return new JdbcTemplate(jndiDataSourceLookup.getDataSource(jndiName));
}
#Bean(name = "secondaryJdbcTemplate")
public NamedParameterJdbcTemplate secondaryJdbcTemplate() {
JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
return new NamedParameterJdbcTemplate(jndiDataSourceLookup.getDataSource(jndiName));
}
Because you are only using one datasource you can remove all the configuration and just use the spring.datasource properties.
Transaction will also work out of the box because you will have only this datasource.
Read more about this topic in the official documentation:
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-sql

Wrong transaction manger is being used in Spring

I have two spring transaction managers.
txManager1 - ChainedKafkaTransactionManager (KafkaTransactionManager,JpaTransactionManager) configured with datasource DB1
txManager2 - JpaTransactionManager configured with datasource DB2
The problem is that I perform some operation using txManager2 but somehow txManager1 is being used instead of txManager2 and the data is getting committed to DB1 instead of DB2.
#Autowired
#Qualifier("common-tx")
private PlatformTransactionManager txManager2 ;
#KafkaListener(topics = "${kafka.topic.name}", groupId = "group-1", containerFactory = "customKafkaListenerContainerFactory")
public void topicListener(String message, Acknowledgment ack)
throws InterruptedException, ClassNotFoundException, IOException {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(domainEvent.getEventId());
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus commonStatus = txManager2 .getTransaction(def);
someService.doSomething();
txManager2 .commit(commonStatus);
ack.acknowledge();
}
In doSomething() I am just persisting an entity, upon debugging it is found that while saving the entity via Spring data repository, the transaction manager
determined in invokeWithinTransaction() of org.springframework.transaction.interceptor.TransactionAspectSupport is wrong, i.e. txManager1 is selected instead of txManager2, is it a configuration issue or am I missing something?
txManager1 configuration :
#Configuration
#EnableTransactionManagement
#PropertySource(value = {"classpath:application-${spring.profiles.active}.properties"})
#Profile({"development","production","qa"})
#EnableJpaRepositories(basePackages={"xxx.xxx.xxxx"},excludeFilters=#ComponentScan.Filter(type=FilterType.REGEX, pattern="xxx.xxx.xxxx.module2.*"))
public class JPAConfig1 {
#Value("${jndi.name}")
private String jndiName;
#Value("${hibernate.dialect}")
private String hibernateDialect;
#Value("${hibernate.show_sql}")
private String showSql;
#Value("${hibernate.format_sql}")
private String formatSql;
#Value("${hibernate.hbm2ddl.auto}")
private String hiberanteUpdate;
#Value("${javax.persistence.validation.mode}")
private String hibernateValidation;
#Bean
#Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver)
{
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
emf.setJpaProperties(jpaProperties(tenantConnection, currentTenantIdentifierResolver));
emf.setPackagesToScan(new String[] {"xxx.xxx.xxxx"});
return emf;
}
private Properties jpaProperties(MultiTenantConnectionProviderImpl tenantConnection, CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",hibernateDialect);
properties.setProperty("hibernate.show_sql",showSql);
properties.setProperty("hibernate.format_sql",formatSql);
properties.setProperty("hibernate.hbm2ddl.auto",hiberanteUpdate);
properties.setProperty("javax.persistence.validation.mode",hibernateValidation);
properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, tenantConnection);
return properties;
}
#Bean
public CurrentTenantIdentifierResolver getCurrentTenantIdentifierResolver(TenantContext tenantContext) {
return new CurrentTenantIdentifierResolverImpl(tenantContext);
}
#Bean(name="tenantConnection")
public MultiTenantConnectionProviderImpl getMultiTenantConnectionProvider(TenantContext tenantContext) {
return new MultiTenantConnectionProviderImpl(false,tenantContext);
}
#Bean
#Primary
public PlatformTransactionManager transactionManager(EntityManagerFactory factory,ProducerFactory producerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(factory);
KafkaTransactionManager tm = new KafkaTransactionManager(producerFactory);
return new ChainedKafkaTransactionManager(tm,transactionManager);
}
#Bean
public TenantContext getTenantContext() {
return new TenantContextImpl();
}
}
txManager2 configuration :
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages="xxx.xxx.xxxx.module2",
entityManagerFactoryRef="common-factory",transactionManagerRef="common-tx")
#PropertySource(value = {"classpath:common-${spring.profiles.active}.properties"})
#Profile({"development","production","qa"})
public class JPAConfig2 {
#Value("${common.jndi.name}")
private String jndiName;
#Value("${common.hibernate.dialect}")
private String hibernateDialect;
#Value("${common.hibernate.show_sql}")
private String showSql;
#Value("${common.hibernate.format_sql}")
private String formatSql;
#Value("${common.hibernate.hbm2ddl.auto}")
private String hiberanteUpdate;
#Value("${common.javax.persistence.validation.mode}")
private String hibernateValidation;
#Bean(name="common-factory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(#Qualifier("common-ds") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan(new String[] {"xxx.xxx.xxxx.module2"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(jpaProperties());
em.setPersistenceUnitName("common");
return em;
}
#Bean("common-ds")
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup(jndiName);
}
private Properties jpaProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect",hibernateDialect);
properties.setProperty("hibernate.show_sql",showSql);
properties.setProperty("hibernate.format_sql",formatSql);
properties.setProperty("hibernate.hbm2ddl.auto",hiberanteUpdate);
properties.setProperty("javax.persistence.validation.mode",hibernateValidation);
return properties;
}
#Bean(name="common-tx")
public PlatformTransactionManager transactionManager(#Qualifier("common-factory") EntityManagerFactory factory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(factory);
return transactionManager;
}
}

Spring Boot - using JPA Repositories with Hibernate

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();
}
}

Spring JPA+Hibernate not able to fetch record using findAll() of JPARepository

I have created configuration using below code :
#Configuration
#EnableTransactionManagement
#ComponentScan("Name of package")
#EnableJpaRepositories("Name of package")
public class Config {
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "Name of package";
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("Driver Name");
dataSource.setUrl("Url");
dataSource.setUsername("UserName");
dataSource.setPassword("Password");
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setPackagesToScan(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN);
entityManagerFactoryBean.setJpaProperties(hibProperties());
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return entityManagerFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, "org.hibernate.dialect.DB2Dialect");
properties.put("hibernate.default_schema","Schema Name");
return properties;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}
There is an custom repository interface that implements JPARepository.
I have autowired the custom repository in controller and tried to call findAll().But the method returns 0 although there are 3 records in DB.
I am using spring web for rest service calls.
Entity class is created with #Entity and #Table annotations.It has an embedded key which is annotated using #EmbeddedId annotation.
#Repository
public interface EntityRepository extends JpaRepository<EntityTable, Long> {
#SuppressWarnings("unchecked") EntityTable save(EntityTable entityTable);
}
Entity table is the name of my table mapped with db table.

BeanDefinitionStoreException exception since trying to switch app to javaconfig from xml config

I am running into some configuration issue since trying to switch to javaconfig from xml config.
Here is the problematic configuration class:
#Configuration
#EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
#Profile({ "default", "cloud" })
public class DataConfiguration {
#Value("${database.driverClassName}")
private String driverClassName;
#Value("${database.url}")
private String url;
#Value("${database.username}")
private String username;
#Value("${database.password}")
private String password;
#Value("${database.validationQuery}")
private String validationQuery;
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setTestOnBorrow(Boolean.TRUE);
dataSource.setTestOnReturn(Boolean.TRUE);
dataSource.setTestWhileIdle(Boolean.TRUE);
dataSource.setTimeBetweenEvictionRunsMillis(1800000);
dataSource.setNumTestsPerEvictionRun(3);
dataSource.setMinEvictableIdleTimeMillis(1800000);
dataSource.setValidationQuery(validationQuery);
dataSource.setMaxActive(5);
dataSource.setLogAbandoned(Boolean.TRUE);
dataSource.setRemoveAbandoned(Boolean.TRUE);
dataSource.setRemoveAbandonedTimeout(10);
return dataSource;
}
#Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory());
return transactionManager;
}
#Bean
public HibernateJpaVendorAdapter jpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
#Bean
public HibernatePersistence persistenceProvider() {
return new HibernatePersistence();
}
#Bean(name = "entityManagerFactory", destroyMethod = "close")
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setPackagesToScan("com.bignibou.domain");
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProvider(persistenceProvider());
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
return entityManagerFactoryBean.getObject();
}
public Map<String, String> propertiesMap() {
Map<String, String> propertiesMap = new HashMap<>();
propertiesMap.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
propertiesMap.put("hibernate.hbm2ddl.auto", "update");
propertiesMap.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
propertiesMap.put("hibernate.connection.charSet", "UTF-8");
propertiesMap.put("hibernate.show_sql", "true");
propertiesMap.put("hibernate.format_sql", "true");
propertiesMap.put("hibernate.use_sql_comments", "true");
return propertiesMap;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
}
Here is the exception I get:
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static javax.persistence.EntityManager org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(javax.persistence.EntityManagerFactory)] threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
... 121 more
Caused by: java.lang.NullPointerException
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.initProxyClassLoader(SharedEntityManagerCreator.java:151)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.<init>(SharedEntityManagerCreator.java:143)
at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:118)
at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:96)
at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
... 122 more
It seems there's an issue with the entityManagerFactory config... What I am getting wrong?
If you are not using the entityManagerFactory() method anywhere in your java configuration, you can instead return the LocalContainerEntityManagerFactoryBean object.
The LocalContainerEntityManagerFactoryBean is both an InitializingBean and a FactoryBean. These are special interfaces that Spring can use to initialize a bean and then add it to the context.
You could therefore change your method to
#Bean(name = "entityManagerFactory", destroyMethod = "close")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setPackagesToScan("com.bignibou.domain");
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProvider(persistenceProvider());
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
return entityManagerFactoryBean;
}
Spring will take care of calling afterPropertiesSet() and getObject() on the object returned by the method and adding the created EntityManagerFactory bean to the context.
This is detailed in the IoC chapter of the Spring documentation.
adding the following line sorted the issue:
entityManagerFactoryBean.setJpaPropertyMap(propertiesMap());
entityManagerFactoryBean.afterPropertiesSet();//NOTICE HERE!!!
return entityManagerFactoryBean.getObject();

Resources