Spring ORM JNDI Tomcat - No EntityManager with actual transaction available - java

I can find but i can't save my Entities.
Tomcat Context:
<Resource name="jdbc/spring" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="spring" password="spring" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/spitter"/>
DatabaseConfig and jpa config:
#Configuration
public class DatabaseConfig {
#Bean
public JndiObjectFactoryBean dataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/spring");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return jndiObjectFactoryBean;
}
#Bean
public JpaVendorAdapter jpaVendorAdapter(){
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setGenerateDdl(false);
adapter.setShowSql(true);
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
return adapter;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter adapter){
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean =
new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(adapter);
entityManagerFactoryBean.setPackagesToScan("com.springinaction.spittr");
entityManagerFactoryBean.setJpaProperties(jpaProperties());
return entityManagerFactoryBean;
}
#Bean
public PersistenceAnnotationBeanPostProcessor paPostProcessor(){
return new PersistenceAnnotationBeanPostProcessor();
}
#Bean
public BeanPostProcessor persistenceTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
private Properties jpaProperties(){
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", "create-drop");
return properties;
}
And DAO:
#Repository
#Transactional
public class UserRepositoryImpl implements UserRepository {
#PersistenceContext
private EntityManager entityManager;
#Override
public User findUser(Long id) {
return entityManager.find(User.class, id);
}
#Override
public User findUserByUsername(String username) {
return (User)entityManager.createQuery("Select u from User u where username= :username ")
.setParameter("username", username)
.getSingleResult();
}
#Override
public void addUser(User user) {
entityManager.persist(user);
}
}
Service:
#Service
public class UserService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = new User();
user.setUsername("admin");
user.setPassword("admin");
Role role = new Role();
role.setRole("ADMIN");
Role role2 = new Role();
role2.setRole("USER");
HashSet set = new HashSet();
set.add(role);
set.add(role2);
user.setRoles(set);
userRepository.addUser(user);
return userRepository.findUserByUsername(s);
}
}
When i am reaching userRepository.addUser(user) no entity is saved to my database and i got No EntityManager with actual transaction available exception.
Where am I wrong?

Ok, i didn't put #EnableTransactionManagement() over my configuration.
Closed

Related

Is there a way to map mutliple databases with same table names in a dynamic way?

First time I encounter this problem. The situation is:
I have more than 100 SQL databases, each one correspond to a different company and each one have the same three tables (same table names, same column names, same column data type).
Is there some way to map all these databases dynamically?
With dynamically I mean to have one class to which I can refer and make any CRUD operation.
After some research I could see what I wanted to do:
Basically I needed to change my data source in run time, for that I used a spring framework interface called AbstracRoutingDataSource.
Example:
Implementing AbstractRoutingDataSource:
public class MultiRoutingDataSource extends AbstractRoutingDataSource {
#Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.getCurrentDb();
}
}
DatabaseContextHolder:
public class DBContextHolder {
private static final ThreadLocal<DBTypeEnum> contextHolder = new ThreadLocal<>();
public static void setCurrentDb(DBTypeEnum dbType) {
contextHolder.set(dbType);
}
public static DBTypeEnum getCurrentDb() {
return contextHolder.get();
}
public static void clear() {
contextHolder.remove();
}
}
Database type enum:
public enum DBTypeEnum{
DATASOURCE1("DATASOURCE1"),
DATASOURCE2("DATASOURCE2");
DBTypeEnum(final String dbTypeEnum){
this.dbTypeEnum = dbTypeEnum;
}
private String dbTypeEnum;
public String dbTypeEnum(){
return dbTypeEnum;
}
}
Persistence configuration:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
basePackages = "base.packages.path",
entityManagerFactoryRef = "multiEntityManager",
transactionManagerRef = "multiTransactionManager"
)
public class PersistenceConfiguration {
private final String PACKAGE_SCAN = "base.package.path";
#Bean(name = "dataSource1")
#ConfigurationProperties("spring.datasource1")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
#Bean(name = "dataSource2")
#ConfigurationProperties("spring.datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
#Bean(name = "multiRoutingDataSource")
public DataSource multiRoutingDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DBTypeEnum.DATASOURCE1, dataSource1());
targetDataSources.put(DBTypeEnum.DATASOURCE2, dataSource2());
MultiRoutingDataSource multiRoutingDataSource = new MultiRoutingDataSource();
multiRoutingDataSource.setDefaultTargetDataSource(dataSource1());
multiRoutingDataSource.setTargetDataSources(targetDataSources);
return multiRoutingDataSource;
}
#Bean(name = "multiEntityManager")
public LocalContainerEntityManagerFactoryBean multiEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(multiRoutingDataSource());
em.setPackagesToScan(PACKAGE_SCAN);
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
return em;
}
#Bean(name = "multiTransactionManager")
public PlatformTransactionManager multiTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
multiEntityManager().getObject());
return transactionManager;
}
#Bean(name = "dbSessionFactory")
public LocalSessionFactoryBean dbSessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(multiRoutingDataSource());
sessionFactoryBean.setPackagesToScan(PACKAGE_SCAN);
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.show_sql", true);
properties.put("hibernate.format_sql", true);
return properties;
}
}
Then you need to have all of your database information in a .properties file:
spring.datasource1.jdbcUrl=jdbc:sql:sql-url:3306/datasource1
spring.datasource1.username=username
spring.datasource1.password=password
spring.datasource1.driver-class-name= Driver
spring.datasource2.jdbcUrl=jdbc:sql:sql-url:3306/datasource2
spring.datasource2.username=username
spring.datasource2.password=password
spring.datasource2.driver-class-name= Driver
Then you need to map your entity:
#Entity
#Table(name = "table_name")
#Getter
#Setter
public class MyEntity implements Serializable {
#Id
#Column(name = "ID", columnDefinition = "varchar(17)")
private String id;
//more fields...
}
I used spring CrudRepositories interface for this entity
public interface IMyEntityRepository extends CrudRepository<MyEntity, String> {
}
Finally my controller is prepared to change datasource depending on a JSON field in my request.
JSON:
{
"dataSource":"DATASOURCE1"
//more fields ...
}
RESTController:
#PutMapping("/url/{id}")
public ResponseEntity<?> editMyEntity(#RequestBody RequestObject request #PathVariable String id){
DBContextHolder.setCurrentDb(DBTypeEnum.valueOf(request.getDataSource);
iMyEntitiRepository.getMyEntity(id);
//...
}

What is wrong of this code? (Multiple Datasource Oracle)

Currently I have to connect two Oracle Datasources in my Spring Boot proyect. I think that I did well the configuration because Spring validated my connection but when I call a service this always response me "Empty". I think is because the TransactionManager don't change.
This is my project structure:
- project
⊢---- config
⊢---- controllers
∟---- models
⊢---- dao
| ⊢---- db1
| ∟---- db2
⊢---- entity
| ⊢---- db1
| ∟---- db2
⊢---- services
⊢---- db1
∟---- db2
This are my entities classes:
package project.models.entity.db1;
//// IMPORTS
#Entity(name = "User")
#Table(name = "T_USER")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Long id;
private String name;
private String surname;
private String username;
private String password;
////// CONSTRUCT
////// GETTERS & SETTERS
////// HASCODE, EQUALS AND TOSTRING
}
package project.models.entity.db2;
//// IMPORTS
#Entity(name = "Shareholder")
#Table(name = "Shareholder")
public class Shareholder implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Integer id;
private Integer numberTitles;
////// CONSTRUCT
////// GETTERS & SETTERS
////// HASCODE, EQUALS AND TOSTRING
}
This are my repositories classes:
package project.models.dao.db1;
//// IMPORTS
#PersistenceContext(name = "db1")
#Repository
public interface IUserDao extends JpaRepository<User, Long> {
}
package project.models.dao.db2;
//// IMPORTS
#PersistenceContext(name = "db2")
#Repository
public interface IShareholderDao extends JpaRepository<Shareholder, Integer> {
}
This are my services classes:
package project.models.services.db1.impl;
//// IMPORTS
#Service
public class UserServiceImpl implements IUserService {
#Autowired
private IUserDao userDao;
#Override
#Transactional("transactionManager")
public List<User> findAll() {
return userDao.findAll();
}
#Override
#Transactional("transactionManager")
public User findById(Long id) {
return userDao.findById(id).orElse(null);
}
package project.models.services.db2.impl;
//// IMPORTS
#Service
public class ShareholderServiceImpl implements IShareholderService {
#Autowired
private IShareholderDao shareholderDao;
#Override
#Transactional("db2TransactionManager")
public List<Shareholder> findAll() {
return shareholderDao.findAll();
}
#Override
#Transactional("db2TransactionManager")
public Shareholder findById(Integer id) {
return shareholderDao.findById(id).orElse(null);
}
}
And this are my config classes:
package project.config;
//// IMPORTS
#Configuration
#ConfigurationProperties(prefix = "oracle1")
#EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = {
"project.models.dao.db1" })
#EnableTransactionManagement
#Validated
public class Db1Config {
#NotNull
private String username;
#NotNull
private String password;
#NotNull
private String url;
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws SQLException {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[] { "project.models.entity.db1" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
em.setPersistenceUnitName("db1");
return em;
}
#Bean(name = "dataSource")
DataSource dataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(username);
dataSource.setPassword(password);
dataSource.setURL(url);
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
#Primary
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() throws SQLException {
return new JpaTransactionManager(entityManagerFactory().getObject());
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "validate");
return properties;
}
}
package project.config;
//// IMPORTS
#Configuration
#ConfigurationProperties(prefix = "oracle2")
#EnableJpaRepositories(entityManagerFactoryRef = "db2EntityManagerFactory", transactionManagerRef = "db2TransactionManager", basePackages = {
"project.models.dao.db2" })
#EnableTransactionManagement
#Validated
public class Db2Config {
#NotNull
private String username;
#NotNull
private String password;
#NotNull
private String url;
#Bean(name = "db2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory() throws SQLException {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(db2DataSource());
em.setPackagesToScan(new String[] { "project.models.entity.db2" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(hibernateProperties());
em.setPersistenceUnitName("db2");
return em;
}
#Bean(name = "db2DataSource")
DataSource db2DataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(username);
dataSource.setPassword(password);
dataSource.setURL(url);
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
#Bean(name = "db2TransactionManager")
public PlatformTransactionManager db2TransactionManager() throws SQLException {
return new JpaTransactionManager(db2EntityManagerFactory().getObject());
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "validate");
return properties;
}
}
And my main application:
package project;
//// IMPORTS
#SpringBootApplication
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class })
#EnableCaching
public class ProjectApplication {
#Autowired
private IUserService userService;
#Autowired
private IShareholderService shareholderService;
public static void main(String[] args) {
SpringApplication.run(ProjectApplication.class, args);
}
#PostConstruct
void init() {
List<User> user = userService.findAll();
List<Shareholder> shareholder = shareholderService.findAll();
System.out.println();
System.out.println(user);
System.out.println(shareholder);
System.out.println();
}
}
And always response me:
[User [id=39, name=Jack, surname=Sparrow, ...], [...], ...]
[]
What is the error? Because I don't see it.
Thank you very much
In Db2Config class, package being scanned is different than Db1Config.
Db1Config:
em.setPackagesToScan(new String[] { "project.models.entity.db1" });
Db2Config
em.setPackagesToScan(new String[] { "project.models.dao.db2" });

#Autowired SessionFactory returning null spring in Java configuration

I m having null pointer exception in sessionFactory when i try to use DI in sessionFactory I have to turn spring 3 project into Spring 4 with no xml. I dont know what the problem i m facing, SessionFactory doesnot autowired at all. when i try to test case generic doa Add Method
here is my Configuration File for bean
#Configuration
#EnableTransactionManagement
#EnableWebMvc
#ComponentScan(basePackages = "io.github.bibekshakya35.ehealth")
public class EhealthCofiguration {
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean(name = "dataSource")
public javax.sql.DataSource getDataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/ehealth");
dataSource.setUsername("test");
dataSource.setPassword("test123");
return dataSource;
}
#Autowired
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(javax.sql.DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("io.github.bibekshakya35.ehealth.model");
sessionBuilder.addProperties(getHibernateProperties());
return sessionBuilder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.hbm2ddl.auto", "update");
return properties;
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(
SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(
sessionFactory);
return transactionManager;
}
}
to load this class i have created
public class EhealthWebAppIntializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(EhealthCofiguration.class);
ServletRegistration.Dynamic dispatcher =servletContext.addServlet("SpringDispatcher", new DispatcherServlet(applicationContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
this is my generic doa class where i m injecting SessionFactory when it try to access sessionFactory.getCurrentSession(); NPE is occur,
#Repository
#Transactional
public class HibernateDAO<T extends Serializable> implements IGenericDao<T> {
private Class<T> clazz;
Session session;
#Autowired
SessionFactory sessionFactory;
private static final Logger LOG = Logger.getLogger(HibernateDAO.class.getName());
#Override
public void setClazz(Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
#Override
public void create(T entity) {
session = getCurrentSession();
LOG.log(Level.INFO, "inside create entity and you just bind your session to the current one{0}", session.toString());
session.saveOrUpdate(entity);
LOG.info("saved");
session.flush();
session.refresh(entity);
}
protected Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
Here is my stack trace for NPE
Exception in thread "main" java.lang.NullPointerException
at io.github.bibekshakya35.ehealth.DAO.genericdao.HibernateDAO.getCurrentSession(HibernateDAO.java:115)
at io.github.bibekshakya35.ehealth.DAO.genericdao.HibernateDAO.create(HibernateDAO.java:85)
at io.github.bibekshakya35.ehealth.service.impl.user.main(user.java:46)
here is my user entity
#Entity
#Table(name = "users")
public class User implements Serializable, AbstractEntity {
#Id
#Column(name = "username",unique = true)
private String userName;
#NotNull(message = "password cannot be empty")
#Column(name = "users_password")
private String userPassword;
#Embedded
private UserProfile userProfile;
#Embedded
private AuditInfo auditInfo;
#Enumerated(EnumType.STRING)
private UserType userType;
#Column(name = "is_active")
private boolean active = true;
//getter n setter
}
In chat, You provided me with this code :
public static void main(String[] args) {
User user = new User();
IGenericDao<User> iGenericDao = new HibernateDAO<>();
user.setUserName("bibekshakya35");
user.setUserPassword("ros3");
user.setUserType(UserType.GUEST);
user.setActive(true);
UserProfile userProfile = new UserProfile();
userProfile.setAge(21);
userProfile.setBasicInfo("kdhsa");
userProfile.setEmailId("dsadas#gmail.com");
userProfile.setUserGender(UserGender.Male);
userProfile.setFullname("bibek shakya");
userProfile.setMobileNumber("45454545");
userProfile.setLandLineNumber("445444");
userProfile.setUserProfilePic("index.jsp");
user.setUserProfile(userProfile);
AuditInfo auditInfo = new AuditInfo();
auditInfo.setCreatedOn(new Date());
auditInfo.setModifiedOn(new Date());
auditInfo.setVerifiedOn(new Date());
user.setAuditInfo(auditInfo);
iGenericDao.create(user);
}
Cause of error:
As You are creating the new HibernateDAO instance like this IGenericDao<User> iGenericDao = new HibernateDAO<>(); This is creating the problem.
In the case where You are using annotations, creating new instance manually ,usually causes the above mentioned error.
Reason of error:
Spring can only autowire beans that it manages; if you call new to create a bean yourself, #Autowired fields don't get filled in (and methods like #PostConstruct aren't called).
Solution:
You need to add #autowired to the HibernateDAO which will instantiate it with the exact class which includes the real #Autowired SessionFactory.
Example:
Usually we do it in the class which is itself annotated with annotations like #Controller or #Service.
Like this
#Controller
#RequestMapping(value="/someURL")
public class mainClass {
#Autowired
HibernateDAO abc;
//Code (methods) to test Your CRUD Operations
}

HibernateException: No CurrentSessionContext configured! in spring boot

I have the following configuration:
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackageClasses = DemoApplication.class)
public class JpaConfig implements TransactionManagementConfigurer {
#Value("${dataSource.driverClassName}")
private String driver;
#Value("${dataSource.url}")
private String url;
#Value("${dataSource.username}")
private String username;
#Value("${dataSource.password}")
private String password;
#Value("${hibernate.dialect}")
private String dialect;
#Value("${hibernate.hbm2ddl.auto}")
private String hbm2ddlAuto;
#Bean
public DataSource configureDataSource() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driver);
config.setJdbcUrl(url);
config.setUsername(username);
config.setPassword(password);
return new HikariDataSource(config);
}
#Bean
public LocalContainerEntityManagerFactoryBean configureEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(configureDataSource());
entityManagerFactoryBean.setPackagesToScan("com.dataart.cashmashine");
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put(org.hibernate.cfg.Environment.DIALECT, dialect);
jpaProperties.put(org.hibernate.cfg.Environment.HBM2DDL_AUTO, hbm2ddlAuto);
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
#Bean
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new JpaTransactionManager();
}
#Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
return hemf.getSessionFactory();
}
}
application.properties:
dataSource.driverClassName=org.postgresql.Driver
dataSource.url=jdbc:postgresql://localhost:5432/cash_mashine
dataSource.username=marc
dataSource.password=marc
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.hbm2ddl.auto=create-drop
In dao I write following rows:
#Autowired
private SessionFactory sessionFactory;
#Override
public CreditCard findCard(String cardNumber) {
Session currentSession = sessionFactory.getCurrentSession();
when executes
sessionFactory.getCurrentSession()
I see following error:
Caused by: org.hibernate.HibernateException: No CurrentSessionContext
configured!
How to fix this?
spring:
jpa:
properties:
hibernate:
current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext
above config in application.yml can solve this problem.
Try adding #Transactional at a public service method which is invoking the DAO.

No transactional EntityManager available when Persisting an object

I have got No transactional EntityManager available exception when I tried to persist an object.
I have a Spring project with the following configuration class:
#Configuration
#ComponentScan
#EnableTransactionManagement
#EnableJpaRepositories
public class SpringConfiguration {
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean emf(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emf =new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
jpaProperties.put("hibernate.show_sql", "true");
emf.setJpaProperties(jpaProperties);
emf.setPackagesToScan(
new String[] {"ds.core.entity"});
emf.setJpaVendorAdapter(
new HibernateJpaVendorAdapter());
return emf;
}
#Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory emf,DataSource dataSource) {
JpaTransactionManager tm =
new JpaTransactionManager();
tm.setEntityManagerFactory(emf);
tm.setDataSource(dataSource);
return tm;
}
And an entity class:
#Entity
public class Type {
#Id #GeneratedValue
private Long id;
private String name;
}
and Jpa implementation class :
#Repository
public class JpaTypeRepo implements TypeRepo {
#PersistenceContext
private EntityManager em;
#Override
public Type insertRecord(Type data) {
em.persist(data);
return data;
}
}
And finally a Service Class with Init():
#Transactional
#Service
public class InitDbService {
#Autowired
private TypeRepo typeRepo;
#PostConstruct
public void init() {
Type type=new Type();
type.setName("newName");
typeRepo.insertRecord(type);
}}
just add #Transactional annotation to the class :JpaTypeRepo
as following:
#Transactional
#Repository
public class JpaTypeRepo implements TypeRepo {
#PersistenceContext
private EntityManager em;
#Override
public Type insertRecord(Type data) {
em.persist(data);
return data;
}
}

Categories

Resources