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.
Related
I have a little program with Java Netbeans and the Spring framework, but I have the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'config': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.driverClassName' in value "${spring.datasource.driverClassName}"
I have Config.Java using the following code:
#Configuration
#EnableTransactionManagement
#EnableAutoConfiguration(exclude = { HibernateJpaAutoConfiguration.class})
#ComponentScans(value = { #ComponentScan("boot.entry"),
#ComponentScan("Model"),
#ComponentScan("Controller"),
#ComponentScan("DAO"),
#ComponentScan("Miscallaneous"),
#ComponentScan("Service")})
public class Config {
#Value("${spring.datasource.driverClassName}")
private String DB_DRIVER;
#Value("${db.password}")
private String DB_PASSWORD;
#Value("${db.url}")
private String DB_URL;
#Value("${db.username}")
private String DB_USERNAME;
#Value("${hibernate.dialect}")
private String HIBERNATE_DIALECT;
#Value("${hibernate.show_sql}")
private String HIBERNATE_SHOW_SQL;
#Value("${hibernate.hbm2ddl.auto}")
private String HIBERNATE_HBM2DDL_AUTO;
#Value("${entitymanager.packagesToScan}")
private String ENTITYMANAGER_PACKAGES_TO_SCAN;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DB_DRIVER);
dataSource.setUrl(DB_URL);
dataSource.setUsername(DB_USERNAME);
dataSource.setPassword(DB_PASSWORD);
return dataSource;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver resolver= new InternalResourceViewResolver();
resolver.setPrefix("/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
And my apliccation.properties with this code (it is for SQL Server):
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.url=jdbc:sqlserver://localhost;databaseName=Prueba
spring.datasource.username=UserLogin
spring.datasource.password=Miguel123
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql = true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
I am trying to connect to SQL Server using a web service with Angular.
I'm trying to configure Spring Boot to use 2 datasources using JNDI:
application.properties:
spring.production.datasource.jndi-name=java:/global/production_gateway
spring.production.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.production.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.production.datasource.jpa.show-sql = true
spring.production.datasource.jpa.hibernate.ddl-auto = update
spring.warehouse.datasource.jndi-name=java:/global/production_warehouse
spring.warehouse.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.warehouse.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
spring.warehouse.datasource.jpa.show-sql = true
spring.warehouse.datasource.jpa.hibernate.ddl-auto = update
Primary datasource:
#Configuration
#EnableJpaRepositories(
basePackages = "org.datalis.plugin.production.entity",
entityManagerFactoryRef = "productionEntityManager",
transactionManagerRef = "productionTransactionManager"
)
#EnableTransactionManagement
public class ContextProductionDatasource {
#Primary
#Bean(name = "productionDataSourceProperties")
#ConfigurationProperties(prefix="spring.production.datasource")
public JndiPropertyHolder productionDataSourceProperties() {
return new JndiPropertyHolder();
}
#Primary
#Bean(name = "productionDataSource")
#ConfigurationProperties(prefix="spring.production.datasource")
public DataSource productionDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
DataSource dataSource = dataSourceLookup.getDataSource(productionDataSourceProperties().getJndiName());
return dataSource;
}
#Primary
#Bean(name = "productionEntityManager")
public EntityManager productionEntityManager(EntityManagerFactory emf) {
return emf.createEntityManager();
}
#Primary
#PersistenceContext(unitName = "production")
#Bean(name = "productionLocalEntityManager")
public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(productionDataSource()).persistenceUnit("production").packages("org.datalis.plugin.production.entity").build();
}
#Primary
#Bean(name = "productionTransactionManager")
public PlatformTransactionManager productionTransactionManager(final EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
#Primary
#Bean(name = "productionExceptionTranslation")
public PersistenceExceptionTranslationPostProcessor productionExceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
private static class JndiPropertyHolder {
private String jndiName;
public String getJndiName() {
return jndiName;
}
public void setJndiName(String jndiName) {
this.jndiName = jndiName;
}
}
}
I try to use the entity manager this way:
#Service
#Transactional(value = "productionEntityManager")
public class ..... {
#PersistenceContext(unitName = "production")
private EntityManager entityManager;
}
But I get an error during deployment:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
Do you know where my configuration is wrong?
You seem to be missing a bean for EntityManagerFactory. You're requesting it here:
public EntityManager productionEntityManager(EntityManagerFactory emf) {
Try adding
#Primary
#Bean(name = "productionEntityManagerFactory")
public EntityManagerFactory productionEntityManagerFactory() {
return Persistence.createEntityManagerFactory("production");
}
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" });
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
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;
}
}