I have this config bean:
@EnableTransactionManagement
@EnableJpaRepositories({ "com.soib.repositories",
"com.notification.repositories"})
@Slf4j
@Configuration
public class EclipseLinkJpaConfiguration extends JpaBaseConfiguration {
protected EclipseLinkJpaConfiguration(
DataSource dataSource,
JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
super(dataSource, properties, jtaTransactionManager);
}
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new EclipseLinkJpaVendorAdapter();
}
@Bean
@Primary
public static JpaProperties properties() {
final JpaProperties jpaProperties = new JpaProperties();
jpaProperties.setShowSql(false);
jpaProperties.setDatabasePlatform("org.eclipse.persistence.platform.database.OraclePlatform");
return jpaProperties;
}
@Override
protected Map<String, Object> getVendorProperties() {
HashMap<String, Object> map = new HashMap<>();
map.put(PersistenceUnitProperties.WEAVING, detectWeavingMode());
return map;
}
private String detectWeavingMode() {
return InstrumentationLoadTimeWeaver.isInstrumentationAvailable() ? "true" : "static";
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("soib-backoffice-entities");
factoryBean.setPackagesToScan("eu.europa.ec.oib.kwbo.model");
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
Properties jpaProperties = new Properties();
jpaProperties.setProperty("eclipselink.target-database", "org.eclipse.persistence.platform.database.OraclePlatform");
jpaProperties.setProperty("eclipselink.target-server", "WebLogic");
jpaProperties.setProperty("eclipselink.logging.level", "WARNING");
jpaProperties.setProperty("eclipselink.logging.level.sql", "WARNING");
jpaProperties.setProperty("eclipselink.logging.logger", "DefaultLogger");
jpaProperties.setProperty("eclipselink.cache.shared.default", "false");
jpaProperties.setProperty("eclipselink.weaving", "false");
jpaProperties.setProperty("eclipselink.jdbc.fetch-size", "200");
factoryBean.setJpaProperties(jpaProperties);
return factoryBean;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.OraclePlatform");
return vendorAdapter;
}
}
but when I start the app, I have this error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#a30810': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:688)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:374)
... 58 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:874)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1358)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:309)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
in my application.properties:
# JPA general settings
spring.jpa.show-sql=false
spring.jpa.generate-ddl=false
spring.jpa.database-platform=org.eclipse.persistence.platform.database.OraclePlatform
# EclipseLink-specific properties
spring.jpa.properties.eclipselink.target-database=org.eclipse.persistence.platform.database.OraclePlatform
spring.jpa.properties.eclipselink.target-server=WebLogic
spring.jpa.properties.eclipselink.logging.level=WARNING
spring.jpa.properties.eclipselink.logging.level.sql=WARNING
spring.jpa.properties.eclipselink.logging.logger=DefaultLogger
spring.jpa.properties.eclipselink.cache.shared.default=false
spring.jpa.properties.eclipselink.weaving=false
spring.jpa.properties.eclipselink.jdbc.fetch-size=200
I agree with M. Deinum. The spring.jpa
properties is useless if you are providing your custom JPA configuration.
You have to create and provide your custom PlatformTransactionManager
and LocalContainerEntityManagerFactoryBean
for custom JPA configuration.
Modify to this:
import jakarta.persistence.EntityManagerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.soib.repositories", "com.notification.repositories"}, transactionManagerRef = "customTransactionManager")
@Slf4j
public class EclipseLinkJPAConfiguration {
@Autowired
private DataSource dataSource;
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter();
vendorAdapter.setShowSql(false);
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.OraclePlatform");
return vendorAdapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("soib-backoffice-entities");
factoryBean.setPackagesToScan("eu.europa.ec.oib.kwbo.model");
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setJpaProperties(jpaProperties());
return factoryBean;
}
private Properties jpaProperties() {
Properties jpaProperties = new Properties();
jpaProperties.setProperty("eclipselink.target-database", "org.eclipse.persistence.platform.database.OraclePlatform");
jpaProperties.setProperty("eclipselink.target-server", "WebLogic");
jpaProperties.setProperty("eclipselink.logging.level", "WARNING");
jpaProperties.setProperty("eclipselink.logging.level.sql", "WARNING");
jpaProperties.setProperty("eclipselink.logging.logger", "DefaultLogger");
jpaProperties.setProperty("eclipselink.cache.shared.default", "false");
jpaProperties.setProperty("eclipselink.weaving", "false");
jpaProperties.setProperty("eclipselink.jdbc.fetch-size", "200");
return jpaProperties;
}
@Bean
public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return entityManagerFactory.getObject();
}
@Bean
public PlatformTransactionManager customTransactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
See if this helps.
Note: When you are doing DAO operations and you want to use your custom transaction manager, then you have to do this: @Transactional(transactionManager = "customTransactionManager")
See if this helps.