JPA Spring configuration

I have been working on a spring web application using spring Data JPA lately

I am having problems with persistanceConfiguration

@Configuration
@EnableTransactionManagement
@PropertySource({ "/resources/hibernate.properties" })
@EnableJpaRepositories(basePackages = "com.servmed.repositories")

public class PersistenceConfig {

    @Autowired
    private Environment env;


    Properties jpaProperties() {
        return new Properties() {
            {
                setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
                setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); //allows Hibernate to generate SQL optimized for a particular relational database.
                setProperty("hibernate.show_sql",env.getProperty("hibernate.show_sql"));
            }
        };
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
    {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        vendorAdapter.setShowSql(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource());
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setJpaProperties(jpaProperties());
        factory.setPackagesToScan("com.servmed.models");

        factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
        return factory;
    }

    @Bean
    public PlatformTransactionManager transactionManager()
    {
        EntityManagerFactory factory = entityManagerFactory().getObject();
        return new JpaTransactionManager(factory);
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator(){
        return new HibernateExceptionTranslator();
    }


    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.user"));
        dataSource.setPassword(env.getProperty("jdbc.pass"));

        return dataSource;
    }
}

      

And here is my pom.xml

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!--Spring dependencies-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-dao</artifactId>
            <version>2.0.8</version>
        </dependency>


        <!-- spring security-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

        <!-- Spring Data JPA dependencies -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.6.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>


        <!--com.mysema.querydsl dependencies-->
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-sql</artifactId>
            <version>${com.mysema.querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${com.mysema.querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-core</artifactId>
            <version>${com.mysema.querydsl.version}</version>
        </dependency>


        <!--Hibernate dependencies-->
         <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>${hibernate.version}</version>
        </dependency>

        <!--db-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.23</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <!--connection pool-->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>8.0.9</version>
        </dependency>


        <!--thymeleaf and servlet api-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>2.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
    </build>

      

It doesn't seem to work for me, I am getting this error:

Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required

      

any idea why?

EDIT

it doesn't seem that the entityManagerFactory method correctly creates the bean used in the transactionManager, I had the same problem with hibernate (sessionFactory bean is not created and cannot be used in the transactionManager method)

EDIT 2

I got rid of this problem (it was due to the wrong properties file), but now I have a different error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/servmed/configuration/PersistenceConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory

      

+1


source to share


2 answers


This is how I defined the transaction manager:

  @Bean
  public Object transactionManager() {
    return new org.springframework.orm.jpa.JpaTransactionManager();
  }

      

And instead of calling a method, entityFactory

you must inject it: this will avoid dependency injection errors in entityManagerFactory

.

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory factory)
{
    return new JpaTransactionManager(factory);
}

      

EDIT

Besides persistence.xml

, call afterPropertiesSet()

and setLoadTimeWeaver

, we have the same code.

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory()
{
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(true);
    vendorAdapter.setShowSql(true);

    Properties jpaProperties = new Properties();
    jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
    jpaProperties.put("hibernate.dialect"     , env.getProperty("hibernate.dialect"));
    jpaProperties.put("hibernate.show_sql"    , pgadenv.getProperty("hibernate.show_sql"));

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setDataSource(dataSource());
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setJpaProperties(jpaProperties);
    factory.setPackagesToScan("com.servmed.models");

    // factory.afterPropertiesSet(); <-- why ?
    // does it work without Weaving ?
    factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
    return factory;
}

      



EDIT (2)

I didn't have time to answer you, here's an example persistence.xml

:

<?xml version="1.0"  encoding="UTF-8"?>
<persistence version="2.1"
  xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
 http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <!-- transaction-type="JTA" -->
  <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <!-- Your probably won't need it. -->
    <!-- <class>com.servmed.models.YourClass</class> -->
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

    <properties>
      <property name="javax.persistence.schema-generation.database.action"       value="none" />
      <property name="javax.persistence.schema-generation.scripts.action"        value="none" />
      <!-- <property name="javax.persistence.schema-generation.scripts.create-target" value="" /> -->
      <!-- <property name="javax.persistence.schema-generation.scripts.drop-target"   value=""/> -->
    </properties>
  </persistence-unit>
</persistence>

      

You probably won't need to list your classes (for example in a comment), otherwise list them.

And in your Spring config add:

factory.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
factory.setPersistenceUnitName("persistenceUnit");

      

However, I am beginning to think that this might be a completely unrelated issue.

+2


source


@Aissasa. You can use a similar JPA config class and you also don't need to have an xm file.



        Code :::

                        import java.util.HashMap;
                        import java.util.Map;
                        import java.util.Properties;
                        import javax.persistence.EntityManagerFactory;
                        import javax.sql.DataSource;
                        import org.eclipse.persistence.config.BatchWriting;
                        import org.eclipse.persistence.config.PersistenceUnitProperties;
                        import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
                        import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
                        import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
                        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.LocalContainerEntityManagerFactoryBean;
                        import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
                        import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
                        import org.springframework.transaction.PlatformTransactionManager;
                        import org.springframework.transaction.annotation.EnableTransactionManagement;
                        import com.zaxxer.hikari.HikariConfig;
                        import com.zaxxer.hikari.HikariDataSource;

                        @Configuration
                        @EnableTransactionManagement
                        @EnableAutoConfiguration
                        @EnableJpaRepositories(basePackages = "com.subu")
                        public class JpaConfiguration extends JpaBaseConfiguration {

                            @Bean
                            public LocalContainerEntityManagerFactoryBean entityManagerFactory(final EntityManagerFactoryBuilder builder) {
                                final LocalContainerEntityManagerFactoryBean ret = 
                                        builder.dataSource(dataSource())
                                               .packages("com.subu")
                                               .properties(jpaProperties())
                                               .persistenceUnit("com.subu")
                                               .build();
                                return ret;
                            }

                            @Bean
                            public DataSource dataSource() {
                                // In classpath from spring-boot-starter-web
                                final Properties props = new Properties();
                                props.put("driverClassName", "com.mysql.jdbc.Driver");
                                props.put("jdbcUrl", "jdbc:mysql://localhost:3306/master?createDatabaseIfNotExist=false");
                                props.put("username", "root");
                                props.put("password", "mysql");
                                HikariConfig hc = new HikariConfig(props);
                                HikariDataSource ds = new HikariDataSource(hc);
                                return ds;
                            }

                            @Bean
                            public Map<String, String> jpaProperties() {
                                Map<String, String> props = new HashMap<>();
                                props.put("eclipselink.weaving", "false");
                                props.put("eclipselink.logging.level.sql", "FINE");
                                props.put("eclipselink.logging.parameters", "true");
                                props.put("javax.persistence.schema-generation.database.action", "create");
                                //props.put("javax.persistence.sql-load-script-source", "sql/import.sql");
                                return props;
                            }
                            @Bean
                            public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
                                final MultiTenantJpaTransactionManager transactionManager = new MultiTenantJpaTransactionManager();
                                transactionManager.setEntityManagerFactory(emf);
                                return transactionManager;
                            }

                            @Override
                            protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
                                return new EclipseLinkJpaVendorAdapter();
                            }



                            @Override
                            protected Map<String, Object> getVendorProperties() {
                                final Map<String, Object> ret = new HashMap<>();
                                ret.put(PersistenceUnitProperties.BATCH_WRITING, BatchWriting.JDBC);
                                return ret;
                            }


                        }





                        ===================================================================================================================================





                        import java.io.Serializable;
                        import javax.persistence.EntityManager;
                        import org.springframework.orm.jpa.EntityManagerHolder;
                        import org.springframework.orm.jpa.JpaTransactionManager;
                        import org.springframework.transaction.TransactionDefinition;
                        import org.springframework.transaction.support.TransactionSynchronizationManager;

                        public class MultiTenantJpaTransactionManager extends JpaTransactionManager {

                            @Override
                            protected void doBegin(final Object transaction, final TransactionDefinition definition) {
                                super.doBegin(transaction, definition);
                                final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
                                        .getResource(getEntityManagerFactory());
                                final EntityManager em = emHolder.getEntityManager();

                            }
                        }

      

0


source







All Articles