1

I am having an issue with inserts not working. Reads (Selects) work okay. However, an insert is not being executed at end of my @Transactional method. Even though I do see the Transaction commit/close being called on the Entity Manager. I have tried different configurations and I still cannot get records (inserts) to work at the end of a transaction. And I don't see any errors being generated. I enabled the hibernate.transaction DEBUG and I don't see any hibernate transaction messages.

I am running Spring boot (.1.5.3) as a WAR executable with Tomcat. I am using persistence.xml (which is required by hibernate5-ddl-maven-plugin< to generate the SQL DDL during the build) on Spring Boot.

While debugging, I saw the JpaTransactionManager creating new transaction (Creating new transaction with name... Opened new EntityManager ,,,Exposing JPA transaction as JDBC transaction), joining other @Transactional methods (Found thread-bound EntityManager... Participating in existing transaction) and committing TX (Initiating transaction commit... Committing JPA transaction on EntityManager), and closing the JPA EM (Closing JPA EntityManager). This all happens according to the @Transactional specs. However, the record is not inserted into to the database. And I don't see any hibernate transaction messages.

Below is some of my configuration.

persistence.xml:

<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">

<!--
This file is needed to generate the DDL.
-->

<persistence-unit
    name="EzListaPersistence"
    transaction-type="RESOURCE_LOCAL">

    <description>
        The set of entity types that can be managed by a
        given entity manager is defined by a persistence unit. A
        persistence unit defines the set of all classes that are
        related or grouped by the application, and which must be
        collocated in their mapping to a single data store.
    </description>

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <!--
      List of fully qualified Entity Classes
    -->

    <class>com.ezlista.domain.account.Account</class>
    ...... NOT DISPLAYED ....
    <class>com.ezlista.domain.useraccount.Notification</class>

    <properties>
        <!--  Hibernate Connection Settings -->
        <property
            name="hibernate.connection.provider_class"
            value="org.hibernate.hikaricp.internal.HikariCPConnectionProvider" />
        <property
            name="hibernate.hikari.dataSourceClassName"
            value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
        <property
            name="hibernate.hikari.dataSource.url"
            value="jdbc:mysql://localhost:3306/EZLISTA?verifyServerCertificate=false&amp;useSSL=false" />
        <property
            name="hibernate.hikari.dataSource.user"
            value="rubens" />
        <property
            name="hibernate.hikari.dataSource.password"
            value="***MASKED***" />
        <property
            name="hibernate.hikari.dataSource.cachePrepStmts"
            value="true" />
        <property
            name="hibernate.hikari.dataSource.prepStmtCacheSize"
            value="250" />
        <property
            name="hibernate.hikari.dataSource.prepStmtCacheSqlLimit"
            value="2048" />
        <property
            name="hibernate.hikari.minimumIdle"
            value="5" />
        <property
            name="hibernate.hikari.maximumPoolSize"
            value="10" />
        <property
            name="hibernate.hikari.idleTimeout"
            value="30000" />


        <!--  SQL Settings -->
        <property name="hibernate.dialect"
                  value="org.hibernate.dialect.MySQL5InnoDBDialect" />
        <property name="hibernate.show_sql"
                  value="false" />
        <property name="hibernate.format_sql"
                  value="true" />
        <property name="hibernate.use_sql_comments"
                  value="false" />
        <property name="hibernate.ddl-auto"
                  value="none" />

        <!--  Hibernate Cache Settings -->
        <property name="hibernate.javax.cache.provider"
                  value="org.ehcache.jsr107.EhcacheCachingProvider" />
        <property name="hibernate.cache.region.factory_class"
                  value="org.hibernate.cache.jcache.JCacheRegionFactory" />
        <property name="hibernate.cache.use_second_level_cache"
                  value="true" />
        <property name="hibernate.cache.use_query_cache"
                  value="false" />
        <property name="hibernate.cache.use_structured_entries"
                  value="true" />
        <property name="hibernate.cache.use_minimal_puts"
                  value="true" />
    </properties>

</persistence-unit>

Java Configuration:

@EntityScan("com.ezlista.domain")
@EnableTransactionManagement

/**
 * Spring Bootstrap Repository Configuration.
 *
 * @author Rubens Gomes
 */
@Configuration
public class RepositoryConfiguration
{
private final static Logger logger = LoggerFactory.getLogger(RepositoryConfiguration.class);
private final static String PERSISTENCE_UNIT = "EzListaPersistence";

@Inject
private Environment env;

public RepositoryConfiguration()
{
    super();
    logger.debug("Constructed");
}


// DataSource
@Bean(name = "dataSource")
public DataSource dataSource()
{
    logger.info("Registering HikariDataSource bean.");
    HikariDataSource ds = new HikariDataSource();

    ds.setDataSourceClassName(env.getRequiredProperty("hikari.dataSourceClassName"));
    ds.setMinimumIdle(env.getRequiredProperty("hikari.minimumIdle", Integer.class));
    ds.setMaximumPoolSize(env.getRequiredProperty("hikari.maximumPoolSize", Integer.class));
    ds.setIdleTimeout(env.getRequiredProperty("hikari.idleTimeout", Integer.class));
    ds.setPoolName(env.getRequiredProperty("hikari.poolName"));

    ds.addDataSourceProperty("user", env.getRequiredProperty("hikari.dataSource.user"));
    ds.addDataSourceProperty("password", env.getRequiredProperty("hikari.dataSource.password"));
    ds.addDataSourceProperty("databaseName", env.getRequiredProperty("hikari.dataSource.databaseName"));
    ds.addDataSourceProperty("serverName", env.getRequiredProperty("hikari.dataSource.serverName"));
    ds.addDataSourceProperty("cachePrepStmts", env.getRequiredProperty("hikari.dataSource.cachePrepStmts", Boolean.class));
    ds.addDataSourceProperty("prepStmtCacheSize", env.getRequiredProperty("hikari.dataSource.prepStmtCacheSize", Integer.class));
    ds.addDataSourceProperty("prepStmtCacheSqlLimit", env.getRequiredProperty("hikari.dataSource.prepStmtCacheSqlLimit", Integer.class));

    return ds;
}


// EntityManagerFactory
@Bean(name = "entityManagerFactory")
public EntityManagerFactory entityManagerFactory()
{
    logger.info("Registering EntityManagerFactory bean.");
    JpaVendorAdapter hibernateJpavendorAdapter = new HibernateJpaVendorAdapter();
    JpaDialect hibernateJpaDialect = new HibernateJpaDialect();

    LocalContainerEntityManagerFactoryBean emfBean =
            new LocalContainerEntityManagerFactoryBean();
    emfBean.setJpaVendorAdapter(hibernateJpavendorAdapter);
    emfBean.setJpaDialect(hibernateJpaDialect);
    emfBean.setPersistenceUnitName(PERSISTENCE_UNIT);
    emfBean.setDataSource(dataSource());
    emfBean.afterPropertiesSet();
    return emfBean.getObject();
}


// TransactionManager
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager()
{
  logger.info("Registering JpaTransactionManager bean.");

  JpaTransactionManager txManager = new JpaTransactionManager();
  EntityManagerFactory emf = entityManagerFactory();
  txManager.setEntityManagerFactory(emf);
  txManager.setDataSource(dataSource());
  return txManager;
}

}
Rubens Gomes
  • 482
  • 5
  • 10

1 Answers1

0

Bingo!!!! I annotated my EntityManager with @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME). After that it works.

Here is the code that fixed the above problem. Notice the @PersistenceContext annotation below (that's what fixed the issue). Before I had @Inject annotation on the em.

@PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
protected EntityManager em;
Rubens Gomes
  • 482
  • 5
  • 10
  • Hi @Rubens Gomes, can you have a look at my code to see what i'm doing wrong? https://stackoverflow.com/questions/47624373/how-to-implement-springs-transactional-annotation-using-hibernate-hikaricp-an/ – jNewbie Dec 04 '17 at 05:22